| 476 | return False |
| 477 | |
| 478 | def _getmembers(object, predicate, getter): |
| 479 | results = [] |
| 480 | processed = set() |
| 481 | names = dir(object) |
| 482 | if isclass(object): |
| 483 | mro = getmro(object) |
| 484 | # add any DynamicClassAttributes to the list of names if object is a class; |
| 485 | # this may result in duplicate entries if, for example, a virtual |
| 486 | # attribute with the same name as a DynamicClassAttribute exists |
| 487 | try: |
| 488 | for base in object.__bases__: |
| 489 | for k, v in base.__dict__.items(): |
| 490 | if isinstance(v, types.DynamicClassAttribute): |
| 491 | names.append(k) |
| 492 | except AttributeError: |
| 493 | pass |
| 494 | else: |
| 495 | mro = () |
| 496 | for key in names: |
| 497 | # First try to get the value via getattr. Some descriptors don't |
| 498 | # like calling their __get__ (see bug #1785), so fall back to |
| 499 | # looking in the __dict__. |
| 500 | try: |
| 501 | value = getter(object, key) |
| 502 | # handle the duplicate key |
| 503 | if key in processed: |
| 504 | raise AttributeError |
| 505 | except AttributeError: |
| 506 | for base in mro: |
| 507 | if key in base.__dict__: |
| 508 | value = base.__dict__[key] |
| 509 | break |
| 510 | else: |
| 511 | # could be a (currently) missing slot member, or a buggy |
| 512 | # __dir__; discard and move on |
| 513 | continue |
| 514 | if not predicate or predicate(value): |
| 515 | results.append((key, value)) |
| 516 | processed.add(key) |
| 517 | results.sort(key=lambda pair: pair[0]) |
| 518 | return results |
| 519 | |
| 520 | def getmembers(object, predicate=None): |
| 521 | """Return all members of an object as (name, value) pairs sorted by name. |