A codemod to modernize your attrs usage by:
- Converting
@attr.s
and@attrs.s
decorators to@define
- Moving type hints from
attr.ib(type=...)
to Python type annotations - Converting
attr.ib()
toattrs.field()
- Removing empty
field()
calls when no other arguments are present
You can run the codemod without installing by using uvx
or pipx run
:
uvx git+https://github.com/jonathanberthias/modernize-attrs src_dir_or_file
The codemod will convert code like this:
import attr
@attr.s
class MyClass:
x = attr.ib(type=int, converter=int)
y = attr.ib(type=str, default="hello")
Into:
from attrs import define, field
@define
class MyClass:
x: int = field(converter=int)
y: str = "hello"
The old way of using attr.s
and attr.ib
is now considered outdated.
The attrs
library has introduced @define
and field()
to provide a more Pythonic way of defining classes with attributes, leveraging type hints for better clarity and tooling support.
In particular, only Mypy can understand the type=
argument in attr.ib()
, making it harder to use other type checkers or get pleasant IDE support.
- The codemod will skip any class that contains
attr.ib()
calls without type hints and print a warning - Existing type annotations are preserved
- Other
attr.ib()
arguments (likedefault
,validator
, etc.) are preserved in thefield()
call
- Python >= 3.11
- libcst >= 1.5.1
To set up for development:
# Clone the repository
git clone https://github.com/jonathanberthias/modernize-attrs
cd modernize-attrs
# Create a virtual environment and install dependencies
uv sync
# Run tests
uv run pytest