Skip to main content

pycodelift

Build-time class-inheritance flattener. Write thin diff-only child classes against a base file; get back a single self-contained module with the inheritance inlined.

Generalizes HuggingFace transformers' modular codegen into a framework-agnostic library. Status: alpha.

When this is worth using

When all three apply:

  1. Many sibling files share a base (10+).
  2. They are read and forked, not just called.
  3. Edits to the base must not silently ripple into already-released siblings.

For five subclasses in a normal app, plain Python inheritance is the right answer.

Install

pip install pycodelift     # or: uv add pycodelift

Quickstart

mypkg/
├── base/modeling_base.py       # parent
└── child/modular_child.py      # diff

mypkg/child/modular_child.py:

from ..base.modeling_base import BaseModel

class ChildModel(BaseModel):
    def __init__(self, config):
        super().__init__(config)
        self.y = 2

__all__ = ["ChildModel"]

Convert:

pycodelift convert mypkg/child/modular_child.py --package mypkg

Or:

from pycodelift import Flattener
files = Flattener(package_name="mypkg").convert("mypkg/child/modular_child.py")
print(files["modeling"])

The output modeling_child.py has BaseModel's body inlined and no inheritance edge.

How it works

Eight CST passes: parse → walk → resolve parent classes → inline-flatten one level → case-preserving rename → pull in transitive helpers → split outputs by class-suffix → render. Each pass with code examples in docs/how-it-works.md.

Policies

Flattener(...) keyword args (all optional):

Argument Purpose Default
rename irregular casing overrides snake↔Pascal derivation
file_types suffix → output stem (Config → configuration_<x>.py) everything → modeling_<x>.py
pre_body_vars top-level vars that come first ("logger",)
skip_imports imports to drop ()
post_class_hooks e.g. TrailingCallHook("post_init") for trailing-call rules ()
header_template banner with {relative_path} / {short_name} slots default banner
excluded_external_files per-package files to skip when walking imports None
prepend_namespace_parent transformers' optimum.habana-style prefix False

flatten_levels=2 and non-empty special_bases raise NotImplementedError in v0.1.

transformers compatibility

from pycodelift.adapters.transformers import make_transformers_flattener

flattener = make_transformers_flattener()
files = flattener.convert("src/transformers/models/olmo2/modular_olmo2.py")

The adapter pins every transformers convention so output matches upstream utils/modular_model_converter.py. CLI: --transformers. Combine with --package optimum for transformers forks.

CLI

pycodelift convert <file>...      # one or many
pycodelift convert-tree <root>     # recursive
pycodelift describe                # dump effective config as JSON

Flags: --package, --transformers, --write, --target-dir.

Caveats

  • One-level flatten only. Foo2(Foo) works; Foo's own parent is not inlined.
  • Not thread-safe (v0.1 mutates module-level vendor state). Use a process pool for parallelism.
  • del self.x is line-level — removes the assignment, not later references.

Examples

Three runnable mini-projects under examples/: 01_minimal, 02_split_outputs, 03_transformers_compat.

Lineage

Derived from huggingface/transformers's utils/modular_model_converter.py (Apache-2.0). The CST passes are theirs (battle-tested across 200+ models); pycodelift extracts the policy slots they hard-coded. See NOTICE.

License

Apache-2.0.

Metadata

Release files for pycodelift 0.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pycodelift 0.0.1
File Size Uploaded
pycodelift-0.0.1.tar.gz 61.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pycodelift 0.0.1
File Interpreter ABI Platform
pycodelift-0.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 114.6 kB

Release files / pycodelift-0.0.1.tar.gz

Download URL pycodelift-0.0.1.tar.gz
Size 61.5 kB
Tags Source
SHA-256 checksum
How to use checksums
075936374a1fcd5018609ebeea03724120679bc71c234d0ff6997f34ae431d8a
BLAKE2b-256 checksum
How to use checksums
b6dcb8046b9861f774d9c84eb018e3b3dfb22dcc332daf1ddbb7f6d2a643d1af
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / pycodelift-0.0.1-py3-none-any.whl

Download URL pycodelift-0.0.1-py3-none-any.whl
Size 53.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9a9e763aff188de2e869bb9b537190a926ae183ea34ef91eae48eb3d3d7b7d23
BLAKE2b-256 checksum
How to use checksums
9bf402ad27178bb806697648b5a174cc619a2658fcb0e18348963ec07b761182
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

0.0.1 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page