{"id":8787,"library":"xdis","title":"xdis: Python Cross-Version Byte-Code Disassembler","description":"xdis is a Python library that provides a cross-version byte-code disassembler and marshal routines. It enables the inspection and manipulation of Python bytecode across a wide range of Python versions, from 1.0 up to 3.15+. The current version is 6.3.0, and it maintains an active release cadence, frequently updating with support for new Python versions and their respective bytecode changes.","status":"active","version":"6.3.0","language":"en","source_language":"en","source_url":"https://github.com/rocky/python-xdis/","tags":["bytecode","disassembler","cross-version","reverse-engineering","debug","marshalling","analysis"],"install":[{"cmd":"pip install xdis","lang":"bash","label":"Install latest version (Python 3.11+)"},{"cmd":"For Python versions before 3.11, consult the GitHub Releases page for specific tarballs or wheels matching your Python version (e.g., xdis_36-x.y.z.tar.gz for Python 3.6-3.11, or older eggs/tarballs for Python 2.x/3.x up to 3.5).","lang":"text","label":"Install for older Python versions"}],"dependencies":[{"reason":"Python 2/3 compatibility layer, used internally by xdis.","package":"six","optional":false},{"reason":"Command-line interface toolkit, used for the pydisasm utility.","package":"click","optional":false}],"imports":[{"note":"For a drop-in replacement of Python's built-in `dis.Bytecode` for cross-version analysis.","symbol":"Bytecode","correct":"from xdis.std import Bytecode"},{"note":"To load bytecode from a .pyc file for a specific Python version.","symbol":"load_bytecode","correct":"from xdis import load"},{"note":"To directly disassemble bytecode objects.","symbol":"disassemble","correct":"from xdis.bytecode import disassemble"}],"quickstart":{"code":"import marshal\nimport types\nfrom xdis.std import Bytecode\n\ndef example_function():\n    a = 10\n    b = 'hello'\n    if a > 5:\n        print(b)\n    return a\n\n# Get the code object of the function\ncode_obj = example_function.__code__\n\n# Disassemble using xdis.std.Bytecode (similar to stdlib dis)\nprint(f\"\\nDisassembly for Python {code_obj.co_firstlineno} via xdis.std:\")\nfor instr in Bytecode(code_obj):\n    print(instr)\n\n# Example of loading bytecode from a marshal.dumps() output (simulated .pyc content)\n# For true cross-version loading, you'd use xdis.load.load_bytecode_from_file\n# or xdis.load.load_bytecode_from_cstring to specify the Python magic number.\n\ndef mock_marshal_loader(code_obj, python_version):\n    # This is a simplified example; xdis.load handles actual magic numbers/versions\n    # The real power is in loading *other* Python versions' bytecode.\n    # For simplicity here, we'll just demonstrate disassembling a marshalled object.\n    marshalled_code = marshal.dumps(code_obj)\n    return marshalled_code\n\nmarshalled_bytes = mock_marshal_loader(code_obj, (3, 9)) # Simulate Python 3.9 bytecode\n\ntry:\n    # To truly demonstrate xdis's cross-version capability, you'd load a .pyc file\n    # generated by a *different* Python version than the one running this code.\n    # For this example, we'll just show disassembling an arbitrary code object.\n    # For actual cross-version loading, investigate xdis.load functions.\n    print(f\"\\nDisassembly of a marshalled code object (Python {code_obj.co_firstlineno}):\")\n    # Note: For actual different Python versions, you'd need the specific magic number\n    # and potentially xdis.load.load_bytecode_from_cstring or file-based loaders.\n    # We'll re-disassemble the current code_obj for a runnable example.\n    from xdis.bytecode import disassemble\n    disassemble(code_obj)\nexcept Exception as e:\n    print(f\"Could not fully demonstrate cross-version load in quickstart due to complexity: {e}\")","lang":"python","description":"This quickstart demonstrates how to use `xdis.std.Bytecode` as a drop-in replacement for the standard library's `dis.Bytecode` to inspect a Python function's bytecode. While `xdis` excels at disassembling bytecode from *different* Python versions, this example focuses on its core disassembler functionality. For advanced cross-version loading from `.pyc` files, users should refer to `xdis.load` functions."},"warnings":[{"fix":"Review the `pydisasm -h` output and `xdis` documentation for updated API calls and format options. Adjust programmatic calls to `xdis` functions to match the new API.","message":"Version 6.1.0 introduced major API changes, particularly affecting how disassembly options are specified (e.g., via `--format` on the `pydisasm` command-line utility) and new output formats like 'extended' or 'bytes'. Code written for previous versions may need updates.","severity":"breaking","affected_versions":">=6.1.0"},{"fix":"For Python < 3.11, navigate to the `xdis` GitHub releases page and download the appropriate `xdis_X-x.y.z.tar.gz` or `.whl` file corresponding to your exact Python interpreter version. Install it manually using `pip install <downloaded_file>`. Ensure the Python environment you are installing into matches the target version of the `xdis` distribution.","message":"Installing `xdis` via `pip install xdis` is primarily for Python 3.11 and newer. For older Python versions (e.g., 2.x, 3.0-3.10), you must manually download specific tarballs or wheels from the GitHub Releases page that are pre-compiled for those Python versions. Installing the generic package on older Python versions may lead to unexpected behavior or `ModuleNotFoundError` if dependencies are not correctly resolved or specific bytecode definitions are missing.","severity":"gotcha","affected_versions":"<6.3.0 (for pip install behavior), <3.11 Python interpreter"},{"fix":"Upgrade to `xdis` version 6.1.7 or newer to ensure correct `MAKE_FUNCTION` formatting and improved marshalling routines for Python 3.11+ bytecode.","message":"The `MAKE_FUNCTION` opcode's formatting and behavior changed significantly in Python 3.11 compared to Python 3.6. `xdis` versions 6.1.7 and later include adjustments to handle these differences, but older `xdis` versions might produce incorrect or confusing disassembly output for Python 3.11 bytecode, especially around function creation.","severity":"gotcha","affected_versions":"<6.1.7 (when disassembling Python 3.6 or 3.11+ bytecode)"},{"fix":"Upgrade to `xdis` version 6.1.7 or newer to benefit from the performance fix for Python 3.11+ exception handling.","message":"An O(n^2) performance issue was identified and fixed in `xdis` version 6.1.7, specifically affecting the handling of exceptions in Python 3.11+. Users disassembling large codebases or complex exception structures with `xdis` versions prior to 6.1.7 on a Python 3.11+ interpreter may experience significant slowdowns.","severity":"gotcha","affected_versions":"<6.1.7 (when analyzing Python 3.11+ bytecode)"},{"fix":"If bytecode manipulation for execution is required, proceed with caution and thorough testing. Recognize that `xdis` is primarily an analysis tool. Direct re-execution of `xasm`-generated bytecode might require deeper understanding of Python's internal code object structure beyond what basic disassembly/assembly provides. Consider `uncompyle6` for dekompilation to source if re-execution is the goal.","message":"Attempting to disassemble bytecode and then reassemble it using `xasm` (a related project) and execute the result can lead to `TypeError` or other runtime issues, particularly with functions that have the same name or complex closures. `xdis` focuses on disassembly and analysis, and perfect round-tripping for execution via reassembly is not guaranteed or fully supported across all cases.","severity":"gotcha","affected_versions":"All versions (when attempting `disasm` -> `xasm` -> execute)"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Ensure `xdis` is up-to-date (current version is 6.3.0). If you are processing bytecode from an older or very new Python version, verify that your installed `xdis` version explicitly supports that target Python version. For installations on Python < 3.11, ensure you followed the specific installation instructions for pre-built wheels/tarballs. If using `uncompyle6`, ensure both `uncompyle6` and `xdis` are the latest compatible versions.","cause":"This error often indicates that `xdis` is trying to process bytecode from a Python version for which it doesn't have the necessary opcode or magic number definitions, or there's a mismatch between the bytecode version and the `xdis` version's capabilities. This can be exacerbated by incorrect installation for older Python versions.","error":"KeyError: 'X.Y.Z' (e.g., 'KeyError: '3.7.5'') when importing xdis or a library using it (like uncompyle6)."},{"fix":"The primary purpose of `xdis` is analysis, not necessarily perfect round-trip bytecode editing and re-execution. If you encounter this, understand that direct bytecode manipulation for execution can be very fragile. Verify the `xasm` project's documentation and current status for any known limitations or specific usage patterns to ensure executable output. Consider higher-level tools like `uncompyle6` for dekompilation if source code re-generation is the goal for execution.","cause":"This error typically occurs when bytecode is reassembled (e.g., using `xasm`) and then executed. The reassembly process, particularly when dealing with complex code objects, multiple functions, or specific optimizations, may not perfectly replicate the original bytecode structure required for Python's interpreter, leading to runtime type mismatches or incorrect references.","error":"TypeError: unsupported operand type(s) for +: 'function' and 'function' (or similar runtime errors) after disassembling bytecode with `pydisasm --asm` and reassembling with `pyc-xasm`."},{"fix":"Upgrade `xdis` to version 6.1.7 or newer to get the latest fixes and improvements for Python 3.11+ bytecode analysis. This ensures that the disassembly accurately reflects the behavior of newer Python interpreters.","cause":"Older versions of `xdis` (pre-6.1.7) had less robust handling for changes in Python 3.11's bytecode, specifically regarding `MAKE_FUNCTION` formatting and an O(n^2) performance issue in exception handling. This could lead to misinterpretation or incomplete display of the bytecode structure.","error":"Incorrect or unexpected disassembly output, especially for `MAKE_FUNCTION` or exception handling blocks when analyzing Python 3.11+ bytecode."}]}