From a4d203ccdce86148415725d29bffda5659d1330f Mon Sep 17 00:00:00 2001 From: Michael Twomey Date: Tue, 15 Oct 2013 14:30:12 +0100 Subject: Correctly raise ParseError for more invalid inputs Fixes #1 Thanks to manish.tomar --- iso8601/iso8601.py | 9 ++-- iso8601/test_iso8601.py | 135 +++++++++++------------------------------------- 2 files changed, 35 insertions(+), 109 deletions(-) (limited to 'iso8601') 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 -- cgit v1.2.1