Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

74 wiersze
2.2KB

  1. from datetime import timedelta
  2. import weakref
  3. from collections import OrderedDict
  4. class _TzSingleton(type):
  5. def __init__(cls, *args, **kwargs):
  6. cls.__instance = None
  7. super(_TzSingleton, cls).__init__(*args, **kwargs)
  8. def __call__(cls):
  9. if cls.__instance is None:
  10. cls.__instance = super(_TzSingleton, cls).__call__()
  11. return cls.__instance
  12. class _TzFactory(type):
  13. def instance(cls, *args, **kwargs):
  14. """Alternate constructor that returns a fresh instance"""
  15. return type.__call__(cls, *args, **kwargs)
  16. class _TzOffsetFactory(_TzFactory):
  17. def __init__(cls, *args, **kwargs):
  18. cls.__instances = weakref.WeakValueDictionary()
  19. cls.__strong_cache = OrderedDict()
  20. cls.__strong_cache_size = 8
  21. def __call__(cls, name, offset):
  22. if isinstance(offset, timedelta):
  23. key = (name, offset.total_seconds())
  24. else:
  25. key = (name, offset)
  26. instance = cls.__instances.get(key, None)
  27. if instance is None:
  28. instance = cls.__instances.setdefault(key,
  29. cls.instance(name, offset))
  30. cls.__strong_cache[key] = cls.__strong_cache.pop(key, instance)
  31. # Remove an item if the strong cache is overpopulated
  32. # TODO: Maybe this should be under a lock?
  33. if len(cls.__strong_cache) > cls.__strong_cache_size:
  34. cls.__strong_cache.popitem(last=False)
  35. return instance
  36. class _TzStrFactory(_TzFactory):
  37. def __init__(cls, *args, **kwargs):
  38. cls.__instances = weakref.WeakValueDictionary()
  39. cls.__strong_cache = OrderedDict()
  40. cls.__strong_cache_size = 8
  41. def __call__(cls, s, posix_offset=False):
  42. key = (s, posix_offset)
  43. instance = cls.__instances.get(key, None)
  44. if instance is None:
  45. instance = cls.__instances.setdefault(key,
  46. cls.instance(s, posix_offset))
  47. cls.__strong_cache[key] = cls.__strong_cache.pop(key, instance)
  48. # Remove an item if the strong cache is overpopulated
  49. # TODO: Maybe this should be under a lock?
  50. if len(cls.__strong_cache) > cls.__strong_cache_size:
  51. cls.__strong_cache.popitem(last=False)
  52. return instance