---
paths:
  - "*/src/**/*.py"
  - "*/tests/**/*.py"
---

# attrs Patterns

How to use attrs across codeflash packages.

## Frozen Data Classes (Default Choice)

```python
@attrs.frozen
class ServicePing:
    """
    A service ping with the service type it belongs to.
    """

    svc_type: type
    ping: Callable[..., None]
```

`@attrs.frozen` gives: `frozen=True`, `slots=True`, `hash=True`. This is the default for data-bearing classes.

## Mutable When Needed

```python
@attrs.define
class Registry:
    """
    A central registry for services.
    """

    _services: dict[type, RegisteredService] = attrs.Factory(dict)
    _on_close: list[Callable[..., Any]] = attrs.Factory(list)

    def register_factory(self, svc_type: type, factory: Callable) -> None:
        ...
```

`@attrs.define` gives `slots=True` but allows mutation. Use for objects with lifecycle (registries, containers, builders).

## Field Customization

```python
@attrs.frozen
class Config:
    _processors: Sequence[Processor] = attrs.field(
        alias="processors",
    )
    _context_class: type[dict[str, Any]] = attrs.field(
        default=dict,
        alias="context_class",
    )
    _logger_factory: Callable[..., Any] | None = attrs.field(
        default=None,
        alias="logger_factory",
    )
```

Private attributes with public constructor aliases. Users write `Config(processors=[...])`, internal code accesses `self._processors`.

## Validators

```python
@attrs.frozen
class Retrying:
    attempts: int = attrs.field(validator=attrs.validators.gt(0))
    timeout: float | None = attrs.field(
        default=45.0,
        validator=attrs.validators.optional(attrs.validators.gt(0)),
    )
```

Use attrs validators, not property setters. Validation happens at construction time, which is where invalid data should be caught.

## Legacy API

Never use `@attrs.s` in new code — that's legacy. Use `@attrs.frozen` (immutable) or `@attrs.define` (mutable). Use `attrs.Factory` for mutable defaults, `attrs.field` for validators/aliases, `attrs.Attribute` for metadata.
