Spaces:
Runtime error
Runtime error
from threading import RLock | |
try: | |
from collections.abc import Mapping as DictMixin | |
except ImportError: # Python < 3.3 | |
try: | |
from UserDict import DictMixin # Python 2 | |
except ImportError: # Python 3.0-3.3 | |
from collections import Mapping as DictMixin | |
# With lazy loading, we might end up with multiple threads triggering | |
# it at the same time. We need a lock. | |
_fill_lock = RLock() | |
class LazyDict(DictMixin): | |
"""Dictionary populated on first use.""" | |
data = None | |
def __getitem__(self, key): | |
if self.data is None: | |
_fill_lock.acquire() | |
try: | |
if self.data is None: | |
self._fill() | |
finally: | |
_fill_lock.release() | |
return self.data[key.upper()] | |
def __contains__(self, key): | |
if self.data is None: | |
_fill_lock.acquire() | |
try: | |
if self.data is None: | |
self._fill() | |
finally: | |
_fill_lock.release() | |
return key in self.data | |
def __iter__(self): | |
if self.data is None: | |
_fill_lock.acquire() | |
try: | |
if self.data is None: | |
self._fill() | |
finally: | |
_fill_lock.release() | |
return iter(self.data) | |
def __len__(self): | |
if self.data is None: | |
_fill_lock.acquire() | |
try: | |
if self.data is None: | |
self._fill() | |
finally: | |
_fill_lock.release() | |
return len(self.data) | |
def keys(self): | |
if self.data is None: | |
_fill_lock.acquire() | |
try: | |
if self.data is None: | |
self._fill() | |
finally: | |
_fill_lock.release() | |
return self.data.keys() | |
class LazyList(list): | |
"""List populated on first use.""" | |
_props = [ | |
'__str__', '__repr__', '__unicode__', | |
'__hash__', '__sizeof__', '__cmp__', | |
'__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', | |
'append', 'count', 'index', 'extend', 'insert', 'pop', 'remove', | |
'reverse', 'sort', '__add__', '__radd__', '__iadd__', '__mul__', | |
'__rmul__', '__imul__', '__contains__', '__len__', '__nonzero__', | |
'__getitem__', '__setitem__', '__delitem__', '__iter__', | |
'__reversed__', '__getslice__', '__setslice__', '__delslice__'] | |
def __new__(cls, fill_iter=None): | |
if fill_iter is None: | |
return list() | |
# We need a new class as we will be dynamically messing with its | |
# methods. | |
class LazyList(list): | |
pass | |
fill_iter = [fill_iter] | |
def lazy(name): | |
def _lazy(self, *args, **kw): | |
_fill_lock.acquire() | |
try: | |
if len(fill_iter) > 0: | |
list.extend(self, fill_iter.pop()) | |
for method_name in cls._props: | |
delattr(LazyList, method_name) | |
finally: | |
_fill_lock.release() | |
return getattr(list, name)(self, *args, **kw) | |
return _lazy | |
for name in cls._props: | |
setattr(LazyList, name, lazy(name)) | |
new_list = LazyList() | |
return new_list | |
# Not all versions of Python declare the same magic methods. | |
# Filter out properties that don't exist in this version of Python | |
# from the list. | |
LazyList._props = [prop for prop in LazyList._props if hasattr(list, prop)] | |
class LazySet(set): | |
"""Set populated on first use.""" | |
_props = ( | |
'__str__', '__repr__', '__unicode__', | |
'__hash__', '__sizeof__', '__cmp__', | |
'__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', | |
'__contains__', '__len__', '__nonzero__', | |
'__getitem__', '__setitem__', '__delitem__', '__iter__', | |
'__sub__', '__and__', '__xor__', '__or__', | |
'__rsub__', '__rand__', '__rxor__', '__ror__', | |
'__isub__', '__iand__', '__ixor__', '__ior__', | |
'add', 'clear', 'copy', 'difference', 'difference_update', | |
'discard', 'intersection', 'intersection_update', 'isdisjoint', | |
'issubset', 'issuperset', 'pop', 'remove', | |
'symmetric_difference', 'symmetric_difference_update', | |
'union', 'update') | |
def __new__(cls, fill_iter=None): | |
if fill_iter is None: | |
return set() | |
class LazySet(set): | |
pass | |
fill_iter = [fill_iter] | |
def lazy(name): | |
def _lazy(self, *args, **kw): | |
_fill_lock.acquire() | |
try: | |
if len(fill_iter) > 0: | |
for i in fill_iter.pop(): | |
set.add(self, i) | |
for method_name in cls._props: | |
delattr(LazySet, method_name) | |
finally: | |
_fill_lock.release() | |
return getattr(set, name)(self, *args, **kw) | |
return _lazy | |
for name in cls._props: | |
setattr(LazySet, name, lazy(name)) | |
new_set = LazySet() | |
return new_set | |
# Not all versions of Python declare the same magic methods. | |
# Filter out properties that don't exist in this version of Python | |
# from the list. | |
LazySet._props = [prop for prop in LazySet._props if hasattr(set, prop)] | |