Skip to main content

Build-time class-inheritance flattener — generalize HuggingFace transformers' modular code-gen to any Python project.

Project description

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 (Configconfiguration_<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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pycodelift-0.0.1.tar.gz (61.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pycodelift-0.0.1-py3-none-any.whl (53.1 kB view details)

Uploaded Python 3

File details

Details for the file pycodelift-0.0.1.tar.gz.

File metadata

  • Download URL: pycodelift-0.0.1.tar.gz
  • Upload date:
  • Size: 61.5 kB
  • Tags: Source
  • Uploaded using 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}

File hashes

Hashes for pycodelift-0.0.1.tar.gz
Algorithm Hash digest
SHA256 075936374a1fcd5018609ebeea03724120679bc71c234d0ff6997f34ae431d8a
MD5 99ef524ad3d9dd6b803272f5781d4af2
BLAKE2b-256 b6dcb8046b9861f774d9c84eb018e3b3dfb22dcc332daf1ddbb7f6d2a643d1af

See more details on using hashes here.

File details

Details for the file pycodelift-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: pycodelift-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 53.1 kB
  • Tags: Python 3
  • Uploaded using 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}

File hashes

Hashes for pycodelift-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 9a9e763aff188de2e869bb9b537190a926ae183ea34ef91eae48eb3d3d7b7d23
MD5 de0f37a252c4edbce8b6a0c78959d1ac
BLAKE2b-256 9bf402ad27178bb806697648b5a174cc619a2658fcb0e18348963ec07b761182

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page