xref: /aosp_15_r20/prebuilts/build-tools/common/py3-stdlib/tomllib/_re.py (revision cda5da8d549138a6648c5ee6d7a49cf8f4a657be)
1*cda5da8dSAndroid Build Coastguard Worker# SPDX-License-Identifier: MIT
2*cda5da8dSAndroid Build Coastguard Worker# SPDX-FileCopyrightText: 2021 Taneli Hukkinen
3*cda5da8dSAndroid Build Coastguard Worker# Licensed to PSF under a Contributor Agreement.
4*cda5da8dSAndroid Build Coastguard Worker
5*cda5da8dSAndroid Build Coastguard Workerfrom __future__ import annotations
6*cda5da8dSAndroid Build Coastguard Worker
7*cda5da8dSAndroid Build Coastguard Workerfrom datetime import date, datetime, time, timedelta, timezone, tzinfo
8*cda5da8dSAndroid Build Coastguard Workerfrom functools import lru_cache
9*cda5da8dSAndroid Build Coastguard Workerimport re
10*cda5da8dSAndroid Build Coastguard Workerfrom typing import Any
11*cda5da8dSAndroid Build Coastguard Worker
12*cda5da8dSAndroid Build Coastguard Workerfrom ._types import ParseFloat
13*cda5da8dSAndroid Build Coastguard Worker
14*cda5da8dSAndroid Build Coastguard Worker# E.g.
15*cda5da8dSAndroid Build Coastguard Worker# - 00:32:00.999999
16*cda5da8dSAndroid Build Coastguard Worker# - 00:32:00
17*cda5da8dSAndroid Build Coastguard Worker_TIME_RE_STR = r"([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])(?:\.([0-9]{1,6})[0-9]*)?"
18*cda5da8dSAndroid Build Coastguard Worker
19*cda5da8dSAndroid Build Coastguard WorkerRE_NUMBER = re.compile(
20*cda5da8dSAndroid Build Coastguard Worker    r"""
21*cda5da8dSAndroid Build Coastguard Worker0
22*cda5da8dSAndroid Build Coastguard Worker(?:
23*cda5da8dSAndroid Build Coastguard Worker    x[0-9A-Fa-f](?:_?[0-9A-Fa-f])*   # hex
24*cda5da8dSAndroid Build Coastguard Worker    |
25*cda5da8dSAndroid Build Coastguard Worker    b[01](?:_?[01])*                 # bin
26*cda5da8dSAndroid Build Coastguard Worker    |
27*cda5da8dSAndroid Build Coastguard Worker    o[0-7](?:_?[0-7])*               # oct
28*cda5da8dSAndroid Build Coastguard Worker)
29*cda5da8dSAndroid Build Coastguard Worker|
30*cda5da8dSAndroid Build Coastguard Worker[+-]?(?:0|[1-9](?:_?[0-9])*)         # dec, integer part
31*cda5da8dSAndroid Build Coastguard Worker(?P<floatpart>
32*cda5da8dSAndroid Build Coastguard Worker    (?:\.[0-9](?:_?[0-9])*)?         # optional fractional part
33*cda5da8dSAndroid Build Coastguard Worker    (?:[eE][+-]?[0-9](?:_?[0-9])*)?  # optional exponent part
34*cda5da8dSAndroid Build Coastguard Worker)
35*cda5da8dSAndroid Build Coastguard Worker""",
36*cda5da8dSAndroid Build Coastguard Worker    flags=re.VERBOSE,
37*cda5da8dSAndroid Build Coastguard Worker)
38*cda5da8dSAndroid Build Coastguard WorkerRE_LOCALTIME = re.compile(_TIME_RE_STR)
39*cda5da8dSAndroid Build Coastguard WorkerRE_DATETIME = re.compile(
40*cda5da8dSAndroid Build Coastguard Worker    rf"""
41*cda5da8dSAndroid Build Coastguard Worker([0-9]{{4}})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])  # date, e.g. 1988-10-27
42*cda5da8dSAndroid Build Coastguard Worker(?:
43*cda5da8dSAndroid Build Coastguard Worker    [Tt ]
44*cda5da8dSAndroid Build Coastguard Worker    {_TIME_RE_STR}
45*cda5da8dSAndroid Build Coastguard Worker    (?:([Zz])|([+-])([01][0-9]|2[0-3]):([0-5][0-9]))?  # optional time offset
46*cda5da8dSAndroid Build Coastguard Worker)?
47*cda5da8dSAndroid Build Coastguard Worker""",
48*cda5da8dSAndroid Build Coastguard Worker    flags=re.VERBOSE,
49*cda5da8dSAndroid Build Coastguard Worker)
50*cda5da8dSAndroid Build Coastguard Worker
51*cda5da8dSAndroid Build Coastguard Worker
52*cda5da8dSAndroid Build Coastguard Workerdef match_to_datetime(match: re.Match) -> datetime | date:
53*cda5da8dSAndroid Build Coastguard Worker    """Convert a `RE_DATETIME` match to `datetime.datetime` or `datetime.date`.
54*cda5da8dSAndroid Build Coastguard Worker
55*cda5da8dSAndroid Build Coastguard Worker    Raises ValueError if the match does not correspond to a valid date
56*cda5da8dSAndroid Build Coastguard Worker    or datetime.
57*cda5da8dSAndroid Build Coastguard Worker    """
58*cda5da8dSAndroid Build Coastguard Worker    (
59*cda5da8dSAndroid Build Coastguard Worker        year_str,
60*cda5da8dSAndroid Build Coastguard Worker        month_str,
61*cda5da8dSAndroid Build Coastguard Worker        day_str,
62*cda5da8dSAndroid Build Coastguard Worker        hour_str,
63*cda5da8dSAndroid Build Coastguard Worker        minute_str,
64*cda5da8dSAndroid Build Coastguard Worker        sec_str,
65*cda5da8dSAndroid Build Coastguard Worker        micros_str,
66*cda5da8dSAndroid Build Coastguard Worker        zulu_time,
67*cda5da8dSAndroid Build Coastguard Worker        offset_sign_str,
68*cda5da8dSAndroid Build Coastguard Worker        offset_hour_str,
69*cda5da8dSAndroid Build Coastguard Worker        offset_minute_str,
70*cda5da8dSAndroid Build Coastguard Worker    ) = match.groups()
71*cda5da8dSAndroid Build Coastguard Worker    year, month, day = int(year_str), int(month_str), int(day_str)
72*cda5da8dSAndroid Build Coastguard Worker    if hour_str is None:
73*cda5da8dSAndroid Build Coastguard Worker        return date(year, month, day)
74*cda5da8dSAndroid Build Coastguard Worker    hour, minute, sec = int(hour_str), int(minute_str), int(sec_str)
75*cda5da8dSAndroid Build Coastguard Worker    micros = int(micros_str.ljust(6, "0")) if micros_str else 0
76*cda5da8dSAndroid Build Coastguard Worker    if offset_sign_str:
77*cda5da8dSAndroid Build Coastguard Worker        tz: tzinfo | None = cached_tz(
78*cda5da8dSAndroid Build Coastguard Worker            offset_hour_str, offset_minute_str, offset_sign_str
79*cda5da8dSAndroid Build Coastguard Worker        )
80*cda5da8dSAndroid Build Coastguard Worker    elif zulu_time:
81*cda5da8dSAndroid Build Coastguard Worker        tz = timezone.utc
82*cda5da8dSAndroid Build Coastguard Worker    else:  # local date-time
83*cda5da8dSAndroid Build Coastguard Worker        tz = None
84*cda5da8dSAndroid Build Coastguard Worker    return datetime(year, month, day, hour, minute, sec, micros, tzinfo=tz)
85*cda5da8dSAndroid Build Coastguard Worker
86*cda5da8dSAndroid Build Coastguard Worker
87*cda5da8dSAndroid Build Coastguard Worker@lru_cache(maxsize=None)
88*cda5da8dSAndroid Build Coastguard Workerdef cached_tz(hour_str: str, minute_str: str, sign_str: str) -> timezone:
89*cda5da8dSAndroid Build Coastguard Worker    sign = 1 if sign_str == "+" else -1
90*cda5da8dSAndroid Build Coastguard Worker    return timezone(
91*cda5da8dSAndroid Build Coastguard Worker        timedelta(
92*cda5da8dSAndroid Build Coastguard Worker            hours=sign * int(hour_str),
93*cda5da8dSAndroid Build Coastguard Worker            minutes=sign * int(minute_str),
94*cda5da8dSAndroid Build Coastguard Worker        )
95*cda5da8dSAndroid Build Coastguard Worker    )
96*cda5da8dSAndroid Build Coastguard Worker
97*cda5da8dSAndroid Build Coastguard Worker
98*cda5da8dSAndroid Build Coastguard Workerdef match_to_localtime(match: re.Match) -> time:
99*cda5da8dSAndroid Build Coastguard Worker    hour_str, minute_str, sec_str, micros_str = match.groups()
100*cda5da8dSAndroid Build Coastguard Worker    micros = int(micros_str.ljust(6, "0")) if micros_str else 0
101*cda5da8dSAndroid Build Coastguard Worker    return time(int(hour_str), int(minute_str), int(sec_str), micros)
102*cda5da8dSAndroid Build Coastguard Worker
103*cda5da8dSAndroid Build Coastguard Worker
104*cda5da8dSAndroid Build Coastguard Workerdef match_to_number(match: re.Match, parse_float: ParseFloat) -> Any:
105*cda5da8dSAndroid Build Coastguard Worker    if match.group("floatpart"):
106*cda5da8dSAndroid Build Coastguard Worker        return parse_float(match.group())
107*cda5da8dSAndroid Build Coastguard Worker    return int(match.group(), 0)
108