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

1from weakref import ref 

2 

3from blinker._saferef import BoundMethodWeakref 

4 

5 

6try: 

7 callable 

8except NameError: 

9 def callable(object): 

10 return hasattr(object, '__call__') 

11 

12 

13try: 

14 from collections import defaultdict 

15except: 

16 class defaultdict(dict): 

17 

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 

24 

25 def __getitem__(self, key): 

26 try: 

27 return dict.__getitem__(self, key) 

28 except KeyError: 

29 return self.__missing__(key) 

30 

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 

36 

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() 

43 

44 def copy(self): 

45 return self.__copy__() 

46 

47 def __copy__(self): 

48 return type(self)(self.default_factory, self) 

49 

50 def __deepcopy__(self, memo): 

51 import copy 

52 return type(self)(self.default_factory, 

53 copy.deepcopy(self.items())) 

54 

55 def __repr__(self): 

56 return 'defaultdict({}, {})'.format(self.default_factory, 

57 dict.__repr__(self)) 

58 

59 

60class _symbol(object): 

61 

62 def __init__(self, name): 

63 """Construct a new named symbol.""" 

64 self.__name__ = self.name = name 

65 

66 def __reduce__(self): 

67 return symbol, (self.name,) 

68 

69 def __repr__(self): 

70 return self.name 

71_symbol.__name__ = 'symbol' 

72 

73 

74class symbol(object): 

75 """A constant symbol. 

76 

77 >>> symbol('foo') is symbol('foo') 

78 True 

79 >>> symbol('foo') 

80 foo 

81 

82 A slight refinement of the MAGICCOOKIE=object() pattern. The primary 

83 advantage of symbol() is its repr(). They are also singletons. 

84 

85 Repeated calls of symbol('name') will all return the same instance. 

86 

87 """ 

88 symbols = {} 

89 

90 def __new__(cls, name): 

91 try: 

92 return cls.symbols[name] 

93 except KeyError: 

94 return cls.symbols.setdefault(name, _symbol(name)) 

95 

96 

97try: 

98 text = (str, unicode) 

99except NameError: 

100 text = str 

101 

102 

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) 

112 

113 

114WeakTypes = (ref, BoundMethodWeakref) 

115 

116 

117class annotatable_weakref(ref): 

118 """A weakref.ref that supports custom instance attributes.""" 

119 

120 

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 

130 

131 

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) 

139 

140 

141class lazy_property(object): 

142 """A @property that is only evaluated once.""" 

143 

144 def __init__(self, deferred): 

145 self._deferred = deferred 

146 self.__doc__ = deferred.__doc__ 

147 

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