Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/blinker/_utilities.py: 36%
92 statements
« prev ^ index » next coverage.py v7.0.1, created at 2022-12-25 06:11 +0000
« prev ^ index » next coverage.py v7.0.1, created at 2022-12-25 06:11 +0000
1from weakref import ref
3from blinker._saferef import BoundMethodWeakref
6try:
7 callable
8except NameError:
9 def callable(object):
10 return hasattr(object, '__call__')
13try:
14 from collections import defaultdict
15except:
16 class defaultdict(dict):
18 def __init__(self, default_factory=None, *a, **kw):
19 if (default_factory is not None and
20 not hasattr(default_factory, '__call__')):
21 raise TypeError('first argument must be callable')
22 dict.__init__(self, *a, **kw)
23 self.default_factory = default_factory
25 def __getitem__(self, key):
26 try:
27 return dict.__getitem__(self, key)
28 except KeyError:
29 return self.__missing__(key)
31 def __missing__(self, key):
32 if self.default_factory is None:
33 raise KeyError(key)
34 self[key] = value = self.default_factory()
35 return value
37 def __reduce__(self):
38 if self.default_factory is None:
39 args = ()
40 else:
41 args = self.default_factory,
42 return type(self), args, None, None, self.items()
44 def copy(self):
45 return self.__copy__()
47 def __copy__(self):
48 return type(self)(self.default_factory, self)
50 def __deepcopy__(self, memo):
51 import copy
52 return type(self)(self.default_factory,
53 copy.deepcopy(self.items()))
55 def __repr__(self):
56 return 'defaultdict({}, {})'.format(self.default_factory,
57 dict.__repr__(self))
60class _symbol(object):
62 def __init__(self, name):
63 """Construct a new named symbol."""
64 self.__name__ = self.name = name
66 def __reduce__(self):
67 return symbol, (self.name,)
69 def __repr__(self):
70 return self.name
71_symbol.__name__ = 'symbol'
74class symbol(object):
75 """A constant symbol.
77 >>> symbol('foo') is symbol('foo')
78 True
79 >>> symbol('foo')
80 foo
82 A slight refinement of the MAGICCOOKIE=object() pattern. The primary
83 advantage of symbol() is its repr(). They are also singletons.
85 Repeated calls of symbol('name') will all return the same instance.
87 """
88 symbols = {}
90 def __new__(cls, name):
91 try:
92 return cls.symbols[name]
93 except KeyError:
94 return cls.symbols.setdefault(name, _symbol(name))
97try:
98 text = (str, unicode)
99except NameError:
100 text = str
103def hashable_identity(obj):
104 if hasattr(obj, '__func__'):
105 return (id(obj.__func__), id(obj.__self__))
106 elif hasattr(obj, 'im_func'):
107 return (id(obj.im_func), id(obj.im_self))
108 elif isinstance(obj, text):
109 return obj
110 else:
111 return id(obj)
114WeakTypes = (ref, BoundMethodWeakref)
117class annotatable_weakref(ref):
118 """A weakref.ref that supports custom instance attributes."""
121def reference(object, callback=None, **annotations):
122 """Return an annotated weak ref."""
123 if callable(object):
124 weak = callable_reference(object, callback)
125 else:
126 weak = annotatable_weakref(object, callback)
127 for key, value in annotations.items():
128 setattr(weak, key, value)
129 return weak
132def callable_reference(object, callback=None):
133 """Return an annotated weak ref, supporting bound instance methods."""
134 if hasattr(object, 'im_self') and object.im_self is not None:
135 return BoundMethodWeakref(target=object, on_delete=callback)
136 elif hasattr(object, '__self__') and object.__self__ is not None:
137 return BoundMethodWeakref(target=object, on_delete=callback)
138 return annotatable_weakref(object, callback)
141class lazy_property(object):
142 """A @property that is only evaluated once."""
144 def __init__(self, deferred):
145 self._deferred = deferred
146 self.__doc__ = deferred.__doc__
148 def __get__(self, obj, cls):
149 if obj is None:
150 return self
151 value = self._deferred(obj)
152 setattr(obj, self._deferred.__name__, value)
153 return value