jenkins-bot has submitted this change and it was merged.
Change subject: Permissive Timestamp fromX methods
......................................................................
Permissive Timestamp fromX methods
Several methods of site and page classes return a Timestamp where
previously they returned a string which should be passed to the
Timestamp class to create a Timestamp object.
In order to improve compatibility with old versions of pywikibot,
Timestamp should recognise it is being passed a Timestamp, and not
try to parse it.
Change-Id: Ifb850b3e52c0fb1b84f2da433f50cb142f854591
---
M pywikibot/__init__.py
A tests/timestamp_tests.py
2 files changed, 107 insertions(+), 2 deletions(-)
Approvals:
John Vandenberg: Looks good to me, approved
XZise: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/__init__.py b/pywikibot/__init__.py
index e20d7c4..d60e45e 100644
--- a/pywikibot/__init__.py
+++ b/pywikibot/__init__.py
@@ -112,6 +112,10 @@
Use Timestamp.fromISOformat() and Timestamp.fromtimestampformat() to
create Timestamp objects from MediaWiki string formats.
+ As these constructors are typically used to create objects using data
+ passed provided by site and page methods, some of which return a Timestamp
+ when previously they returned a MediaWiki string representation, these
+ methods also accept a Timestamp object, in which case they return a clone.
Use Site.getcurrenttime() for the current time; this is more reliable
than using Timestamp.utcnow().
@@ -124,11 +128,19 @@
@classmethod
def fromISOformat(cls, ts):
"""Convert an ISO 8601 timestamp to a Timestamp object."""
+ # If inadvertantly passed a Timestamp object, use replace()
+ # to create a clone.
+ if isinstance(ts, cls):
+ return ts.replace(microsecond=ts.microsecond)
return cls.strptime(ts, cls.ISO8601Format)
@classmethod
def fromtimestampformat(cls, ts):
"""Convert a MediaWiki internal timestamp to a Timestamp object."""
+ # If inadvertantly passed a Timestamp object, use replace()
+ # to create a clone.
+ if isinstance(ts, cls):
+ return ts.replace(microsecond=ts.microsecond)
return cls.strptime(ts, cls.mediawikiTSFormat)
def toISOformat(self):
@@ -144,7 +156,8 @@
return self.toISOformat()
def __add__(self, other):
- newdt = datetime.datetime.__add__(self, other)
+ """Perform addition, returning a Timestamp instead of datetime."""
+ newdt = super(Timestamp, self).__add__(other)
if isinstance(newdt, datetime.datetime):
return Timestamp(newdt.year, newdt.month, newdt.day, newdt.hour,
newdt.minute, newdt.second, newdt.microsecond,
@@ -153,7 +166,8 @@
return newdt
def __sub__(self, other):
- newdt = datetime.datetime.__sub__(self, other)
+ """Perform substraction, returning a Timestamp instead of datetime."""
+ newdt = super(Timestamp, self).__sub__(other)
if isinstance(newdt, datetime.datetime):
return Timestamp(newdt.year, newdt.month, newdt.day, newdt.hour,
newdt.minute, newdt.second, newdt.microsecond,
diff --git a/tests/timestamp_tests.py b/tests/timestamp_tests.py
new file mode 100644
index 0000000..c3e0c2b
--- /dev/null
+++ b/tests/timestamp_tests.py
@@ -0,0 +1,91 @@
+# -*- coding: utf-8 -*-
+"""Tests for the Timestamp class."""
+#
+# (C) Pywikibot team, 2014
+#
+# Distributed under the terms of the MIT license.
+#
+__version__ = '$Id$'
+
+import datetime
+
+from pywikibot import Timestamp as T
+
+from tests.aspects import unittest, TestCase
+
+
+class TestTimestamp(TestCase):
+
+ """Test Timestamp class comparisons."""
+
+ net = False
+
+ def test_instantiate_from_instance(self):
+ """Test passing instance to factory methods works."""
+ t1 = T.utcnow()
+ self.assertIsNot(t1, T.fromISOformat(t1))
+ self.assertEqual(t1, T.fromISOformat(t1))
+ self.assertIsInstance(T.fromISOformat(t1), T)
+ self.assertIsNot(t1, T.fromtimestampformat(t1))
+ self.assertEqual(t1, T.fromtimestampformat(t1))
+ self.assertIsInstance(T.fromtimestampformat(t1), T)
+
+ def test_iso_format(self):
+ t1 = T.utcnow()
+ ts1 = t1.toISOformat()
+ t2 = T.fromISOformat(ts1)
+ ts2 = t2.toISOformat()
+ # MediaWiki ISO format doesn't include microseconds
+ self.assertNotEqual(t1, t2)
+ t1 = t1.replace(microsecond=0)
+ self.assertEqual(t1, t2)
+ self.assertEqual(ts1, ts2)
+
+ def test_mediawiki_format(self):
+ t1 = T.utcnow()
+ ts1 = t1.totimestampformat()
+ t2 = T.fromtimestampformat(ts1)
+ ts2 = t2.totimestampformat()
+ # MediaWiki timestamp format doesn't include microseconds
+ self.assertNotEqual(t1, t2)
+ t1 = t1.replace(microsecond=0)
+ self.assertEqual(t1, t2)
+ self.assertEqual(ts1, ts2)
+
+ def test_add_timedelta(self):
+ t1 = T.utcnow()
+ t2 = t1 + datetime.timedelta(days=1)
+ self.assertEqual(t1.day + 1, t2.day)
+ self.assertIsInstance(t2, T)
+
+ def test_add_timedate(self):
+ """Test unsupported additions raise NotImplemented."""
+ t1 = datetime.datetime.utcnow()
+ t2 = t1 + datetime.timedelta(days=1)
+ t3 = t1.__add__(t2)
+ self.assertIs(t3, NotImplemented)
+
+ # Now check that the pywikibot sub-class behaves the same way
+ t1 = T.utcnow()
+ t2 = t1 + datetime.timedelta(days=1)
+ t3 = t1.__add__(t2)
+ self.assertIs(t3, NotImplemented)
+
+ def test_sub_timedelta(self):
+ t1 = T.utcnow()
+ t2 = t1 - datetime.timedelta(days=1)
+ self.assertEqual(t1.day - 1, t2.day)
+ self.assertIsInstance(t2, T)
+
+ def test_sub_timedate(self):
+ t1 = T.utcnow()
+ t2 = t1 - datetime.timedelta(days=1)
+ td = t1 - t2
+ self.assertIsInstance(td, datetime.timedelta)
+ self.assertEqual(t2 + td, t1)
+
+if __name__ == '__main__':
+ try:
+ unittest.main()
+ except SystemExit:
+ pass
--
To view, visit https://gerrit.wikimedia.org/r/175404
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Ifb850b3e52c0fb1b84f2da433f50cb142f854591
Gerrit-PatchSet: 3
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: John Vandenberg <[email protected]>
Gerrit-Reviewer: John Vandenberg <[email protected]>
Gerrit-Reviewer: Ladsgroup <[email protected]>
Gerrit-Reviewer: Merlijn van Deen <[email protected]>
Gerrit-Reviewer: XZise <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
Pywikibot-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/pywikibot-commits