dateutil / dateutil
1
# -*- coding: utf-8 -*-
2 20
from __future__ import unicode_literals
3

4 20
from datetime import datetime, timedelta, date, time
5 20
import itertools as it
6

7 20
from dateutil import tz
8 20
from dateutil.tz import UTC
9 20
from dateutil.parser import isoparser, isoparse
10

11 20
import pytest
12 20
import six
13

14

15 20
def _generate_tzoffsets(limited):
16 20
    def _mkoffset(hmtuple, fmt):
17 20
        h, m = hmtuple
18 20
        m_td = (-1 if h < 0 else 1) * m
19

20 20
        tzo = tz.tzoffset(None, timedelta(hours=h, minutes=m_td))
21 20
        return tzo, fmt.format(h, m)
22

23 20
    out = []
24 20
    if not limited:
25
        # The subset that's just hours
26 20
        hm_out_h = [(h, 0) for h in (-23, -5, 0, 5, 23)]
27 20
        out.extend([_mkoffset(hm, '{:+03d}') for hm in hm_out_h])
28

29
        # Ones that have hours and minutes
30 20
        hm_out = [] + hm_out_h
31 20
        hm_out += [(-12, 15), (11, 30), (10, 2), (5, 15), (-5, 30)]
32
    else:
33 20
        hm_out = [(-5, -0)]
34

35 20
    fmts = ['{:+03d}:{:02d}', '{:+03d}{:02d}']
36 20
    out += [_mkoffset(hm, fmt) for hm in hm_out for fmt in fmts]
37

38
    # Also add in UTC and naive
39 20
    out.append((UTC, 'Z'))
40 20
    out.append((None, ''))
41

42 20
    return out
43

44 20
FULL_TZOFFSETS = _generate_tzoffsets(False)
45 20
FULL_TZOFFSETS_AWARE = [x for x in FULL_TZOFFSETS if x[1]]
46 20
TZOFFSETS = _generate_tzoffsets(True)
47

48 20
DATES = [datetime(1996, 1, 1), datetime(2017, 1, 1)]
49 20
@pytest.mark.parametrize('dt', tuple(DATES))
50 2
def test_year_only(dt):
51 20
    dtstr = dt.strftime('%Y')
52

53 20
    assert isoparse(dtstr) == dt
54

55 20
DATES += [datetime(2000, 2, 1), datetime(2017, 4, 1)]
56 20
@pytest.mark.parametrize('dt', tuple(DATES))
57 2
def test_year_month(dt):
58 20
    fmt   = '%Y-%m'
59 20
    dtstr = dt.strftime(fmt)
60

61 20
    assert isoparse(dtstr) == dt
62

63 20
DATES += [datetime(2016, 2, 29), datetime(2018, 3, 15)]
64 20
YMD_FMTS = ('%Y%m%d', '%Y-%m-%d')
65 20
@pytest.mark.parametrize('dt', tuple(DATES))
66 20
@pytest.mark.parametrize('fmt', YMD_FMTS)
67 2
def test_year_month_day(dt, fmt):
68 20
    dtstr = dt.strftime(fmt)
69

70 20
    assert isoparse(dtstr) == dt
71

72 20
def _isoparse_date_and_time(dt, date_fmt, time_fmt, tzoffset,
73
                            microsecond_precision=None):
74 20
    tzi, offset_str = tzoffset
75 20
    fmt = date_fmt + 'T' + time_fmt
76 20
    dt = dt.replace(tzinfo=tzi)
77 20
    dtstr = dt.strftime(fmt)
78

79 20
    if microsecond_precision is not None:
80
        if not fmt.endswith('%f'):  # pragma: nocover
81
            raise ValueError('Time format has no microseconds!')
82

83 20
        if microsecond_precision != 6: 
84 20
            dtstr = dtstr[:-(6 - microsecond_precision)]
85
        elif microsecond_precision > 6: # pragma: nocover
86
            raise ValueError('Precision must be 1-6') 
87

88 20
    dtstr += offset_str
89

90 20
    assert isoparse(dtstr) == dt
91

92 20
DATETIMES = [datetime(1998, 4, 16, 12),
93
             datetime(2019, 11, 18, 23),
94
             datetime(2014, 12, 16, 4)]
