diff options
author | Michael Twomey <mick@twomeylee.name> | 2013-10-15 14:30:12 +0100 |
---|---|---|
committer | Michael Twomey <mick@twomeylee.name> | 2013-10-15 14:30:12 +0100 |
commit | a4d203ccdce86148415725d29bffda5659d1330f (patch) | |
tree | 9f8d39766ff01d64bae0807f0385df6727387eaa | |
parent | 0912257149c969fae013f4e24c531de5ce8d14e0 (diff) | |
download | pyiso8601-a4d203ccdce86148415725d29bffda5659d1330f.tar.gz |
Correctly raise ParseError for more invalid inputs
Fixes #1
Thanks to manish.tomar
-rw-r--r-- | iso8601/iso8601.py | 9 | ||||
-rw-r--r-- | iso8601/test_iso8601.py | 135 | ||||
-rw-r--r-- | setup.py | 4 |
3 files changed, 38 insertions, 110 deletions
diff --git a/iso8601/iso8601.py b/iso8601/iso8601.py index c852062..eee6741 100644 --- a/iso8601/iso8601.py +++ b/iso8601/iso8601.py @@ -106,6 +106,9 @@ def parse_date(datestring, default_timezone=UTC): groups["fraction"] = int(float("0.%s" % groups["fraction"]) * 1e6) if groups["second"] is None: groups["second"] = 0 - return datetime(int(groups["year"]), int(groups["month"]), int(groups["day"]), - int(groups["hour"]), int(groups["minute"]), int(groups["second"]), - int(groups["fraction"]), tz) + try: + return datetime(int(groups["year"]), int(groups["month"]), int(groups["day"]), + int(groups["hour"]), int(groups["minute"]), int(groups["second"]), + int(groups["fraction"]), tz) + except Exception as e: + raise ParseError(e) diff --git a/iso8601/test_iso8601.py b/iso8601/test_iso8601.py index caa6b4c..5e1aa7f 100644 --- a/iso8601/test_iso8601.py +++ b/iso8601/test_iso8601.py @@ -1,5 +1,9 @@ from __future__ import absolute_import +import datetime + +import pytest + from iso8601 import iso8601 def test_iso8601_regex(): @@ -11,114 +15,33 @@ def test_timezone_regex(): assert iso8601.TIMEZONE_REGEX.match("+01:20") assert iso8601.TIMEZONE_REGEX.match("-01:00") -def test_parse_date(): - d = iso8601.parse_date("2006-10-20T15:34:56Z") - assert d.year == 2006 - assert d.month == 10 - assert d.day == 20 - assert d.hour == 15 - assert d.minute == 34 - assert d.second == 56 - assert d.tzinfo == iso8601.UTC - -def test_parse_date_fraction(): - d = iso8601.parse_date("2006-10-20T15:34:56.123Z") - assert d.year == 2006 - assert d.month == 10 - assert d.day == 20 - assert d.hour == 15 - assert d.minute == 34 - assert d.second == 56 - assert d.microsecond == 123000 - assert d.tzinfo == iso8601.UTC - -def test_parse_date_fraction_2(): - """From bug 6 - - """ - d = iso8601.parse_date("2007-5-7T11:43:55.328Z'") - assert d.year == 2007 - assert d.month == 5 - assert d.day == 7 - assert d.hour == 11 - assert d.minute == 43 - assert d.second == 55 - assert d.microsecond == 328000 - assert d.tzinfo == iso8601.UTC - -def test_parse_date_tz(): - d = iso8601.parse_date("2006-10-20T15:34:56.123+02:30") - assert d.year == 2006 - assert d.month == 10 - assert d.day == 20 - assert d.hour == 15 - assert d.minute == 34 - assert d.second == 56 - assert d.microsecond == 123000 - assert d.tzinfo.tzname(None) == "+02:30" - offset = d.tzinfo.utcoffset(None) - assert offset.days == 0 - assert offset.seconds == 60 * 60 * 2.5 - -def test_parse_invalid_date(): - try: - iso8601.parse_date(None) - except iso8601.ParseError: - pass - else: - assert 1 == 2 - -def test_parse_invalid_date2(): - try: - iso8601.parse_date("23") - except iso8601.ParseError: - pass - else: - assert 1 == 2 - -def test_parse_no_timezone(): - """issue 4 - Handle datetime string without timezone - - This tests what happens when you parse a date with no timezone. While not - strictly correct this is quite common. I'll assume UTC for the time zone - in this case. - """ - d = iso8601.parse_date("2007-01-01T08:00:00") - assert d.year == 2007 - assert d.month == 1 - assert d.day == 1 - assert d.hour == 8 - assert d.minute == 0 - assert d.second == 0 - assert d.microsecond == 0 - assert d.tzinfo == iso8601.UTC - -def test_parse_no_seconds(): - d = iso8601.parse_date("1997-07-16T19:20+01:00") - assert d.year == 1997 - assert d.month == 7 - assert d.day == 16 - assert d.hour == 19 - assert d.minute == 20 - assert d.second == 0 - assert d.microsecond == 0 - assert d.tzinfo.tzname(None) == "+01:00" - def test_parse_no_timezone_different_default(): tz = iso8601.FixedOffset(2, 0, "test offset") d = iso8601.parse_date("2007-01-01T08:00:00", default_timezone=tz) assert d.tzinfo == tz -def test_space_separator(): - """Handle a separator other than T - - """ - d = iso8601.parse_date("2007-06-23 06:40:34.00Z") - assert d.year == 2007 - assert d.month == 6 - assert d.day == 23 - assert d.hour == 6 - assert d.minute == 40 - assert d.second == 34 - assert d.microsecond == 0 - assert d.tzinfo == iso8601.UTC +@pytest.mark.parametrize("invalid_date", [ + ("2013-10-",), + ("2013-",), + ("",), + (None,), + ("23",), +]) + +def test_parse_invalid_date(invalid_date): + with pytest.raises(iso8601.ParseError) as exc: + iso8601.parse_date(invalid_date) + assert exc.errisinstance(iso8601.ParseError) + +@pytest.mark.parametrize("valid_date,expected_datetime", [ + ("2007-06-23 06:40:34.00Z", datetime.datetime(2007, 6, 23, 6, 40, 34, 0, iso8601.UTC)), # Handle a separator other than T + ("1997-07-16T19:20+01:00", datetime.datetime(1997, 7, 16, 19, 20, 0, 0, iso8601.FixedOffset(1, 0, "+01:00"))), # Parse with no seconds + ("2007-01-01T08:00:00", datetime.datetime(2007, 1, 1, 8, 0, 0, 0, iso8601.UTC)), # Handle timezone-less dates. Assumes UTC. http://code.google.com/p/pyiso8601/issues/detail?id=4 + ("2006-10-20T15:34:56.123+02:30", datetime.datetime(2006, 10, 20, 15, 34, 56, 123000, iso8601.FixedOffset(2, 30, "+02:30"))), + ("2006-10-20T15:34:56Z", datetime.datetime(2006, 10, 20, 15, 34, 56, 0, iso8601.UTC)), + ("2007-5-7T11:43:55.328Z'", datetime.datetime(2007, 5, 7, 11, 43, 55, 328000, iso8601.UTC)), # http://code.google.com/p/pyiso8601/issues/detail?id=6 + ("2006-10-20T15:34:56.123Z", datetime.datetime(2006, 10, 20, 15, 34, 56, 123000, iso8601.UTC)), +]) + +def test_parse_valid_date(valid_date, expected_datetime): + assert iso8601.parse_date(valid_date) == expected_datetime @@ -21,8 +21,10 @@ Changes * Wow, it's alive! First update since 2007 * Moved over to https://bitbucket.org/micktwomey/pyiso8601 -* Applied patch from https://code.google.com/p/pyiso8601/issues/detail?id=23 (thanks to zefciu), add support for python 3 +* Add support for python 3. https://code.google.com/p/pyiso8601/issues/detail?id=23 (thanks to zefciu) * Switched to py.test and tox for testing +* Make seconds optional in date format ("1997-07-16T19:20+01:00" now valid). https://bitbucket.org/micktwomey/pyiso8601/pull-request/1/make-the-inclusion-of-seconds-optional-in/diff (thanks to Chris Down) +* Correctly raise ParseError for more invalid inputs (https://bitbucket.org/micktwomey/pyiso8601/issue/1/raise-parseerror-for-invalid-input) (thanks to manish.tomar) 0.1.4 ----- |