(
ctx: mypy.plugin.ClassDefContext,
auto_attribs_default: bool | None,
frozen_default: bool,
slots_default: bool,
)
| 336 | |
| 337 | |
| 338 | def attr_class_maker_callback_impl( |
| 339 | ctx: mypy.plugin.ClassDefContext, |
| 340 | auto_attribs_default: bool | None, |
| 341 | frozen_default: bool, |
| 342 | slots_default: bool, |
| 343 | ) -> bool: |
| 344 | info = ctx.cls.info |
| 345 | |
| 346 | init = _get_decorator_bool_argument(ctx, "init", True) |
| 347 | frozen = _get_frozen(ctx, frozen_default) |
| 348 | order = _determine_eq_order(ctx) |
| 349 | slots = _get_decorator_bool_argument(ctx, "slots", slots_default) |
| 350 | |
| 351 | auto_attribs = _get_decorator_optional_bool_argument(ctx, "auto_attribs", auto_attribs_default) |
| 352 | kw_only = _get_decorator_bool_argument(ctx, "kw_only", False) |
| 353 | match_args = _get_decorator_bool_argument(ctx, "match_args", True) |
| 354 | |
| 355 | for super_info in ctx.cls.info.mro[1:-1]: |
| 356 | if "attrs_tag" in super_info.metadata and "attrs" not in super_info.metadata: |
| 357 | # Super class is not ready yet. Request another pass. |
| 358 | return False |
| 359 | |
| 360 | attributes = _analyze_class(ctx, auto_attribs, kw_only) |
| 361 | |
| 362 | # Check if attribute types are ready. |
| 363 | for attr in attributes: |
| 364 | node = info.get(attr.name) |
| 365 | if node is None: |
| 366 | # This name is likely blocked by some semantic analysis error that |
| 367 | # should have been reported already. |
| 368 | _add_empty_metadata(info) |
| 369 | return True |
| 370 | |
| 371 | _add_attrs_magic_attribute(ctx, [(attr.name, info[attr.name].type) for attr in attributes]) |
| 372 | if slots: |
| 373 | _add_slots(ctx, attributes) |
| 374 | if match_args: |
| 375 | _add_match_args(ctx, attributes) |
| 376 | |
| 377 | # Save the attributes so that subclasses can reuse them. |
| 378 | ctx.cls.info.metadata["attrs"] = { |
| 379 | "attributes": [attr.serialize() for attr in attributes], |
| 380 | "frozen": frozen, |
| 381 | } |
| 382 | |
| 383 | adder = MethodAdder(ctx) |
| 384 | # If __init__ is not being generated, attrs still generates it as __attrs_init__ instead. |
| 385 | _add_init(ctx, attributes, adder, "__init__" if init else ATTRS_INIT_NAME) |
| 386 | |
| 387 | if order: |
| 388 | _add_order(ctx, adder) |
| 389 | if frozen: |
| 390 | _make_frozen(ctx, attributes) |
| 391 | # Frozen classes are hashable by default, even if inheriting from non-frozen ones. |
| 392 | hashable: bool | None = _get_decorator_bool_argument( |
| 393 | ctx, "hash", True |
| 394 | ) and _get_decorator_bool_argument(ctx, "unsafe_hash", True) |
| 395 | else: |
no test coverage detected
searching dependent graphs…