95 20
@pytest.mark.parametrize('dt', tuple(DATETIMES))
96 20
@pytest.mark.parametrize('date_fmt', YMD_FMTS)
97 20
@pytest.mark.parametrize('tzoffset', TZOFFSETS)
98 2
def test_ymd_h(dt, date_fmt, tzoffset):
99 20
    _isoparse_date_and_time(dt, date_fmt, '%H', tzoffset)
100

101 20
DATETIMES = [datetime(2012, 1, 6, 9, 37)]
102 20
@pytest.mark.parametrize('dt', tuple(DATETIMES))
103 20
@pytest.mark.parametrize('date_fmt', YMD_FMTS)
104 20
@pytest.mark.parametrize('time_fmt', ('%H%M', '%H:%M'))
105 20
@pytest.mark.parametrize('tzoffset', TZOFFSETS)
106 2
def test_ymd_hm(dt, date_fmt, time_fmt, tzoffset):
107 20
    _isoparse_date_and_time(dt, date_fmt, time_fmt, tzoffset)
108

109 20
DATETIMES = [datetime(2003, 9, 2, 22, 14, 2),
110
             datetime(2003, 8, 8, 14, 9, 14),
111
             datetime(2003, 4, 7, 6, 14, 59)]
112 20
HMS_FMTS = ('%H%M%S', '%H:%M:%S')
113 20
@pytest.mark.parametrize('dt', tuple(DATETIMES))
114 20
@pytest.mark.parametrize('date_fmt', YMD_FMTS)
115 20
@pytest.mark.parametrize('time_fmt', HMS_FMTS)
116 20
@pytest.mark.parametrize('tzoffset', TZOFFSETS)
117 2
def test_ymd_hms(dt, date_fmt, time_fmt, tzoffset):
118 20
    _isoparse_date_and_time(dt, date_fmt, time_fmt, tzoffset)
119

120 20
DATETIMES = [datetime(2017, 11, 27, 6, 14, 30, 123456)]
121 20
@pytest.mark.parametrize('dt', tuple(DATETIMES))
122 20
@pytest.mark.parametrize('date_fmt', YMD_FMTS)
123 20
@pytest.mark.parametrize('time_fmt', (x + sep + '%f' for x in HMS_FMTS
124
                                      for sep in '.,'))
125 20
@pytest.mark.parametrize('tzoffset', TZOFFSETS)
126 20
@pytest.mark.parametrize('precision', list(range(3, 7)))
127 2
def test_ymd_hms_micro(dt, date_fmt, time_fmt, tzoffset, precision):
128
    # Truncate the microseconds to the desired precision for the representation
129 20
    dt = dt.replace(microsecond=int(round(dt.microsecond, precision-6)))
130

131 20
    _isoparse_date_and_time(dt, date_fmt, time_fmt, tzoffset, precision)
132

133
###
134
# Truncation of extra digits beyond microsecond precision
135 20
@pytest.mark.parametrize('dt_str', [
136
    '2018-07-03T14:07:00.123456000001',
137
    '2018-07-03T14:07:00.123456999999',
138
])
139 2
def test_extra_subsecond_digits(dt_str):
140 20
    assert isoparse(dt_str) == datetime(2018, 7, 3, 14, 7, 0, 123456)
141

142 20
@pytest.mark.parametrize('tzoffset', FULL_TZOFFSETS)
143 2
def test_full_tzoffsets(tzoffset):
144 20
    dt = datetime(2017, 11, 27, 6, 14, 30, 123456)
145 20
    date_fmt = '%Y-%m-%d'
146 20
    time_fmt = '%H:%M:%S.%f'
147

148 20
    _isoparse_date_and_time(dt, date_fmt, time_fmt, tzoffset)
149

150 20
@pytest.mark.parametrize('dt_str', [
151
    '2014-04-11T00',
152
    '2014-04-10T24',
153
    '2014-04-11T00:00',
154
    '2014-04-10T24:00',
155
    '2014-04-11T00:00:00',
156
    '2014-04-10T24:00:00',
157
    '2014-04-11T00:00:00.000',
158
    '2014-04-10T24:00:00.000',
159
    '2014-04-11T00:00:00.000000',
160
    '2014-04-10T24:00:00.000000']
161
)
162 2
def test_datetime_midnight(dt_str):
163 20
    assert isoparse(dt_str) == datetime(2014, 4, 11, 0, 0, 0, 0)
164

