jenkins-bot submitted this change.

View Change


Approvals: RoySmith: Looks good to me, but someone else must approve Xqt: Looks good to me, approved jenkins-bot: Verified
[IMPR] add some tests and documentation and simplify some code

path detached from 1105d0c

Change-Id: I8f481428da13b7b6fa7796c965e49d2bda24bfba
---
M tests/time_tests.py
M pywikibot/time.py
2 files changed, 78 insertions(+), 13 deletions(-)

diff --git a/pywikibot/time.py b/pywikibot/time.py
index e96a5f7..d6e7854 100644
--- a/pywikibot/time.py
+++ b/pywikibot/time.py
@@ -11,6 +11,7 @@
import math
import re
import types
+from contextlib import suppress
from typing import Type, Union

import pywikibot
@@ -118,8 +119,8 @@
m = re.match(RE_MW, timestr)

if not m:
- msg = "time data '{timestr}' does not match MW format."
- raise ValueError(msg.format(timestr=timestr))
+ raise ValueError(
+ f'time data {timestr!r} does not match MW format.')

return cls.strptime(timestr, cls.mediawikiTSFormat)

@@ -139,8 +140,8 @@
m = re.match(RE_ISO8601, timestr)

if not m:
- msg = "time data '{timestr}' does not match ISO8601 format."
- raise ValueError(msg.format(timestr=timestr))
+ raise ValueError(
+ f'time data {timestr!r} does not match ISO8601 format.')

strpfmt = '%Y-%m-%d{sep}%H:%M:%S'.format(sep=m.group('sep'))
strpstr = timestr[:19]
@@ -205,13 +206,10 @@
]

for handler in handlers:
- try:
+ with suppress(ValueError):
return handler(timestr)
- except ValueError:
- continue

- msg = "time data '{timestr}' does not match any format."
- raise ValueError(msg.format(timestr=timestr))
+ raise ValueError(f'time data {timestr!r} does not match any format.')

def clone(self) -> 'Timestamp':
"""Clone this instance."""
@@ -251,14 +249,43 @@
return cls._from_iso8601(_ts)

@classmethod
- def fromtimestampformat(cls: Type['Timestamp'], ts: Union[str, 'Timestamp']
- ) -> 'Timestamp':
- """Convert a MediaWiki internal timestamp to a Timestamp object."""
+ def fromtimestampformat(cls: Type['Timestamp'],
+ ts: Union[str, 'Timestamp'],
+ strict: bool = False) -> 'Timestamp':
+ """Convert a MediaWiki internal timestamp to a Timestamp object.
+
+ .. versionchanged:: 3.0
+ create a Timestamp if only year, month and day are given.
+ .. versionchanged:: 8.0
+ the *strict* parameter was added which discards missing
+ element tolerance.
+
+ Example
+ -------
+
+ >>> Timestamp.fromtimestampformat('20220705082234')
+ Timestamp(2022, 7, 5, 8, 22, 34)
+ >>> Timestamp.fromtimestampformat('20220927')
+ Timestamp(2022, 9, 27, 0, 0)
+ >>> Timestamp.fromtimestampformat('20221109', strict=True)
+ Traceback (most recent call last):
+ ...
+ ValueError: time data '20221109' does not match MW format.
+
+ :param ts: the timestamp to be converted
+ :param strict: If true, do not ignore missing timestamp elements
+ for hours, minutes or seconds
+ :return: return the *Timestamp* object from given *ts*.
+ :raises ValueError: The timestamp is invalid, e.g. missing or
+ invalid timestamp component.
+ """
# If inadvertently passed a Timestamp object, use replace()
# to create a clone.
if isinstance(ts, cls):
return ts.clone()
- if len(ts) == 8: # year, month and day are given only
+
+ if len(ts) == 8 and not strict:
+ # year, month and day are given only
ts += '000000'
return cls._from_mw(ts)

diff --git a/tests/time_tests.py b/tests/time_tests.py
index ff208f5..7d4f8d8 100755
--- a/tests/time_tests.py
+++ b/tests/time_tests.py
@@ -196,6 +196,33 @@
self.assertEqual(t1, t2)
self.assertEqual(ts1, ts2)

+ tests = [
+ ('202211', None),
+ ('2022112', None),
+ ('20221127', (2022, 11, 27)),
+ ('202211271', None),
+ ('2022112712', None),
+ ('20221127123', None),
+ ('202211271234', None),
+ ('2022112712345', None),
+ ('20221127123456', (2022, 11, 27, 12, 34, 56)),
+ ]
+ for mw_ts, ts in tests:
+ with self.subTest(timestamp=mw_ts):
+ if ts is None:
+ with self.assertRaisesRegex(
+ ValueError,
+ f'time data {mw_ts!r} does not match MW format'):
+ Timestamp.fromtimestampformat(mw_ts)
+ else:
+ self.assertEqual(Timestamp.fromtimestampformat(mw_ts),
+ Timestamp(*ts))
+
+ for mw_ts, ts in tests[1:-1]:
+ with self.subTest(timestamp=mw_ts), self.assertRaisesRegex(
+ ValueError, f'time data {mw_ts!r} does not match MW'):
+ Timestamp.fromtimestampformat(mw_ts, strict=True)
+
def test_add_timedelta(self):
"""Test addin a timedelta to a Timestamp."""
t1 = Timestamp.utcnow()

To view, visit change 869747. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: I8f481428da13b7b6fa7796c965e49d2bda24bfba
Gerrit-Change-Number: 869747
Gerrit-PatchSet: 2
Gerrit-Owner: Xqt <info@gno.de>
Gerrit-Reviewer: Mpaa <mpaa.wiki@gmail.com>
Gerrit-Reviewer: RoySmith <roy@panix.com>
Gerrit-Reviewer: Xqt <info@gno.de>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged