1from datetime import timedelta 2 3 4class _TzSingleton(type): 5 def __init__(cls, *args, **kwargs): 6 cls.__instance = None 7 super(_TzSingleton, cls).__init__(*args, **kwargs) 8 9 def __call__(cls): 10 if cls.__instance is None: 11 cls.__instance = super(_TzSingleton, cls).__call__() 12 return cls.__instance 13 14class _TzFactory(type): 15 def instance(cls, *args, **kwargs): 16 """Alternate constructor that returns a fresh instance""" 17 return type.__call__(cls, *args, **kwargs) 18 19 20class _TzOffsetFactory(_TzFactory): 21 def __init__(cls, *args, **kwargs): 22 cls.__instances = {} 23 24 def __call__(cls, name, offset): 25 if isinstance(offset, timedelta): 26 key = (name, offset.total_seconds()) 27 else: 28 key = (name, offset) 29 30 instance = cls.__instances.get(key, None) 31 if instance is None: 32 instance = cls.__instances.setdefault(key, 33 cls.instance(name, offset)) 34 return instance 35 36 37class _TzStrFactory(_TzFactory): 38 def __init__(cls, *args, **kwargs): 39 cls.__instances = {} 40 41 def __call__(cls, s, posix_offset=False): 42 key = (s, posix_offset) 43 instance = cls.__instances.get(key, None) 44 45 if instance is None: 46 instance = cls.__instances.setdefault(key, 47 cls.instance(s, posix_offset)) 48 return instance 49 50