{"id":4407,"library":"zipfile36","title":"Python 3.6 Zipfile Backport","description":"zipfile36 is a backport of the `zipfile` module from Python 3.6, offering enhancements and API changes introduced in that version to older Python environments. Its latest version is 0.1.3, released in October 2016. As a backport for an End-of-Life Python version (3.6), the library is considered to be in maintenance status with no active development.","status":"maintenance","version":"0.1.3","language":"en","source_language":"en","source_url":"https://gitlab.com/takluyver/zipfile36","tags":["zip","archive","compression","backport","python3.6","file-handling"],"install":[{"cmd":"pip install zipfile36","lang":"bash","label":"Install `zipfile36`"}],"dependencies":[{"reason":"Required for DEFLATE compression. Typically built-in with Python, but might be missing in some custom installations.","package":"zlib","optional":true},{"reason":"Required for BZIP2 compression, if used.","package":"bz2","optional":true},{"reason":"Required for LZMA compression, if used.","package":"lzma","optional":true},{"reason":"Required for ZSTD compression, if used (available in newer Python versions).","package":"compression.zstd","optional":true}],"imports":[{"note":"The backport is designed to be aliased as `zipfile` for compatibility with existing code written for the standard library's `zipfile` module. Direct import as `zipfile36` works but deviates from the intended usage pattern.","wrong":"import zipfile36","symbol":"zipfile","correct":"import sys\nif sys.version_info >= (3, 6):\n    import zipfile\nelse:\n    import zipfile36 as zipfile"}],"quickstart":{"code":"import sys\nimport os\nimport io\n\n# Suggested usage for zipfile36 backport\nif sys.version_info >= (3, 6):\n    import zipfile\nelse:\n    try:\n        import zipfile36 as zipfile\n    except ImportError:\n        print(\"zipfile36 not installed. Please install with 'pip install zipfile36' for Python versions < 3.6.\")\n        sys.exit(1)\n\n# Create a dummy file\nfile_content = \"Hello, zipfile36! This is a test file.\"\nfile_name = \"test_file.txt\"\nwith open(file_name, \"w\") as f:\n    f.write(file_content)\n\nzip_file_name = \"my_archive.zip\"\n\n# 1. Create a zip archive and add a file\nprint(f\"Creating '{zip_file_name}' and adding '{file_name}'...\")\nwith zipfile.ZipFile(zip_file_name, 'w', zipfile.ZIP_DEFLATED) as zf:\n    zf.write(file_name, arcname=\"docs/zipped_test_file.txt\")\nprint(f\"'{file_name}' added to '{zip_file_name}' as 'docs/zipped_test_file.txt'.\")\n\n# 2. Read from the zip archive\nprint(f\"\\nReading contents from '{zip_file_name}'...\")\nwith zipfile.ZipFile(zip_file_name, 'r') as zf:\n    print(f\"Files in '{zip_file_name}': {zf.namelist()}\")\n    with zf.open(\"docs/zipped_test_file.txt\") as member_file:\n        read_content = member_file.read().decode('utf-8')\n        print(f\"Content of 'docs/zipped_test_file.txt': {read_content}\")\n\n# Clean up\nos.remove(file_name)\nos.remove(zip_file_name)\nprint(\"\\nCleaned up dummy files.\")","lang":"python","description":"This quickstart demonstrates how to use `zipfile36` (aliased as `zipfile`) to create a ZIP archive, add a file to it, and then read the file's contents from the archive. It includes the recommended conditional import statement."},"warnings":[{"fix":"Avoid pickling `zipfile.ZipFile` instances directly. Instead, serialize the necessary file paths or contents and recreate `ZipFile` objects as needed.","message":"Pickling `zipfile.ZipFile` instances will raise a `TypeError` in Python 3.6+ (and by extension, when using `zipfile36`). This behavior change fixed a prior bug in Python < 3.6 where `ZipFile` objects containing unpicklable `_thread.RLock` objects were incorrectly picklable. Code relying on pickling `ZipFile` objects for serialization will break.","severity":"breaking","affected_versions":"0.1.x on Python >= 3.6 (native `zipfile`), or older Python versions using `zipfile36`."},{"fix":"For reliable file type detection, use dedicated file-sniffing libraries (e.g., `python-magic`, `filetype`) or validate the content more thoroughly after initial checks, especially when dealing with untrusted sources.","message":"The `zipfile.is_zipfile()` function is not a robust file type identifier and can produce false positives. It primarily checks for the presence of a ZIP central directory signature at the end of a file, which can coincidentally appear in other file types (e.g., gzipped files, executables with appended data).","severity":"gotcha","affected_versions":"All versions of `zipfile36` (and the native `zipfile` module in CPython)."},{"fix":"Update exception handling blocks to catch `ValueError` instead of `RuntimeError` for operations that misuse `ZipFile` objects (e.g., operating on a closed archive).","message":"Error types for certain operations changed in Python 3.6. Specifically, operations on a closed `ZipFile` (e.g., `open()`, `write()`, `extract()`, `extractall()`, `writestr()`) or with an invalid mode will now raise `ValueError` instead of `RuntimeError`.","severity":"breaking","affected_versions":"0.1.x, impacts users migrating from Python < 3.6 or expecting `RuntimeError`."},{"fix":"Instead of `mode='U'`, use `io.TextIOWrapper` to read compressed text files with explicit encoding and newline handling. For example: `io.TextIOWrapper(zip_file.open('member.txt'), encoding='utf-8', newline='')`.","message":"The `mode='U'` option for `ZipFile.open()` (for universal newlines mode) was removed in Python 3.6.","severity":"deprecated","affected_versions":"0.1.x, specifically affects usage of `mode='U'`."}],"env_vars":null,"last_verified":"2026-04-12T00:00:00.000Z","next_check":"2026-07-11T00:00:00.000Z"}