File tree Expand file tree Collapse file tree 3 files changed +32
-5
lines changed Expand file tree Collapse file tree 3 files changed +32
-5
lines changed Original file line number Diff line number Diff line change @@ -342,8 +342,9 @@ inspect
342342 (Contributed by Thomas Krennwallner in :issue: `35759 `.)
343343
344344* The performance of :func: `inspect.getattr_static ` has been considerably
345- improved. Most calls to the function should be around 2x faster than they
346- were in Python 3.11. (Contributed by Alex Waygood in :gh: `103193 `.)
345+ improved. Most calls to the function should be at least 2x faster than they
346+ were in Python 3.11, and some may be 6x faster or more. (Contributed by Alex
347+ Waygood in :gh: `103193 `.)
347348
348349pathlib
349350-------
@@ -597,7 +598,7 @@ typing
597598 :func: `runtime-checkable protocols <typing.runtime_checkable> ` has changed
598599 significantly. Most ``isinstance() `` checks against protocols with only a few
599600 members should be at least 2x faster than in 3.11, and some may be 20x
600- faster or more. However, ``isinstance() `` checks against protocols with seven
601+ faster or more. However, ``isinstance() `` checks against protocols with fourteen
601602 or more members may be slower than in Python 3.11. (Contributed by Alex
602603 Waygood in :gh: `74690 ` and :gh: `103193 `.)
603604
Original file line number Diff line number Diff line change @@ -1794,8 +1794,9 @@ def _check_class(klass, attr):
17941794 return entry .__dict__ [attr ]
17951795 return _sentinel
17961796
1797- def _shadowed_dict (klass ):
1798- for entry in _static_getmro (klass ):
1797+ @functools .lru_cache ()
1798+ def _shadowed_dict_from_mro_tuple (mro ):
1799+ for entry in mro :
17991800 dunder_dict = _get_dunder_dict_of_class (entry )
18001801 if '__dict__' in dunder_dict :
18011802 class_dict = dunder_dict ['__dict__' ]
@@ -1805,6 +1806,9 @@ def _shadowed_dict(klass):
18051806 return class_dict
18061807 return _sentinel
18071808
1809+ def _shadowed_dict (klass ):
1810+ return _shadowed_dict_from_mro_tuple (_static_getmro (klass ))
1811+
18081812def getattr_static (obj , attr , default = _sentinel ):
18091813 """Retrieve attributes without triggering dynamic lookup via the
18101814 descriptor protocol, __getattr__ or __getattribute__.
Original file line number Diff line number Diff line change @@ -2111,6 +2111,28 @@ def __dict__(self):
21112111 self .assertEqual (inspect .getattr_static (foo , 'a' ), 3 )
21122112 self .assertFalse (test .called )
21132113
2114+ def test_mutated_mro (self ):
2115+ test = self
2116+ test .called = False
2117+
2118+ class Foo (dict ):
2119+ a = 3
2120+ @property
2121+ def __dict__ (self ):
2122+ test .called = True
2123+ return {}
2124+
2125+ class Bar (dict ):
2126+ a = 4
2127+
2128+ class Baz (Bar ): pass
2129+
2130+ baz = Baz ()
2131+ self .assertEqual (inspect .getattr_static (baz , 'a' ), 4 )
2132+ Baz .__bases__ = (Foo ,)
2133+ self .assertEqual (inspect .getattr_static (baz , 'a' ), 3 )
2134+ self .assertFalse (test .called )
2135+
21142136 def test_custom_object_dict (self ):
21152137 test = self
21162138 test .called = False
You can’t perform that action at this time.
0 commit comments