165 20
@pytest.mark.parametrize('datestr', [
166
    '2014-01-01',
167
    '20140101',
168
])
169 20
@pytest.mark.parametrize('sep', [' ', 'a', 'T', '_', '-'])
170 2
def test_isoparse_sep_none(datestr, sep):
171 20
    isostr = datestr + sep + '14:33:09'
172 20
    assert isoparse(isostr) == datetime(2014, 1, 1, 14, 33, 9)
173

174
##
175
# Uncommon date formats
176 20
TIME_ARGS = ('time_args',
177
    ((None, time(0), None), ) + tuple(('%H:%M:%S.%f', _t, _tz)
178
        for _t, _tz in it.product([time(0), time(9, 30), time(14, 47)],
179
                                  TZOFFSETS)))
180

181 20
@pytest.mark.parametrize('isocal,dt_expected',[
182
    ((2017, 10), datetime(2017, 3, 6)),
183
    ((2020, 1), datetime(2019, 12, 30)),    # ISO year != Cal year
184
    ((2004, 53), datetime(2004, 12, 27)),   # Only half the week is in 2014
185
])
186 2
def test_isoweek(isocal, dt_expected):
187
    # TODO: Figure out how to parametrize this on formats, too
188 20
    for fmt in ('{:04d}-W{:02d}', '{:04d}W{:02d}'):
189 20
        dtstr = fmt.format(*isocal)
190 20
        assert isoparse(dtstr) == dt_expected
191

192 20
@pytest.mark.parametrize('isocal,dt_expected',[
193
    ((2016, 13, 7), datetime(2016, 4, 3)),
194
    ((2004, 53, 7), datetime(2005, 1, 2)),      # ISO year != Cal year
195
    ((2009, 1, 2), datetime(2008, 12, 30)),     # ISO year < Cal year
196
    ((2009, 53, 6), datetime(2010, 1, 2))       # ISO year > Cal year
197
])
198 2
def test_isoweek_day(isocal, dt_expected):
199
    # TODO: Figure out how to parametrize this on formats, too
200 20
    for fmt in ('{:04d}-W{:02d}-{:d}', '{:04d}W{:02d}{:d}'):
201 20
        dtstr = fmt.format(*isocal)
202 20
        assert isoparse(dtstr) == dt_expected
203

204 20
@pytest.mark.parametrize('isoord,dt_expected', [
205
    ((2004, 1), datetime(2004, 1, 1)),
206
    ((2016, 60), datetime(2016, 2, 29)),
207
    ((2017, 60), datetime(2017, 3, 1)),
208
    ((2016, 366), datetime(2016, 12, 31)),
209
    ((2017, 365), datetime(2017, 12, 31))
210
])
211 2
def test_iso_ordinal(isoord, dt_expected):
212 20
    for fmt in ('{:04d}-{:03d}', '{:04d}{:03d}'):
213 20
        dtstr = fmt.format(*isoord)
214

215 20
        assert isoparse(dtstr) == dt_expected
216

217

218
###
219
# Acceptance of bytes
220 20
@pytest.mark.parametrize('isostr,dt', [
221
    (b'2014', datetime(2014, 1, 1)),
222
    (b'20140204', datetime(2014, 2, 4)),
223
    (b'2014-02-04', datetime(2014, 2, 4)),
224
    (b'2014-02-04T12', datetime(2014, 2, 4, 12)),
225
    (b'2014-02-04T12:30', datetime(2014, 2, 4, 12, 30)),
226
    (b'2014-02-04T12:30:15', datetime(2014, 2, 4, 12, 30, 15)),
227
    (b'2014-02-04T12:30:15.224', datetime(2014, 2, 4, 12, 30, 15, 224000)),
228
    (b'20140204T123015.224', datetime(2014, 2, 4, 12, 30, 15, 224000)),
229
    (b'2014-02-04T12:30:15.224Z', datetime(2014, 2, 4, 12, 30, 15, 224000,
230
                                           UTC)),
231
    (b'2014-02-04T12:30:15.224z', datetime(2014, 2, 4, 12, 30, 15, 224000,
232
                                           UTC)),
233
    (b'2014-02-04T12:30:15.224+05:00',
234
        datetime(2014, 2, 4, 12, 30, 15, 224000,
235
                 tzinfo=tz.tzoffset(None, timedelta(hours=5))))])
236 2
def test_bytes(isostr, dt):
237 20
    assert isoparse(isostr) == dt
238

239

