Metadata-Version: 2.4
Name: pycrefine
Version: 1.1.1
Summary: A Python .pyc decompiler for educational purposes
Author: Saheb
License-Expression: MIT
Project-URL: Homepage, https://github.com/sahebbiswas/pycrefine
Project-URL: Issues, https://github.com/sahebbiswas/pycrefine/issues
Keywords: decompiler,bytecode,pyc,cpython,reverse-engineering
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Disassemblers
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: pylint==4.1.3; extra == "dev"
Requires-Dist: mypy==2.4.0; extra == "dev"
Dynamic: license-file

# pycrefine

[![Python 3.9](https://github.com/sahebbiswas/pycrefine/actions/workflows/ci-py39.yml/badge.svg?branch=main&event=push)](https://github.com/sahebbiswas/pycrefine/actions/workflows/ci-py39.yml)
[![Python 3.12](https://github.com/sahebbiswas/pycrefine/actions/workflows/ci-py312.yml/badge.svg?branch=main&event=push)](https://github.com/sahebbiswas/pycrefine/actions/workflows/ci-py312.yml)
[![Python 3.14](https://github.com/sahebbiswas/pycrefine/actions/workflows/ci-py314.yml/badge.svg?branch=main&event=push)](https://github.com/sahebbiswas/pycrefine/actions/workflows/ci-py314.yml)
[![Lint](https://github.com/sahebbiswas/pycrefine/actions/workflows/lint.yml/badge.svg?branch=main&event=push)](https://github.com/sahebbiswas/pycrefine/actions/workflows/lint.yml)

pycrefine turns compiled Python bytecode (`.pyc` files) back into readable Python source.
It reads `.pyc` files written by CPython 3.9 and later, has no third-party dependencies,
and works both as a command and as a library.

```console
$ pycrefine __pycache__/report.cpython-312.pyc
def summarize(rows, limit=10):
    totals = {}
    for name, amount in rows:
        totals[name] = (totals.get(name, 0) + amount)
    return sorted(totals.items(), key=(lambda kv: -kv[1]))[:limit]
```

## Supported Python versions

| Bytecode written by | Status | Run pycrefine under |
|---|---|---|
| Python 3.9 | supported, tested in CI | any Python 3.9 or later |
| Python 3.12, 3.14 | supported, tested in CI | the same minor version (3.12 for 3.12 bytecode) |
| Python 3.13 | works, not in CI | Python 3.13 |
| Python 3.10, 3.11 | partial: loops and exception handling often come out wrong | the same minor version |
| Python 3.8 and older | not supported | |

Bytecode from 3.10 onwards can only be decompiled by the Python version that wrote it
([#94](https://github.com/sahebbiswas/pycrefine/issues/94)). pycrefine tells you which
version to use, and [Getting started](https://github.com/sahebbiswas/pycrefine/blob/main/docs/getting-started.md#run-under-the-python-that-wrote-the-file)
shows how to run it under another Python in one command. Some constructs (`match`,
`async`/`await`, `yield from`) are not reconstructed yet; see
[Limitations](https://github.com/sahebbiswas/pycrefine/blob/main/docs/limitations.md).

## Install

```bash
python -m pip install pycrefine
```

Until the first release reaches PyPI, install from GitHub instead:

```bash
python -m pip install "git+https://github.com/sahebbiswas/pycrefine"
```

Or run it from a checkout without installing: `python pycrefine.py file.pyc`. Install
problems (`command not found`, `externally-managed-environment`, …) are covered in
[Troubleshooting](https://github.com/sahebbiswas/pycrefine/blob/main/docs/troubleshooting.md#installation-and-setup).

## Quick start

```bash
pycrefine module.cpython-312.pyc                 # print the source
pycrefine module.cpython-312.pyc -o module.py    # save it to a file
python -m pycrefine module.cpython-312.pyc       # same, if the command is not on PATH
```

From Python:

```python
import pycrefine

source = pycrefine.get_decompiler("module.cpython-312.pyc").decompile()
print(source)
```

## Documentation

| Guide | Read it to |
|---|---|
| [Getting started](https://github.com/sahebbiswas/pycrefine/blob/main/docs/getting-started.md) | install, decompile a first file, and run under the right Python version |
| [Use cases](https://github.com/sahebbiswas/pycrefine/blob/main/docs/use-cases.md) | recover a project from `__pycache__`, batch-decompile a tree, decompile PyInstaller or in-memory code, check the output |
| [Command line and Python API](https://github.com/sahebbiswas/pycrefine/blob/main/docs/usage.md) | look up every option, exit status and API call |
| [Troubleshooting](https://github.com/sahebbiswas/pycrefine/blob/main/docs/troubleshooting.md) | fix setup problems and understand each error message |
| [Limitations](https://github.com/sahebbiswas/pycrefine/blob/main/docs/limitations.md) | see what is not reconstructed yet, and how to tell |
| [Architecture](https://github.com/sahebbiswas/pycrefine/blob/main/docs/architecture.md) | find your way around the code |
| [Contributing](https://github.com/sahebbiswas/pycrefine/blob/main/CONTRIBUTING.md) | set up a development environment, run the checks, version and release |

## Contributing

Bug reports with the `.pyc` file (or the source it came from) and the Python version that
compiled it are the most useful contribution. See [CONTRIBUTING.md](https://github.com/sahebbiswas/pycrefine/blob/main/CONTRIBUTING.md) for
the development setup, the checks every pull request runs, and the versioning policy.

## License

[MIT](https://github.com/sahebbiswas/pycrefine/blob/main/LICENSE)
