mirror of
https://github.com/morpheus65535/bazarr
synced 2024-12-27 18:17:46 +00:00
a7fba2ee1b
As Brazil does not have Daylight Saving Time anymore as decided by it's government, pytz needed to be updated to have the new data about the country timezones. And as some in pytz calls in bazarr used tzlocal functions, that one needed also to be updated. Works fine now, tested on Brazil - Timezone America/Sao_Paulo This commit fixes #641
172 lines
5.3 KiB
Python
172 lines
5.3 KiB
Python
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)]
|