Summary of module attributes and types. This is used for instances of types.ModuleType, because they can have different attributes per instance, and for type narrowing with hasattr() checks.
| 1527 | |
| 1528 | |
| 1529 | class ExtraAttrs: |
| 1530 | """Summary of module attributes and types. |
| 1531 | |
| 1532 | This is used for instances of types.ModuleType, because they can have different |
| 1533 | attributes per instance, and for type narrowing with hasattr() checks. |
| 1534 | """ |
| 1535 | |
| 1536 | def __init__( |
| 1537 | self, |
| 1538 | attrs: dict[str, Type], |
| 1539 | immutable: set[str] | None = None, |
| 1540 | mod_name: str | None = None, |
| 1541 | ) -> None: |
| 1542 | self.attrs = attrs |
| 1543 | if immutable is None: |
| 1544 | immutable = set() |
| 1545 | self.immutable = immutable |
| 1546 | self.mod_name = mod_name |
| 1547 | |
| 1548 | def __hash__(self) -> int: |
| 1549 | return hash((tuple(self.attrs.items()), tuple(sorted(self.immutable)))) |
| 1550 | |
| 1551 | def __eq__(self, other: object) -> bool: |
| 1552 | if not isinstance(other, ExtraAttrs): |
| 1553 | return NotImplemented |
| 1554 | return self.attrs == other.attrs and self.immutable == other.immutable |
| 1555 | |
| 1556 | def copy(self) -> ExtraAttrs: |
| 1557 | return ExtraAttrs(self.attrs.copy(), self.immutable.copy(), self.mod_name) |
| 1558 | |
| 1559 | def __repr__(self) -> str: |
| 1560 | return f"ExtraAttrs({self.attrs!r}, {self.immutable!r}, {self.mod_name!r})" |
| 1561 | |
| 1562 | def serialize(self) -> JsonDict: |
| 1563 | return { |
| 1564 | ".class": "ExtraAttrs", |
| 1565 | "attrs": {k: v.serialize() for k, v in self.attrs.items()}, |
| 1566 | "immutable": sorted(self.immutable), |
| 1567 | "mod_name": self.mod_name, |
| 1568 | } |
| 1569 | |
| 1570 | @classmethod |
| 1571 | def deserialize(cls, data: JsonDict) -> ExtraAttrs: |
| 1572 | assert data[".class"] == "ExtraAttrs" |
| 1573 | return ExtraAttrs( |
| 1574 | {k: deserialize_type(v) for k, v in data["attrs"].items()}, |
| 1575 | set(data["immutable"]), |
| 1576 | data["mod_name"], |
| 1577 | ) |
| 1578 | |
| 1579 | def write(self, data: WriteBuffer) -> None: |
| 1580 | write_tag(data, EXTRA_ATTRS) |
| 1581 | write_type_map(data, self.attrs) |
| 1582 | write_str_list(data, sorted(self.immutable)) |
| 1583 | write_str_opt(data, self.mod_name) |
| 1584 | write_tag(data, END_TAG) |
| 1585 | |
| 1586 | @classmethod |
no outgoing calls
no test coverage detected
searching dependent graphs…