Transform all `_CountingAttr`s on a class into `Attribute`s. If *these* is passed, use that and don't look for them on the class. If *collect_by_mro* is True, collect them in the correct MRO order, otherwise use the old -- incorrect -- order. See #428. Return an `_Attributes
(
cls,
these,
auto_attribs,
kw_only,
collect_by_mro,
field_transformer,
)
| 377 | |
| 378 | |
| 379 | def _transform_attrs( |
| 380 | cls, |
| 381 | these, |
| 382 | auto_attribs, |
| 383 | kw_only, |
| 384 | collect_by_mro, |
| 385 | field_transformer, |
| 386 | ) -> _Attributes: |
| 387 | """ |
| 388 | Transform all `_CountingAttr`s on a class into `Attribute`s. |
| 389 | |
| 390 | If *these* is passed, use that and don't look for them on the class. |
| 391 | |
| 392 | If *collect_by_mro* is True, collect them in the correct MRO order, |
| 393 | otherwise use the old -- incorrect -- order. See #428. |
| 394 | |
| 395 | Return an `_Attributes`. |
| 396 | """ |
| 397 | cd = cls.__dict__ |
| 398 | anns = _get_annotations(cls) |
| 399 | |
| 400 | if these is not None: |
| 401 | ca_list = list(these.items()) |
| 402 | elif auto_attribs is True: |
| 403 | ca_names = { |
| 404 | name |
| 405 | for name, attr in cd.items() |
| 406 | if attr.__class__ is _CountingAttr |
| 407 | } |
| 408 | ca_list = [] |
| 409 | annot_names = set() |
| 410 | for attr_name, type in anns.items(): |
| 411 | if _is_class_var(type): |
| 412 | continue |
| 413 | annot_names.add(attr_name) |
| 414 | a = cd.get(attr_name, NOTHING) |
| 415 | |
| 416 | if a.__class__ is not _CountingAttr: |
| 417 | a = attrib(a) |
| 418 | ca_list.append((attr_name, a)) |
| 419 | |
| 420 | unannotated = ca_names - annot_names |
| 421 | if unannotated: |
| 422 | raise UnannotatedAttributeError( |
| 423 | "The following `attr.ib`s lack a type annotation: " |
| 424 | + ", ".join( |
| 425 | sorted(unannotated, key=lambda n: cd.get(n).counter) |
| 426 | ) |
| 427 | + "." |
| 428 | ) |
| 429 | else: |
| 430 | ca_list = sorted( |
| 431 | ( |
| 432 | (name, attr) |
| 433 | for name, attr in cd.items() |
| 434 | if attr.__class__ is _CountingAttr |
| 435 | ), |
| 436 | key=lambda e: e[1].counter, |