(tstr)
| 410 | return time_comps |
| 411 | |
| 412 | def _parse_isoformat_time(tstr): |
| 413 | # Format supported is HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]] |
| 414 | len_str = len(tstr) |
| 415 | if len_str < 2: |
| 416 | raise ValueError("Isoformat time too short") |
| 417 | |
| 418 | # This is equivalent to re.search('[+-Z]', tstr), but faster |
| 419 | tz_pos = (tstr.find('-') + 1 or tstr.find('+') + 1 or tstr.find('Z') + 1) |
| 420 | timestr = tstr[:tz_pos-1] if tz_pos > 0 else tstr |
| 421 | |
| 422 | time_comps = _parse_hh_mm_ss_ff(timestr) |
| 423 | |
| 424 | tzi = None |
| 425 | if tz_pos == len_str and tstr[-1] == 'Z': |
| 426 | tzi = timezone.utc |
| 427 | elif tz_pos > 0: |
| 428 | tzstr = tstr[tz_pos:] |
| 429 | |
| 430 | # Valid time zone strings are: |
| 431 | # HH len: 2 |
| 432 | # HHMM len: 4 |
| 433 | # HH:MM len: 5 |
| 434 | # HHMMSS len: 6 |
| 435 | # HHMMSS.f+ len: 7+ |
| 436 | # HH:MM:SS len: 8 |
| 437 | # HH:MM:SS.f+ len: 10+ |
| 438 | |
| 439 | if len(tzstr) in (0, 1, 3): |
| 440 | raise ValueError("Malformed time zone string") |
| 441 | |
| 442 | tz_comps = _parse_hh_mm_ss_ff(tzstr) |
| 443 | |
| 444 | if all(x == 0 for x in tz_comps): |
| 445 | tzi = timezone.utc |
| 446 | else: |
| 447 | tzsign = -1 if tstr[tz_pos - 1] == '-' else 1 |
| 448 | |
| 449 | td = timedelta(hours=tz_comps[0], minutes=tz_comps[1], |
| 450 | seconds=tz_comps[2], microseconds=tz_comps[3]) |
| 451 | |
| 452 | tzi = timezone(tzsign * td) |
| 453 | |
| 454 | time_comps.append(tzi) |
| 455 | |
| 456 | return time_comps |
| 457 | |
| 458 | # tuple[int, int, int] -> tuple[int, int, int] version of date.fromisocalendar |
| 459 | def _isoweek_to_gregorian(year, week, day): |
no test coverage detected