@@ -440,9 +440,7 @@ def isabstract(object):
440
440
return True
441
441
return False
442
442
443
- def getmembers (object , predicate = None ):
444
- """Return all members of an object as (name, value) pairs sorted by name.
445
- Optionally, only return members that satisfy a given predicate."""
443
+ def _getmembers (object , predicate , getter ):
446
444
if isclass (object ):
447
445
mro = (object ,) + getmro (object )
448
446
else :
@@ -465,7 +463,7 @@ def getmembers(object, predicate=None):
465
463
# like calling their __get__ (see bug #1785), so fall back to
466
464
# looking in the __dict__.
467
465
try :
468
- value = getattr (object , key )
466
+ value = getter (object , key )
469
467
# handle the duplicate key
470
468
if key in processed :
471
469
raise AttributeError
@@ -484,6 +482,25 @@ def getmembers(object, predicate=None):
484
482
results .sort (key = lambda pair : pair [0 ])
485
483
return results
486
484
485
+ def getmembers (object , predicate = None ):
486
+ """Return all members of an object as (name, value) pairs sorted by name.
487
+ Optionally, only return members that satisfy a given predicate."""
488
+ return _getmembers (object , predicate , getattr )
489
+
490
+ def getmembers_static (object , predicate = None ):
491
+ """Return all members of an object as (name, value) pairs sorted by name
492
+ without triggering dynamic lookup via the descriptor protocol,
493
+ __getattr__ or __getattribute__. Optionally, only return members that
494
+ satisfy a given predicate.
495
+
496
+ Note: this function may not be able to retrieve all members
497
+ that getmembers can fetch (like dynamically created attributes)
498
+ and may find members that getmembers can't (like descriptors
499
+ that raise AttributeError). It can also return descriptor objects
500
+ instead of instance members in some cases.
501
+ """
502
+ return _getmembers (object , predicate , getattr_static )
503
+
487
504
Attribute = namedtuple ('Attribute' , 'name kind defining_class object' )
488
505
489
506
def classify_class_attrs (cls ):
0 commit comments