Python bytecode utilities
Pycnite is a collection of utilities for working with compiled Python bytecode. This library provides pure Python, versioned parsers for the .pyc format, enabling tools that work with bytecode to support different host and target Python versions. It currently supports target Python versions 3.8 through 3.12.
Warnings
- gotcha Pycnite is currently in 'Development Status :: 3 - Alpha'. This means the API might not be stable, and breaking changes could occur in future versions without extensive prior notice.
- gotcha The `.pyc` file format is an implementation detail of CPython and can change between Python versions, even minor ones. While pycnite aims to support multiple versions, unexpected behavior may occur with new or unsupported Python versions.
Install
-
pip install pycnite
Imports
- pyc
from pycnite import pyc
- bytecode
from pycnite import bytecode
Quickstart
import os
import py_compile
import tempfile
# Create a dummy Python file
dummy_py_content = '''
def greet(name):
message = f"Hello, {name}!"
return message
result = greet("World")
'''
# Use tempfile to create and manage temporary files
with tempfile.TemporaryDirectory() as tmpdir:
dummy_py_path = os.path.join(tmpdir, 'dummy_module.py')
dummy_pyc_path = os.path.join(tmpdir, '__pycache__', 'dummy_module.cpython-310.pyc') # Adjust for your Python version
with open(dummy_py_path, 'w') as f:
f.write(dummy_py_content)
# Compile the .py file to .pyc
# py_compile automatically creates __pycache__ and the .pyc file
py_compile.compile(dummy_py_path, cfile=dummy_pyc_path, doraise=True)
print(f"Generated .pyc file at: {dummy_pyc_path}")
try:
from pycnite import pyc
# Load the .pyc file using pycnite
# You may need to specify the Python version if pycnite can't infer it
# For example, pyc.load_pyc(dummy_pyc_path, python_version=(3, 10))
pyc_file = pyc.load_pyc(dummy_pyc_path)
print(f"\nLoaded .pyc file successfully. Python version: {pyc_file.version}")
print(f"Magic number: {hex(pyc_file.magic)}")
# Accessing the code object (example for the module's code object)
code_obj = pyc_file.code
print(f"\nCode object name: {code_obj.co_name}")
print(f"Number of arguments: {code_obj.co_argcount}")
print(f"Constants: {code_obj.co_consts}")
print(f"Names used: {code_obj.co_names}")
# print(f"Disassembled bytecode:\n{code_obj.dis()}") # Requires 'dis' module and pycnite's dis method
except ImportError:
print("\nPycnite not installed. Skipping pycnite specific checks.")
except Exception as e:
print(f"\nError loading .pyc with pycnite: {e}")