240
###
241
# Invalid ISO strings
242 20
@pytest.mark.parametrize('isostr,exception', [
243
    ('201', ValueError),                        # ISO string too short
244
    ('2012-0425', ValueError),                  # Inconsistent date separators
245
    ('201204-25', ValueError),                  # Inconsistent date separators
246
    ('20120425T0120:00', ValueError),           # Inconsistent time separators
247
    ('20120425T012500-334', ValueError),        # Wrong microsecond separator
248
    ('2001-1', ValueError),                     # YYYY-M not valid
249
    ('2012-04-9', ValueError),                  # YYYY-MM-D not valid
250
    ('201204', ValueError),                     # YYYYMM not valid
251
    ('20120411T03:30+', ValueError),            # Time zone too short
252
    ('20120411T03:30+1234567', ValueError),     # Time zone too long
253
    ('20120411T03:30-25:40', ValueError),       # Time zone invalid
254
    ('2012-1a', ValueError),                    # Invalid month
255
    ('20120411T03:30+00:60', ValueError),       # Time zone invalid minutes
256
    ('20120411T03:30+00:61', ValueError),       # Time zone invalid minutes
257
    ('20120411T033030.123456012:00',            # No sign in time zone
258
        ValueError),
259
    ('2012-W00', ValueError),                   # Invalid ISO week
260
    ('2012-W55', ValueError),                   # Invalid ISO week
261
    ('2012-W01-0', ValueError),                 # Invalid ISO week day
262
    ('2012-W01-8', ValueError),                 # Invalid ISO week day
263
    ('2013-000', ValueError),                   # Invalid ordinal day
264
    ('2013-366', ValueError),                   # Invalid ordinal day
265
    ('2013366', ValueError),                    # Invalid ordinal day
266
    ('2014-03-12Π’12:30:14', ValueError),        # Cyrillic T
267
    ('2014-04-21T24:00:01', ValueError),        # Invalid use of 24 for midnight
268
    ('2014_W01-1', ValueError),                 # Invalid separator
269
    ('2014W01-1', ValueError),                  # Inconsistent use of dashes
270
    ('2014-W011', ValueError),                  # Inconsistent use of dashes
271

272
])
273 2
def test_iso_raises(isostr, exception):
274 20
    with pytest.raises(exception):
275 20
        isoparse(isostr)
276

277

278 20
@pytest.mark.parametrize('sep_act, valid_sep, exception', [
279
    ('T', 'C', ValueError),
280
    ('C', 'T', ValueError),
281
])
282 2
def test_iso_with_sep_raises(sep_act, valid_sep, exception):
283 20
    parser = isoparser(sep=valid_sep)
284 20
    isostr = '2012-04-25' + sep_act + '01:25:00'
285 20
    with pytest.raises(exception):
286 20
        parser.isoparse(isostr)
287

288

289 20
@pytest.mark.xfail() 
290
@pytest.mark.parametrize('isostr,exception', [  # pragma: nocover
291
    ('20120425T01:2000', ValueError),           # Inconsistent time separators
292
])
293
def test_iso_raises_failing(isostr, exception):
294
    # These are test cases where the current implementation is too lenient
295
    # and need to be fixed
296
    with pytest.raises(exception):
297
        isoparse(isostr)
298

299

300
###
301
# Test ISOParser constructor
302 20
@pytest.mark.parametrize('sep', ['  ', '9', 'πŸ›'])
303 2
def test_isoparser_invalid_sep(sep):
304 20
    with pytest.raises(ValueError):
305 20
        isoparser(sep=sep)
306

307

308
# This only fails on Python 3
309 20
@pytest.mark.xfail(not six.PY2, reason="Fails on Python 3 only")
310 2
def test_isoparser_byte_sep():
311 6
    dt = datetime(2017, 12, 6, 12, 30, 45)
312 6
    dt_str = dt.isoformat(sep=str('T'))
313

314 6
    dt_rt = isoparser(sep=b'T').isoparse(dt_str)
315

316 6
    assert dt == dt_rt
317

318

319
###
320
# Test parse_tzstr
321 20
@pytest.mark.parametrize('tzoffset', FULL_TZOFFSETS)
322 2
def test_parse_tzstr(tzoffset):
323 20
    dt = datetime(2017, 11, 27, 6, 14, 30, 123456)
324 20
    date_fmt = '%Y-%m-%d'
325 20
    time_fmt = '%H:%M:%S.%f'
326

