Mercurial > repos > rliterman > csp2
comparison CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/lib/python3.8/site-packages/pytz/lazy.py @ 68:5028fdace37b
planemo upload commit 2e9511a184a1ca667c7be0c6321a36dc4e3d116d
author | jpayne |
---|---|
date | Tue, 18 Mar 2025 16:23:26 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
67:0e9998148a16 | 68:5028fdace37b |
---|---|
1 from threading import RLock | |
2 try: | |
3 from collections.abc import Mapping as DictMixin | |
4 except ImportError: # Python < 3.3 | |
5 try: | |
6 from UserDict import DictMixin # Python 2 | |
7 except ImportError: # Python 3.0-3.3 | |
8 from collections import Mapping as DictMixin | |
9 | |
10 | |
11 # With lazy loading, we might end up with multiple threads triggering | |
12 # it at the same time. We need a lock. | |
13 _fill_lock = RLock() | |
14 | |
15 | |
16 class LazyDict(DictMixin): | |
17 """Dictionary populated on first use.""" | |
18 data = None | |
19 | |
20 def __getitem__(self, key): | |
21 if self.data is None: | |
22 _fill_lock.acquire() | |
23 try: | |
24 if self.data is None: | |
25 self._fill() | |
26 finally: | |
27 _fill_lock.release() | |
28 return self.data[key.upper()] | |
29 | |
30 def __contains__(self, key): | |
31 if self.data is None: | |
32 _fill_lock.acquire() | |
33 try: | |
34 if self.data is None: | |
35 self._fill() | |
36 finally: | |
37 _fill_lock.release() | |
38 return key in self.data | |
39 | |
40 def __iter__(self): | |
41 if self.data is None: | |
42 _fill_lock.acquire() | |
43 try: | |
44 if self.data is None: | |
45 self._fill() | |
46 finally: | |
47 _fill_lock.release() | |
48 return iter(self.data) | |
49 | |
50 def __len__(self): | |
51 if self.data is None: | |
52 _fill_lock.acquire() | |
53 try: | |
54 if self.data is None: | |
55 self._fill() | |
56 finally: | |
57 _fill_lock.release() | |
58 return len(self.data) | |
59 | |
60 def keys(self): | |
61 if self.data is None: | |
62 _fill_lock.acquire() | |
63 try: | |
64 if self.data is None: | |
65 self._fill() | |
66 finally: | |
67 _fill_lock.release() | |
68 return self.data.keys() | |
69 | |
70 | |
71 class LazyList(list): | |
72 """List populated on first use.""" | |
73 | |
74 _props = [ | |
75 '__str__', '__repr__', '__unicode__', | |
76 '__hash__', '__sizeof__', '__cmp__', | |
77 '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', | |
78 'append', 'count', 'index', 'extend', 'insert', 'pop', 'remove', | |
79 'reverse', 'sort', '__add__', '__radd__', '__iadd__', '__mul__', | |
80 '__rmul__', '__imul__', '__contains__', '__len__', '__nonzero__', | |
81 '__getitem__', '__setitem__', '__delitem__', '__iter__', | |
82 '__reversed__', '__getslice__', '__setslice__', '__delslice__'] | |
83 | |
84 def __new__(cls, fill_iter=None): | |
85 | |
86 if fill_iter is None: | |
87 return list() | |
88 | |
89 # We need a new class as we will be dynamically messing with its | |
90 # methods. | |
91 class LazyList(list): | |
92 pass | |
93 | |
94 fill_iter = [fill_iter] | |
95 | |
96 def lazy(name): | |
97 def _lazy(self, *args, **kw): | |
98 _fill_lock.acquire() | |
99 try: | |
100 if len(fill_iter) > 0: | |
101 list.extend(self, fill_iter.pop()) | |
102 for method_name in cls._props: | |
103 delattr(LazyList, method_name) | |
104 finally: | |
105 _fill_lock.release() | |
106 return getattr(list, name)(self, *args, **kw) | |
107 return _lazy | |
108 | |
109 for name in cls._props: | |
110 setattr(LazyList, name, lazy(name)) | |
111 | |
112 new_list = LazyList() | |
113 return new_list | |
114 | |
115 # Not all versions of Python declare the same magic methods. | |
116 # Filter out properties that don't exist in this version of Python | |
117 # from the list. | |
118 LazyList._props = [prop for prop in LazyList._props if hasattr(list, prop)] | |
119 | |
120 | |
121 class LazySet(set): | |
122 """Set populated on first use.""" | |
123 | |
124 _props = ( | |
125 '__str__', '__repr__', '__unicode__', | |
126 '__hash__', '__sizeof__', '__cmp__', | |
127 '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', | |
128 '__contains__', '__len__', '__nonzero__', | |
129 '__getitem__', '__setitem__', '__delitem__', '__iter__', | |
130 '__sub__', '__and__', '__xor__', '__or__', | |
131 '__rsub__', '__rand__', '__rxor__', '__ror__', | |
132 '__isub__', '__iand__', '__ixor__', '__ior__', | |
133 'add', 'clear', 'copy', 'difference', 'difference_update', | |
134 'discard', 'intersection', 'intersection_update', 'isdisjoint', | |
135 'issubset', 'issuperset', 'pop', 'remove', | |
136 'symmetric_difference', 'symmetric_difference_update', | |
137 'union', 'update') | |
138 | |
139 def __new__(cls, fill_iter=None): | |
140 | |
141 if fill_iter is None: | |
142 return set() | |
143 | |
144 class LazySet(set): | |
145 pass | |
146 | |
147 fill_iter = [fill_iter] | |
148 | |
149 def lazy(name): | |
150 def _lazy(self, *args, **kw): | |
151 _fill_lock.acquire() | |
152 try: | |
153 if len(fill_iter) > 0: | |
154 for i in fill_iter.pop(): | |
155 set.add(self, i) | |
156 for method_name in cls._props: | |
157 delattr(LazySet, method_name) | |
158 finally: | |
159 _fill_lock.release() | |
160 return getattr(set, name)(self, *args, **kw) | |
161 return _lazy | |
162 | |
163 for name in cls._props: | |
164 setattr(LazySet, name, lazy(name)) | |
165 | |
166 new_set = LazySet() | |
167 return new_set | |
168 | |
169 # Not all versions of Python declare the same magic methods. | |
170 # Filter out properties that don't exist in this version of Python | |
171 # from the list. | |
172 LazySet._props = [prop for prop in LazySet._props if hasattr(set, prop)] |