Metadata-Version: 2.4
Name: inito
Version: 0.0.1b0
Summary: A Lombok-inspired boilerplate-elimination library for Python.
Project-URL: Homepage, https://github.com/swtnk/inito
Project-URL: Repository, https://github.com/swtnk/inito
Project-URL: Documentation, https://github.com/swtnk/inito#readme
Project-URL: Changelog, https://github.com/swtnk/inito/blob/main/CHANGELOG.md
Project-URL: Issues, https://github.com/swtnk/inito/issues
Author-email: Swetank Subham <swetanksubham.r@gmail.com>
License-Expression: MIT
License-File: LICENSE
Keywords: boilerplate,builder,codegen,dataclass,lombok
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
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: Typing :: Typed
Requires-Python: >=3.9
Provides-Extra: dev
Requires-Dist: attrs>=23; extra == 'dev'
Requires-Dist: furo>=2024.1; extra == 'dev'
Requires-Dist: mypy<2,>=1.11; extra == 'dev'
Requires-Dist: myst-parser>=3; extra == 'dev'
Requires-Dist: pre-commit>=3.7; extra == 'dev'
Requires-Dist: pyperf>=2.6; extra == 'dev'
Requires-Dist: pytest-benchmark>=4; extra == 'dev'
Requires-Dist: pytest-cov>=5; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Requires-Dist: sphinx>=7; extra == 'dev'
Description-Content-Type: text/markdown

# 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

```bash
pip install inito
```

or

```bash
uv add inito
```

## Quick start

```python
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:

```python
from inito import Data


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

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

```python
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()
```

## 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](./docs/performance.md) for benchmarks against
handwritten classes, `dataclasses`, and `attrs`. See [TASKS.md](./TASKS.md)
for what's left: docs, CI hardening, and release.

### Known limitation: static type checkers don't see generated members yet

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, but invisible to
`mypy`/`pyright` today, since neither tool has a plugin for inito yet. Your
code will run correctly; `mypy --strict`/`pyright` will flag those accesses
as unknown attributes in the meantime. `attrs` and Pydantic hit the same
problem and solved it with dedicated mypy plugins — that's tracked as a
future initiative (see `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](./CONTRIBUTING.md).

## License

MIT — see [LICENSE](./LICENSE).
