annotate CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/lib/python3.8/site-packages/pytz/lazy.py @ 69:33d812a61356

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