|
10 | 10 | try: |
11 | 11 | from _types import * |
12 | 12 | except ImportError: |
| 13 | + import inspect |
13 | 14 | import sys |
14 | 15 |
|
15 | 16 | def _f(): pass |
@@ -79,7 +80,37 @@ def _m(self): pass |
79 | 80 | # LazyImportType in pure Python cannot be guaranteed |
80 | 81 | # without overriding the filter, so there is no fallback. |
81 | 82 |
|
82 | | - del sys, _f, _g, _C, _c, _ag, _cell_factory # Not for export |
| 83 | + def enclose_lookup_special(): |
| 84 | + _sentinel = object() |
| 85 | + |
| 86 | + def lookup_special(object, name, default=_sentinel): |
| 87 | + """Lookup method name `name` on `object` skipping the instance |
| 88 | + dictionary. |
| 89 | + |
| 90 | + `name` must be a string. If the named special attribute does not exist, |
| 91 | + `default` is returned if provided, otherwise AttributeError is raised. |
| 92 | + """ |
| 93 | + |
| 94 | + cls = type(object) |
| 95 | + if not isinstance(name, str): |
| 96 | + raise TypeError( |
| 97 | + f"attribute name must be string, not '{type(name).__name__}'" |
| 98 | + ) |
| 99 | + try: |
| 100 | + descr = inspect.getattr_static(cls, name) |
| 101 | + except AttributeError: |
| 102 | + if not default is _sentinel: |
| 103 | + return default |
| 104 | + raise |
| 105 | + if hasattr(descr, "__get__"): |
| 106 | + return descr.__get__(object, cls) |
| 107 | + return descr |
| 108 | + |
| 109 | + return lookup_special |
| 110 | + |
| 111 | + lookup_special = enclose_lookup_special() |
| 112 | + |
| 113 | + del sys, inspect _f, _g, _C, _c, _ag, _cell_factory # Not for export |
83 | 114 |
|
84 | 115 | def lookup_special(object, name, *args): |
85 | 116 | """Lookup method name `name` on `object` skipping the instance |
|
0 commit comments