327 20
    _isoparse_date_and_time(dt, date_fmt, time_fmt, tzoffset)
328

329

330 20
@pytest.mark.parametrize('tzstr', [
331
    '-00:00', '+00:00', '+00', '-00', '+0000', '-0000'
332
])
333 20
@pytest.mark.parametrize('zero_as_utc', [True, False])
334 2
def test_parse_tzstr_zero_as_utc(tzstr, zero_as_utc):
335 20
    tzi = isoparser().parse_tzstr(tzstr, zero_as_utc=zero_as_utc)
336 20
    assert tzi == UTC
337 20
    assert (type(tzi) == tz.tzutc) == zero_as_utc
338

339

340 20
@pytest.mark.parametrize('tzstr,exception', [
341
    ('00:00', ValueError),     # No sign
342
    ('05:00', ValueError),     # No sign
343
    ('_00:00', ValueError),    # Invalid sign
344
    ('+25:00', ValueError),    # Offset too large
345
    ('00:0000', ValueError),   # String too long
346
])
347 2
def test_parse_tzstr_fails(tzstr, exception):
348 20
    with pytest.raises(exception):
349 20
        isoparser().parse_tzstr(tzstr)
350

351
###
352
# Test parse_isodate
353 20
def __make_date_examples():
354 20
    dates_no_day = [
355
        date(1999, 12, 1),
356
        date(2016, 2, 1)
357
    ]
358

359 20
    if not six.PY2:
360
        # strftime does not support dates before 1900 in Python 2
361 14
        dates_no_day.append(date(1000, 11, 1))
362

363
    # Only one supported format for dates with no day
364 20
    o = zip(dates_no_day, it.repeat('%Y-%m'))
365

366 20
    dates_w_day = [
367
        date(1969, 12, 31),
368
        date(1900, 1, 1),
369
        date(2016, 2, 29),
370
        date(2017, 11, 14)
371
    ]
372

373 20
    dates_w_day_fmts = ('%Y%m%d', '%Y-%m-%d')
374 20
    o = it.chain(o, it.product(dates_w_day, dates_w_day_fmts))
375

376 20
    return list(o)
377

378

379 20
@pytest.mark.parametrize('d,dt_fmt', __make_date_examples())
380 20
@pytest.mark.parametrize('as_bytes', [True, False])
381 2
def test_parse_isodate(d, dt_fmt, as_bytes):
382 20
    d_str = d.strftime(dt_fmt)
383 20
    if isinstance(d_str, six.text_type) and as_bytes:
384 14
        d_str = d_str.encode('ascii')
385 20
    elif isinstance(d_str, bytes) and not as_bytes:
386 6
        d_str = d_str.decode('ascii')
387

388 20
    iparser = isoparser()
389 20
    assert iparser.parse_isodate(d_str) == d
390

391

392 20
@pytest.mark.parametrize('isostr,exception', [
393
    ('243', ValueError),                        # ISO string too short
394
    ('2014-0423', ValueError),                  # Inconsistent date separators
395
    ('201404-23', ValueError),                  # Inconsistent date separators
396
    ('2014ζ—₯03月14', ValueError),                # Not ASCII
397
    ('2013-02-29', ValueError),                 # Not a leap year
398
    ('2014/12/03', ValueError),                 # Wrong separators
399
    ('2014-04-19T', ValueError),                # Unknown components
400
])
401 2
def test_isodate_raises(isostr, exception):
402 20
    with pytest.raises(exception):
403 20
        isoparser().parse_isodate(isostr)
404

405

406
###
407
# Test parse_isotime
408 20
def __make_time_examples():
409 20
    outputs = []
410

411
    # HH
412 20
    time_h = [time(0), time(8), time(22)]
413 20
    time_h_fmts = ['%H']
414

415 20
    outputs.append(it.product(time_h, time_h_fmts))
416

417
    # HHMM / HH:MM
418 20
    time_hm = [time(0, 0), time(0, 30), time(8, 47), time(16, 1)]
419 20
    time_hm_fmts = ['%H%M', '%H:%M']
420

421 20
    outputs.append(it.product(time_hm, time_hm_fmts))
422

423
    # HHMMSS / HH:MM:SS
424 20
    time_hms = [time(0, 0, 0), time(0, 15, 30),
425
                time(8, 2, 16), time(12, 0), time(16, 2), time(20, 45)]
426

427 20
    time_hms_fmts = ['%H%M%S', '%H:%M:%S']
