Skip to main content

A Lombok-inspired boilerplate-elimination library for Python.

Project description

inito

A Lombok-inspired boilerplate-elimination library for Python. inito generates constructors, repr, equality/hashing, accessors, and fluent builders once at class-decoration time — never at instance construction or attribute-access time — so the generated classes perform like handwritten ones. Zero runtime dependencies.

Install

pip install inito

or

uv add inito

Quick start

from inito import Data


@Data
class User:
    name: str
    age: int = 0


user = User("Ada", age=30)
print(user)              # User(name='Ada', age=30)
print(user.get_name())   # Ada
user.set_age(31)

@Data also accepts options:

from inito import Data


@Data(frozen=True)
class Point:
    x: int
    y: int

@builder generates a fluent, chainable builder, and composes with @dataclass:

from dataclasses import dataclass
from inito import builder


@builder(to_builder=True)
@dataclass
class Request:
    prompt: str
    temperature: float = 0.7


request = Request.builder().prompt("hello").build()
revised = request.to_builder().temperature(0.9).build()

Type checking

inito ships a mypy plugin that synthesizes every generated member (__init__'s real signature, get_x/set_x, .builder()/Builder/ .to_builder()) so mypy --strict sees your decorated classes correctly — no # type: ignore needed. Enable it in your pyproject.toml or mypy.ini:

[tool.mypy]
plugins = ["inito.typing.mypy_plugin"]

The plugin is mypy-only — pyright has no third-party plugin mechanism. @Data and @AllArgsConstructor additionally ship a .pyi stub marked with the standard typing.dataclass_transform (PEP 681), so pyright also gets a correctly-typed __init__ for those two decorators — no plugin needed, since this is a standard both tools understand natively. get_x/set_x and @Builder's fluent chain remain pyright's gap regardless (see below), since dataclass_transform can only express a constructor signature, not arbitrary generated methods.

Status

Implemented today: @Data (constructor, __repr__, __eq__, __hash__, getters, setters), @Getter (getters only), @Setter (setters only), @NoArgsConstructor (no-argument constructor using field defaults), @AllArgsConstructor (constructor only, every field), @RequiredArgsConstructor (constructor only accepting required fields), @Builder/builder (fluent builder, to_builder=True support), @ToString (__repr__ only — pairs well with @Builder for a readable repr without pulling in @Data's constructor/eq/hash/accessors), and @EqualsAndHashCode (__eq__/__hash__ only).

All of inito.md's Initial Features (v1) are now implemented. See docs/performance.md for benchmarks against handwritten classes, dataclasses, and attrs. See TASKS.md for what's left: docs, CI hardening, and release.

Known limitation: pyright doesn't see most generated members

Every generated member (get_x, set_x, .builder(), .to_builder(), the generated constructor's parameters, ...) is attached to your class via setattr at decoration time — real attributes at runtime. mypy sees all of them correctly once you enable the bundled plugin (the same approach attrs/Pydantic use). pyright has no equivalent third-party plugin mechanism, so get_x/set_x and @Builder's fluent chain still show up as unknown attributes there — your code runs correctly regardless, this is a pyright-only static-typing gap.

@Data's and @AllArgsConstructor's constructors are the exception: pyright does see these correctly, via a .pyi stub marked with the standard typing.dataclass_transform (no inito-specific plugin needed — this is a mechanism pyright supports natively). This doesn't extend to @NoArgsConstructor/@RequiredArgsConstructor: both were deliberately left unmarked, since their real signatures diverge from what dataclass_transform can express (@NoArgsConstructor truly accepts zero arguments rather than "all fields optional"; @RequiredArgsConstructor excludes defaulted fields from __init__ entirely rather than making them optional) — applying the marker there would make pyright silently accept calls the real runtime rejects, which is worse than the current honest gap. Closing the remaining gap for get_x/set_x/@Builder would need a different strategy (e.g. a companion stub generator); tracked in TASKS.md Phase 17, not required for this release.

Known limitations: frozen dataclasses and self-referential fields

Stacking any inito constructor-generating decorator (@Data, @Builder, @AllArgsConstructor, ...) with @dataclass(frozen=True) — in either order — raises dataclasses.FrozenInstanceError. This is expected, not a bug: the generated __init__/build() assign fields with plain self.x = value, which correctly respects the frozen class's blocking __setattr__ rather than silently bypassing the immutability you asked for. If you want inito's own frozen-style behavior, use @Data(frozen=True) (which just omits setters) instead of also stacking @dataclass(frozen=True).

Self-referential type hints (e.g. a linked-list next: Node) also aren't supported: inito resolves annotations eagerly, once, at decoration time — before the class's own name is bound in its module's globals — so a forward reference to the class currently being decorated can't resolve. Forward references to any other, already-defined class work normally.

Contributing

See CONTRIBUTING.md.

License

MIT — see LICENSE.

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

inito-0.0.3b0.tar.gz (56.2 kB view details)

Uploaded Source

Built Distribution

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

inito-0.0.3b0-py3-none-any.whl (32.8 kB view details)

Uploaded Python 3

File details

Details for the file inito-0.0.3b0.tar.gz.

File metadata

  • Download URL: inito-0.0.3b0.tar.gz
  • Upload date:
  • Size: 56.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for inito-0.0.3b0.tar.gz
Algorithm Hash digest
SHA256 f30196b2538c6037894c3e1260e532d1516582887570b1555290040a88b8f116
MD5 4bbe405005e99b4ba7d0190552331752
BLAKE2b-256 fd0c6acc1306df4f5443533c8ef99a9e2f91669ac315e423fafebfc15cb26ef3

See more details on using hashes here.

Provenance

The following attestation bundles were made for inito-0.0.3b0.tar.gz:

Publisher: release.yml on swtnk/inito

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file inito-0.0.3b0-py3-none-any.whl.

File metadata

  • Download URL: inito-0.0.3b0-py3-none-any.whl
  • Upload date:
  • Size: 32.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for inito-0.0.3b0-py3-none-any.whl
Algorithm Hash digest
SHA256 43274a17bb92257bb5d4b71ca4ef199c58b30eb6b821b8a0842bdf0e1367c11a
MD5 a8ca19f275d795faefef251311a5aa63
BLAKE2b-256 1412edb22f97e85605f9f61da8fc95266bb1ce03ec98a682785eacc6b914f9cd

See more details on using hashes here.

Provenance

The following attestation bundles were made for inito-0.0.3b0-py3-none-any.whl:

Publisher: release.yml on swtnk/inito

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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