jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/869747 )
Change subject: [IMPR] add some tests and documentation and simplify some code ......................................................................
[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(-)
Approvals: RoySmith: Looks good to me, but someone else must approve Xqt: Looks good to me, approved jenkins-bot: Verified
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()
pywikibot-commits@lists.wikimedia.org