428

429 20
    outputs.append(it.product(time_hms, time_hms_fmts))
430

431
    # HHMMSS.ffffff / HH:MM:SS.ffffff
432 20
    time_hmsu = [time(0, 0, 0, 0), time(4, 15, 3, 247993),
433
                 time(14, 21, 59, 948730),
434
                 time(23, 59, 59, 999999)]
435

436 20
    time_hmsu_fmts = ['%H%M%S.%f', '%H:%M:%S.%f']
437

438 20
    outputs.append(it.product(time_hmsu, time_hmsu_fmts))
439

440 20
    outputs = list(map(list, outputs))
441

442
    # Time zones
443 20
    ex_naive = list(it.chain.from_iterable(x[0:2] for x in outputs))
444 20
    o = it.product(ex_naive, TZOFFSETS)    # ((time, fmt), (tzinfo, offsetstr))
445 20
    o = ((t.replace(tzinfo=tzi), fmt + off_str)
446
         for (t, fmt), (tzi, off_str) in o)
447

448 20
    outputs.append(o)
449

450 20
    return list(it.chain.from_iterable(outputs))
451

452

453 20
@pytest.mark.parametrize('time_val,time_fmt', __make_time_examples())
454 20
@pytest.mark.parametrize('as_bytes', [True, False])
455 2
def test_isotime(time_val, time_fmt, as_bytes):
456 20
    tstr = time_val.strftime(time_fmt)
457 20
    if isinstance(tstr, six.text_type) and as_bytes:
458 14
        tstr = tstr.encode('ascii')
459 20
    elif isinstance(tstr, bytes) and not as_bytes:
460 6
        tstr = tstr.decode('ascii')
461

462 20
    iparser = isoparser()
463

464 20
    assert iparser.parse_isotime(tstr) == time_val
465

466

467 20
@pytest.mark.parametrize('isostr', [
468
    '24:00',
469
    '2400',
470
    '24:00:00',
471
    '240000',
472
    '24:00:00.000',
473
    '24:00:00,000',
474
    '24:00:00.000000',
475
    '24:00:00,000000',
476
])
477 2
def test_isotime_midnight(isostr):
478 20
    iparser = isoparser()
479 20
    assert iparser.parse_isotime(isostr) == time(0, 0, 0, 0)
480

481

482 20
@pytest.mark.parametrize('isostr,exception', [
483
    ('3', ValueError),                          # ISO string too short
484
    ('14ζ™‚30εˆ†15η§’', ValueError),                # Not ASCII
485
    ('14_30_15', ValueError),                   # Invalid separators
486
    ('1430:15', ValueError),                    # Inconsistent separator use
487
    ('25', ValueError),                         # Invalid hours
488
    ('25:15', ValueError),                      # Invalid hours
489
    ('14:60', ValueError),                      # Invalid minutes
490
    ('14:59:61', ValueError),                   # Invalid seconds
491
    ('14:30:15.34468305:00', ValueError),       # No sign in time zone
492
    ('14:30:15+', ValueError),                  # Time zone too short
493
    ('14:30:15+1234567', ValueError),           # Time zone invalid
494
    ('14:59:59+25:00', ValueError),             # Invalid tz hours
495
    ('14:59:59+12:62', ValueError),             # Invalid tz minutes
496
    ('14:59:30_344583', ValueError),            # Invalid microsecond separator
497
    ('24:01', ValueError),                      # 24 used for non-midnight time
498
    ('24:00:01', ValueError),                   # 24 used for non-midnight time
499
    ('24:00:00.001', ValueError),               # 24 used for non-midnight time
500
    ('24:00:00.000001', ValueError),            # 24 used for non-midnight time
501
])
502 2
def test_isotime_raises(isostr, exception):
503 20
    iparser = isoparser()
504 20
    with pytest.raises(exception):
505 20
        iparser.parse_isotime(isostr)
506

507

508 20
@pytest.mark.xfail() 
509
@pytest.mark.parametrize('isostr,exception', [  # pragma: nocover
510
    ('14:3015', ValueError),                    # Inconsistent separator use
511
    ('201202', ValueError)                      # Invalid ISO format
512
])
513
def test_isotime_raises_xfail(isostr, exception):
514
    iparser = isoparser()
515
    with pytest.raises(exception):
516
        iparser.parse_isotime(isostr)

Read our documentation on viewing source code .

Loading