Skip to content

Commit 26f15a4

Browse files
author
Daniel da Silva
committed
Make netcdftime.datetime immutable and hashable. Fixes Unidata#255.
1 parent 96c074b commit 26f15a4

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

netcdftime.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
)
2020
TIMEZONE_REGEX = re.compile("(?P<prefix>[+-])(?P<hours>[0-9]{1,2}):(?P<minutes>[0-9]{1,2})")
2121

22-
class datetime:
22+
class datetime(object):
2323
"""
2424
Phony datetime object which mimics the python datetime object,
2525
but allows for dates that don't exist in the proleptic gregorian calendar.
@@ -44,6 +44,8 @@ def __init__(self,year,month,day,hour=0,minute=0,second=0,dayofwk=-1,dayofyr=1):
4444
self.dayofyr=dayofyr
4545
self.second=second
4646
self.format='%Y-%m-%d %H:%M:%S'
47+
self._immutable = True
48+
4749
def strftime(self,format=None):
4850
if format is None:
4951
format = self.format
@@ -53,6 +55,15 @@ def timetuple(self):
5355
def __repr__(self):
5456
return self.strftime(self.format)
5557

58+
def __hash__(self):
59+
return hash(self.timetuple())
60+
61+
def __setattr__(self, name, value):
62+
if hasattr(self, '_immutable'):
63+
raise AttributeError("attempt to change immutable instance")
64+
else:
65+
object.__setattr__(self, name, value)
66+
5667
def _compare(self, comparison_op, other):
5768
if hasattr(other, 'strftime'):
5869
return comparison_op(self.strftime('%Y-%m-%d %H:%M:%S'),
@@ -78,6 +89,7 @@ def __ge__(self, other):
7889
return self._compare(operator.ge, other)
7990

8091

92+
8193
def JulianDayFromDate(date,calendar='standard'):
8294

8395
"""

test/tst_netcdftime.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,17 @@ def runTest(self):
198198
assert d2 > d1
199199
assert d2 >= d1
200200

201+
# check datetime hash
202+
assert hash(d1) == hash(d1)
203+
assert hash(d1) != hash(d3)
204+
205+
# check datetime immutability
206+
try:
207+
d1.year = 1999
208+
self.fail("datetime is mutable")
209+
except AttributeError:
210+
pass
211+
201212

202213
class TestDate2index(unittest.TestCase):
203214

@@ -370,5 +381,6 @@ def test_select_nc(self):
370381
assert_equal(date.replace(tzinfo=tzutc()), date2)
371382
f.close()
372383

384+
373385
if __name__ == '__main__':
374386
unittest.main()

0 commit comments

Comments
 (0)