abc.py (3710B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\stdlib\abc.py 2 import types 3 from _weakrefset import WeakSet 4 5 class _C: 6 pass 7 8 9 _InstanceType = type(_C()) 10 11 def abstractmethod(funcobj): 12 funcobj.__isabstractmethod__ = True 13 return funcobj 14 15 16 class abstractproperty(property): 17 __isabstractmethod__ = True 18 19 20 class ABCMeta(type): 21 _abc_invalidation_counter = 0 22 23 def __new__(mcls, name, bases, namespace): 24 cls = super(ABCMeta, mcls).__new__(mcls, name, bases, namespace) 25 abstracts = set((name for name, value in namespace.items() if getattr(value, '__isabstractmethod__', False))) 26 for base in bases: 27 for name in getattr(base, '__abstractmethods__', set()): 28 value = getattr(cls, name, None) 29 if getattr(value, '__isabstractmethod__', False): 30 abstracts.add(name) 31 32 cls.__abstractmethods__ = frozenset(abstracts) 33 cls._abc_registry = WeakSet() 34 cls._abc_cache = WeakSet() 35 cls._abc_negative_cache = WeakSet() 36 cls._abc_negative_cache_version = ABCMeta._abc_invalidation_counter 37 return cls 38 39 def register(cls, subclass): 40 if not isinstance(subclass, (type, types.ClassType)): 41 raise TypeError('Can only register classes') 42 if issubclass(subclass, cls): 43 return 44 if issubclass(cls, subclass): 45 raise RuntimeError('Refusing to create an inheritance cycle') 46 cls._abc_registry.add(subclass) 47 ABCMeta._abc_invalidation_counter += 1 48 49 def _dump_registry(cls, file = None): 50 print >> file, 'Class: %s.%s' % (cls.__module__, cls.__name__) 51 print >> file, 'Inv.counter: %s' % ABCMeta._abc_invalidation_counter 52 for name in sorted(cls.__dict__.keys()): 53 if name.startswith('_abc_'): 54 value = getattr(cls, name) 55 print >> file, '%s: %r' % (name, value) 56 57 def __instancecheck__(cls, instance): 58 subclass = getattr(instance, '__class__', None) 59 if subclass is not None and subclass in cls._abc_cache: 60 return True 61 subtype = type(instance) 62 if subtype is _InstanceType: 63 subtype = subclass 64 if subtype is subclass or subclass is None: 65 if cls._abc_negative_cache_version == ABCMeta._abc_invalidation_counter and subtype in cls._abc_negative_cache: 66 return False 67 return cls.__subclasscheck__(subtype) 68 return cls.__subclasscheck__(subclass) or cls.__subclasscheck__(subtype) 69 70 def __subclasscheck__(cls, subclass): 71 if subclass in cls._abc_cache: 72 return True 73 if cls._abc_negative_cache_version < ABCMeta._abc_invalidation_counter: 74 cls._abc_negative_cache = WeakSet() 75 cls._abc_negative_cache_version = ABCMeta._abc_invalidation_counter 76 elif subclass in cls._abc_negative_cache: 77 return False 78 ok = cls.__subclasshook__(subclass) 79 if ok is not NotImplemented: 80 if ok: 81 cls._abc_cache.add(subclass) 82 else: 83 cls._abc_negative_cache.add(subclass) 84 return ok 85 if cls in getattr(subclass, '__mro__', ()): 86 cls._abc_cache.add(subclass) 87 return True 88 for rcls in cls._abc_registry: 89 if issubclass(subclass, rcls): 90 cls._abc_cache.add(subclass) 91 return True 92 93 for scls in cls.__subclasses__(): 94 if issubclass(subclass, scls): 95 cls._abc_cache.add(subclass) 96 return True 97 98 cls._abc_negative_cache.add(subclass) 99 return False