File tree 3 files changed +32
-5
lines changed
3 files changed +32
-5
lines changed Original file line number Diff line number Diff line change @@ -342,8 +342,9 @@ inspect
342
342
(Contributed by Thomas Krennwallner in :issue: `35759 `.)
343
343
344
344
* 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 `.)
347
348
348
349
pathlib
349
350
-------
@@ -597,7 +598,7 @@ typing
597
598
:func: `runtime-checkable protocols <typing.runtime_checkable> ` has changed
598
599
significantly. Most ``isinstance() `` checks against protocols with only a few
599
600
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
601
602
or more members may be slower than in Python 3.11. (Contributed by Alex
602
603
Waygood in :gh: `74690 ` and :gh: `103193 `.)
603
604
Original file line number Diff line number Diff line change @@ -1794,8 +1794,9 @@ def _check_class(klass, attr):
1794
1794
return entry .__dict__ [attr ]
1795
1795
return _sentinel
1796
1796
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 :
1799
1800
dunder_dict = _get_dunder_dict_of_class (entry )
1800
1801
if '__dict__' in dunder_dict :
1801
1802
class_dict = dunder_dict ['__dict__' ]
@@ -1805,6 +1806,9 @@ def _shadowed_dict(klass):
1805
1806
return class_dict
1806
1807
return _sentinel
1807
1808
1809
+ def _shadowed_dict (klass ):
1810
+ return _shadowed_dict_from_mro_tuple (_static_getmro (klass ))
1811
+
1808
1812
def getattr_static (obj , attr , default = _sentinel ):
1809
1813
"""Retrieve attributes without triggering dynamic lookup via the
1810
1814
descriptor protocol, __getattr__ or __getattribute__.
Original file line number Diff line number Diff line change @@ -2111,6 +2111,28 @@ def __dict__(self):
2111
2111
self .assertEqual (inspect .getattr_static (foo , 'a' ), 3 )
2112
2112
self .assertFalse (test .called )
2113
2113
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
+
2114
2136
def test_custom_object_dict (self ):
2115
2137
test = self
2116
2138
test .called = False
You can’t perform that action at this time.
0 commit comments