gh-103193: Use LBYL idioms rather than EAFP in inspect.getattr_static
by AlexWaygood · Pull Request #103318 · python/cpython (original) (raw)
Yeah, I tried out doing this instead (diff is relative to my current patch, not to main
), and it's slower than what I currently have:
diff --git a/Lib/inspect.py b/Lib/inspect.py index a317f0ca74..7fcaa13750 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -1787,8 +1787,10 @@ def _check_instance(obj, attr):
def _check_class(klass, attr): for entry in _static_getmro(klass):
if _shadowed_dict(type(entry)) is _sentinel and attr in entry.__dict__:
return entry.__dict__[attr]
if _shadowed_dict(type(entry)) is _sentinel:
ret = entry.__dict__.get(attr, _sentinel)
if ret is not _sentinel:
return _sentinelreturn ret
def _is_type(obj): @@ -1800,13 +1802,13 @@ def _is_type(obj):
def _shadowed_dict(klass): for entry in _static_getmro(klass):
dunder_dict = _get_dunder_dict_of_class(entry)
if '__dict__' in dunder_dict:
class_dict = dunder_dict['__dict__']
if not (type(class_dict) is types.GetSetDescriptorType and
class_dict.__name__ == "__dict__" and
class_dict.__objclass__ is entry):
return class_dict
class_dict = _get_dunder_dict_of_class(entry).get('__dict__', _sentinel)
if class_dict is not _sentinel and not (
type(class_dict) is types.GetSetDescriptorType
and class_dict.__name__ == "__dict__"
and class_dict.__objclass__ is entry
):
return _sentinelreturn class_dict
def getattr_static(obj, attr, default=_sentinel): @@ -1845,11 +1847,10 @@ def getattr_static(obj, attr, default=_sentinel): if obj is klass: # for types we check the metaclass too for entry in _static_getmro(type(klass)):
if (
_shadowed_dict(type(entry)) is _sentinel
and attr in entry.__dict__
):
return entry.__dict__[attr]
if _shadowed_dict(type(entry)) is _sentinel:
ret = entry.__dict__.get(attr, _sentinel)
if ret is not _sentinel:
return ret
@carljm is that the kind of thing you were talking about? :)