MCPcopy Index your code
hub / github.com/python/cpython / classify_class_attrs

Function classify_class_attrs

Lib/inspect.py:541–653  ·  view source on GitHub ↗

Return list of attribute-descriptor tuples. For each name in dir(cls), the return list contains a 4-tuple with these elements: 0. The name (a string). 1. The kind of attribute this is, one of these strings: 'class method' created via classmethod()

(cls)

Source from the content-addressed store, hash-verified

539Attribute = namedtuple('Attribute', 'name kind defining_class object')
540
541def classify_class_attrs(cls):
542 """Return list of attribute-descriptor tuples.
543
544 For each name in dir(cls), the return list contains a 4-tuple
545 with these elements:
546
547 0. The name (a string).
548
549 1. The kind of attribute this is, one of these strings:
550 'class method' created via classmethod()
551 'static method' created via staticmethod()
552 'property' created via property()
553 'method' any other flavor of method or descriptor
554 'data' not a method
555
556 2. The class which defined this attribute (a class).
557
558 3. The object as obtained by calling getattr; if this fails, or if the
559 resulting object does not live anywhere in the class' mro (including
560 metaclasses) then the object is looked up in the defining class's
561 dict (found by walking the mro).
562
563 If one of the items in dir(cls) is stored in the metaclass it will now
564 be discovered and not have None be listed as the class in which it was
565 defined. Any items whose home class cannot be discovered are skipped.
566 """
567
568 mro = getmro(cls)
569 metamro = getmro(type(cls)) # for attributes stored in the metaclass
570 metamro = tuple(cls for cls in metamro if cls not in (type, object))
571 class_bases = (cls,) + mro
572 all_bases = class_bases + metamro
573 names = dir(cls)
574 # :dd any DynamicClassAttributes to the list of names;
575 # this may result in duplicate entries if, for example, a virtual
576 # attribute with the same name as a DynamicClassAttribute exists.
577 for base in mro:
578 for k, v in base.__dict__.items():
579 if isinstance(v, types.DynamicClassAttribute) and v.fget is not None:
580 names.append(k)
581 result = []
582 processed = set()
583
584 for name in names:
585 # Get the object associated with the name, and where it was defined.
586 # Normal objects will be looked up with both getattr and directly in
587 # its class' dict (in case getattr fails [bug #1785], and also to look
588 # for a docstring).
589 # For DynamicClassAttributes on the second pass we only look in the
590 # class's dict.
591 #
592 # Getting an obj from the __dict__ sometimes reveals more than
593 # using getattr. Static and class methods are dramatic examples.
594 homecls = None
595 get_obj = None
596 dict_obj = None
597 if name not in processed:
598 try:

Callers

nothing calls this directly

Calls 8

getmroFunction · 0.85
setFunction · 0.85
isroutineFunction · 0.85
AttributeClass · 0.85
itemsMethod · 0.45
appendMethod · 0.45
__getattr__Method · 0.45
addMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…