mirror of
https://github.com/psycopg/psycopg2.git
synced 2025-01-31 09:24:07 +03:00
Cache FixedOffsetTimezone instances
Avoid creating new a new FixedOffsetTimezone instance if one with the same offset and name has been created before. This will save memory when returning many rows containing "timestamp with timezone" columns, and also improves comparability.
This commit is contained in:
parent
1469a56512
commit
bca7200b3f
19
lib/tz.py
19
lib/tz.py
|
@ -38,17 +38,36 @@ class FixedOffsetTimezone(datetime.tzinfo):
|
||||||
with a small change to the `!__init__()` method to allow for pickling
|
with a small change to the `!__init__()` method to allow for pickling
|
||||||
and a default name in the form ``sHH:MM`` (``s`` is the sign.).
|
and a default name in the form ``sHH:MM`` (``s`` is the sign.).
|
||||||
|
|
||||||
|
The implementation also caches instances. During creation, if a
|
||||||
|
FixedOffsetTimezone instance has previously been created with the same
|
||||||
|
offset and name that instance will be returned. This saves memory and
|
||||||
|
improves comparability.
|
||||||
|
|
||||||
.. __: http://docs.python.org/library/datetime.html#datetime-tzinfo
|
.. __: http://docs.python.org/library/datetime.html#datetime-tzinfo
|
||||||
"""
|
"""
|
||||||
_name = None
|
_name = None
|
||||||
_offset = ZERO
|
_offset = ZERO
|
||||||
|
|
||||||
|
_cache = {}
|
||||||
|
|
||||||
def __init__(self, offset=None, name=None):
|
def __init__(self, offset=None, name=None):
|
||||||
if offset is not None:
|
if offset is not None:
|
||||||
self._offset = datetime.timedelta(minutes = offset)
|
self._offset = datetime.timedelta(minutes = offset)
|
||||||
if name is not None:
|
if name is not None:
|
||||||
self._name = name
|
self._name = name
|
||||||
|
|
||||||
|
def __new__(cls, offset=None, name=None):
|
||||||
|
"""Return a suitable instance created earlier if it exists
|
||||||
|
"""
|
||||||
|
key = (offset, name)
|
||||||
|
try:
|
||||||
|
return cls._cache[key]
|
||||||
|
except KeyError:
|
||||||
|
tz = datetime.tzinfo.__new__(cls, offset, name)
|
||||||
|
tz.__init__(offset, name)
|
||||||
|
cls._cache[key] = tz
|
||||||
|
return tz
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
offset_mins = self._offset.seconds // 60 + self._offset.days * 24 * 60
|
offset_mins = self._offset.seconds // 60 + self._offset.days * 24 * 60
|
||||||
return "psycopg2.tz.FixedOffsetTimezone(offset=%r, name=%r)" \
|
return "psycopg2.tz.FixedOffsetTimezone(offset=%r, name=%r)" \
|
||||||
|
|
|
@ -532,6 +532,13 @@ class FixedOffsetTimezoneTests(unittest.TestCase):
|
||||||
tzinfo = FixedOffsetTimezone(name="FOO")
|
tzinfo = FixedOffsetTimezone(name="FOO")
|
||||||
self.assertEqual(repr(tzinfo), "psycopg2.tz.FixedOffsetTimezone(offset=0, name='FOO')")
|
self.assertEqual(repr(tzinfo), "psycopg2.tz.FixedOffsetTimezone(offset=0, name='FOO')")
|
||||||
|
|
||||||
|
def test_instance_caching(self):
|
||||||
|
self.assert_(FixedOffsetTimezone(name="FOO") is FixedOffsetTimezone(name="FOO"))
|
||||||
|
self.assert_(FixedOffsetTimezone(7 * 60) is FixedOffsetTimezone(7 * 60))
|
||||||
|
self.assert_(FixedOffsetTimezone(-9 * 60, 'FOO') is FixedOffsetTimezone(-9 * 60, 'FOO'))
|
||||||
|
self.assert_(FixedOffsetTimezone(9 * 60) is not FixedOffsetTimezone(9 * 60, 'FOO'))
|
||||||
|
self.assert_(FixedOffsetTimezone(name='FOO') is not FixedOffsetTimezone(9 * 60, 'FOO'))
|
||||||
|
|
||||||
def test_suite():
|
def test_suite():
|
||||||
return unittest.TestLoader().loadTestsFromName(__name__)
|
return unittest.TestLoader().loadTestsFromName(__name__)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user