Retrieve attributes without triggering dynamic lookup via the descriptor protocol, __getattr__ or __getattribute__. Note: this function may not be able to retrieve all attributes that getattr can fetch (like dynamically created attributes) and may find attributes that g
(obj, attr, default=_sentinel)
| 1723 | |
| 1724 | |
| 1725 | def getattr_static(obj, attr, default=_sentinel): |
| 1726 | """Retrieve attributes without triggering dynamic lookup via the |
| 1727 | descriptor protocol, __getattr__ or __getattribute__. |
| 1728 | |
| 1729 | Note: this function may not be able to retrieve all attributes |
| 1730 | that getattr can fetch (like dynamically created attributes) |
| 1731 | and may find attributes that getattr can't (like descriptors |
| 1732 | that raise AttributeError). It can also return descriptor objects |
| 1733 | instead of instance members in some cases. See the |
| 1734 | documentation for details. |
| 1735 | """ |
| 1736 | instance_result = _sentinel |
| 1737 | |
| 1738 | objtype = type(obj) |
| 1739 | if type not in _static_getmro(objtype): |
| 1740 | klass = objtype |
| 1741 | dict_attr = _shadowed_dict(klass) |
| 1742 | if (dict_attr is _sentinel or |
| 1743 | type(dict_attr) is types.MemberDescriptorType): |
| 1744 | instance_result = _check_instance(obj, attr) |
| 1745 | else: |
| 1746 | klass = obj |
| 1747 | |
| 1748 | klass_result = _check_class(klass, attr) |
| 1749 | |
| 1750 | if instance_result is not _sentinel and klass_result is not _sentinel: |
| 1751 | if _check_class(type(klass_result), "__get__") is not _sentinel and ( |
| 1752 | _check_class(type(klass_result), "__set__") is not _sentinel |
| 1753 | or _check_class(type(klass_result), "__delete__") is not _sentinel |
| 1754 | ): |
| 1755 | return klass_result |
| 1756 | |
| 1757 | if instance_result is not _sentinel: |
| 1758 | return instance_result |
| 1759 | if klass_result is not _sentinel: |
| 1760 | return klass_result |
| 1761 | |
| 1762 | if obj is klass: |
| 1763 | # for types we check the metaclass too |
| 1764 | for entry in _static_getmro(type(klass)): |
| 1765 | if ( |
| 1766 | _shadowed_dict(type(entry)) is _sentinel |
| 1767 | and attr in entry.__dict__ |
| 1768 | ): |
| 1769 | return entry.__dict__[attr] |
| 1770 | if default is not _sentinel: |
| 1771 | return default |
| 1772 | raise AttributeError(attr) |
| 1773 | |
| 1774 | |
| 1775 | # ------------------------------------------------ generator introspection |
no test coverage detected