ominfra 0.0.0.dev309__py3-none-any.whl → 0.0.0.dev310__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ominfra/scripts/journald2aws.py +101 -0
- ominfra/scripts/manage.py +101 -0
- ominfra/scripts/supervisor.py +101 -0
- {ominfra-0.0.0.dev309.dist-info → ominfra-0.0.0.dev310.dist-info}/METADATA +3 -3
- {ominfra-0.0.0.dev309.dist-info → ominfra-0.0.0.dev310.dist-info}/RECORD +9 -9
- {ominfra-0.0.0.dev309.dist-info → ominfra-0.0.0.dev310.dist-info}/WHEEL +0 -0
- {ominfra-0.0.0.dev309.dist-info → ominfra-0.0.0.dev310.dist-info}/entry_points.txt +0 -0
- {ominfra-0.0.0.dev309.dist-info → ominfra-0.0.0.dev310.dist-info}/licenses/LICENSE +0 -0
- {ominfra-0.0.0.dev309.dist-info → ominfra-0.0.0.dev310.dist-info}/top_level.txt +0 -0
ominfra/scripts/manage.py
CHANGED
@@ -1524,29 +1524,37 @@ class TomlFlags:
|
|
1524
1524
|
def set(self, key: TomlKey, flag: int, *, recursive: bool) -> None: # noqa: A003
|
1525
1525
|
cont = self._flags
|
1526
1526
|
key_parent, key_stem = key[:-1], key[-1]
|
1527
|
+
|
1527
1528
|
for k in key_parent:
|
1528
1529
|
if k not in cont:
|
1529
1530
|
cont[k] = {'flags': set(), 'recursive_flags': set(), 'nested': {}}
|
1530
1531
|
cont = cont[k]['nested']
|
1532
|
+
|
1531
1533
|
if key_stem not in cont:
|
1532
1534
|
cont[key_stem] = {'flags': set(), 'recursive_flags': set(), 'nested': {}}
|
1535
|
+
|
1533
1536
|
cont[key_stem]['recursive_flags' if recursive else 'flags'].add(flag)
|
1534
1537
|
|
1535
1538
|
def is_(self, key: TomlKey, flag: int) -> bool:
|
1536
1539
|
if not key:
|
1537
1540
|
return False # document root has no flags
|
1541
|
+
|
1538
1542
|
cont = self._flags
|
1539
1543
|
for k in key[:-1]:
|
1540
1544
|
if k not in cont:
|
1541
1545
|
return False
|
1546
|
+
|
1542
1547
|
inner_cont = cont[k]
|
1543
1548
|
if flag in inner_cont['recursive_flags']:
|
1544
1549
|
return True
|
1550
|
+
|
1545
1551
|
cont = inner_cont['nested']
|
1552
|
+
|
1546
1553
|
key_stem = key[-1]
|
1547
1554
|
if key_stem in cont:
|
1548
1555
|
cont = cont[key_stem]
|
1549
1556
|
return flag in cont['flags'] or flag in cont['recursive_flags']
|
1557
|
+
|
1550
1558
|
return False
|
1551
1559
|
|
1552
1560
|
|
@@ -1564,24 +1572,31 @@ class TomlNestedDict:
|
|
1564
1572
|
access_lists: bool = True,
|
1565
1573
|
) -> dict:
|
1566
1574
|
cont: ta.Any = self.dict
|
1575
|
+
|
1567
1576
|
for k in key:
|
1568
1577
|
if k not in cont:
|
1569
1578
|
cont[k] = {}
|
1579
|
+
|
1570
1580
|
cont = cont[k]
|
1581
|
+
|
1571
1582
|
if access_lists and isinstance(cont, list):
|
1572
1583
|
cont = cont[-1]
|
1584
|
+
|
1573
1585
|
if not isinstance(cont, dict):
|
1574
1586
|
raise KeyError('There is no nest behind this key')
|
1587
|
+
|
1575
1588
|
return cont
|
1576
1589
|
|
1577
1590
|
def append_nest_to_list(self, key: TomlKey) -> None:
|
1578
1591
|
cont = self.get_or_create_nest(key[:-1])
|
1592
|
+
|
1579
1593
|
last_key = key[-1]
|
1580
1594
|
if last_key in cont:
|
1581
1595
|
list_ = cont[last_key]
|
1582
1596
|
if not isinstance(list_, list):
|
1583
1597
|
raise KeyError('An object other than list found behind this key')
|
1584
1598
|
list_.append({})
|
1599
|
+
|
1585
1600
|
else:
|
1586
1601
|
cont[last_key] = [{}]
|
1587
1602
|
|
@@ -1651,23 +1666,30 @@ class TomlParser:
|
|
1651
1666
|
char = self.src[self.pos]
|
1652
1667
|
except IndexError:
|
1653
1668
|
break
|
1669
|
+
|
1654
1670
|
if char == '\n':
|
1655
1671
|
self.pos += 1
|
1656
1672
|
continue
|
1673
|
+
|
1657
1674
|
if char in self.KEY_INITIAL_CHARS:
|
1658
1675
|
self.key_value_rule(header)
|
1659
1676
|
self.skip_chars(self.WS)
|
1677
|
+
|
1660
1678
|
elif char == '[':
|
1661
1679
|
try:
|
1662
1680
|
second_char: ta.Optional[str] = self.src[self.pos + 1]
|
1663
1681
|
except IndexError:
|
1664
1682
|
second_char = None
|
1683
|
+
|
1665
1684
|
self.flags.finalize_pending()
|
1685
|
+
|
1666
1686
|
if second_char == '[':
|
1667
1687
|
header = self.create_list_rule()
|
1668
1688
|
else:
|
1669
1689
|
header = self.create_dict_rule()
|
1690
|
+
|
1670
1691
|
self.skip_chars(self.WS)
|
1692
|
+
|
1671
1693
|
elif char != '#':
|
1672
1694
|
raise self.suffixed_err('Invalid statement')
|
1673
1695
|
|
@@ -1679,8 +1701,10 @@ class TomlParser:
|
|
1679
1701
|
char = self.src[self.pos]
|
1680
1702
|
except IndexError:
|
1681
1703
|
break
|
1704
|
+
|
1682
1705
|
if char != '\n':
|
1683
1706
|
raise self.suffixed_err('Expected newline or end of document after a statement')
|
1707
|
+
|
1684
1708
|
self.pos += 1
|
1685
1709
|
|
1686
1710
|
return self.data.dict
|
@@ -1709,7 +1733,9 @@ class TomlParser:
|
|
1709
1733
|
if not error_on.isdisjoint(self.src[self.pos:new_pos]):
|
1710
1734
|
while self.src[self.pos] not in error_on:
|
1711
1735
|
self.pos += 1
|
1736
|
+
|
1712
1737
|
raise self.suffixed_err(f'Found invalid character {self.src[self.pos]!r}')
|
1738
|
+
|
1713
1739
|
self.pos = new_pos
|
1714
1740
|
|
1715
1741
|
def skip_comment(self) -> None:
|
@@ -1717,6 +1743,7 @@ class TomlParser:
|
|
1717
1743
|
char: ta.Optional[str] = self.src[self.pos]
|
1718
1744
|
except IndexError:
|
1719
1745
|
char = None
|
1746
|
+
|
1720
1747
|
if char == '#':
|
1721
1748
|
self.pos += 1
|
1722
1749
|
self.skip_until(
|
@@ -1740,7 +1767,9 @@ class TomlParser:
|
|
1740
1767
|
|
1741
1768
|
if self.flags.is_(key, TomlFlags.EXPLICIT_NEST) or self.flags.is_(key, TomlFlags.FROZEN):
|
1742
1769
|
raise self.suffixed_err(f'Cannot declare {key} twice')
|
1770
|
+
|
1743
1771
|
self.flags.set(key, TomlFlags.EXPLICIT_NEST, recursive=False)
|
1772
|
+
|
1744
1773
|
try:
|
1745
1774
|
self.data.get_or_create_nest(key)
|
1746
1775
|
except KeyError:
|
@@ -1748,20 +1777,25 @@ class TomlParser:
|
|
1748
1777
|
|
1749
1778
|
if not self.src.startswith(']', self.pos):
|
1750
1779
|
raise self.suffixed_err("Expected ']' at the end of a table declaration")
|
1780
|
+
|
1751
1781
|
self.pos += 1
|
1752
1782
|
return key
|
1753
1783
|
|
1754
1784
|
def create_list_rule(self) -> TomlKey:
|
1755
1785
|
self.pos += 2 # Skip "[["
|
1756
1786
|
self.skip_chars(self.WS)
|
1787
|
+
|
1757
1788
|
key = self.parse_key()
|
1758
1789
|
|
1759
1790
|
if self.flags.is_(key, TomlFlags.FROZEN):
|
1760
1791
|
raise self.suffixed_err(f'Cannot mutate immutable namespace {key}')
|
1792
|
+
|
1761
1793
|
# Free the namespace now that it points to another empty list item...
|
1762
1794
|
self.flags.unset_all(key)
|
1795
|
+
|
1763
1796
|
# ...but this key precisely is still prohibited from table declaration
|
1764
1797
|
self.flags.set(key, TomlFlags.EXPLICIT_NEST, recursive=False)
|
1798
|
+
|
1765
1799
|
try:
|
1766
1800
|
self.data.append_nest_to_list(key)
|
1767
1801
|
except KeyError:
|
@@ -1769,6 +1803,7 @@ class TomlParser:
|
|
1769
1803
|
|
1770
1804
|
if not self.src.startswith(']]', self.pos):
|
1771
1805
|
raise self.suffixed_err("Expected ']]' at the end of an array declaration")
|
1806
|
+
|
1772
1807
|
self.pos += 2
|
1773
1808
|
return key
|
1774
1809
|
|
@@ -1782,6 +1817,7 @@ class TomlParser:
|
|
1782
1817
|
# Check that dotted key syntax does not redefine an existing table
|
1783
1818
|
if self.flags.is_(cont_key, TomlFlags.EXPLICIT_NEST):
|
1784
1819
|
raise self.suffixed_err(f'Cannot redefine namespace {cont_key}')
|
1820
|
+
|
1785
1821
|
# Containers in the relative path can't be opened with the table syntax or dotted key/value syntax in
|
1786
1822
|
# following table sections.
|
1787
1823
|
self.flags.add_pending(cont_key, TomlFlags.EXPLICIT_NEST)
|
@@ -1793,41 +1829,54 @@ class TomlParser:
|
|
1793
1829
|
nest = self.data.get_or_create_nest(abs_key_parent)
|
1794
1830
|
except KeyError:
|
1795
1831
|
raise self.suffixed_err('Cannot overwrite a value') from None
|
1832
|
+
|
1796
1833
|
if key_stem in nest:
|
1797
1834
|
raise self.suffixed_err('Cannot overwrite a value')
|
1835
|
+
|
1798
1836
|
# Mark inline table and array namespaces recursively immutable
|
1799
1837
|
if isinstance(value, (dict, list)):
|
1800
1838
|
self.flags.set(header + key, TomlFlags.FROZEN, recursive=True)
|
1839
|
+
|
1801
1840
|
nest[key_stem] = value
|
1802
1841
|
|
1803
1842
|
def parse_key_value_pair(self) -> ta.Tuple[TomlKey, ta.Any]:
|
1804
1843
|
key = self.parse_key()
|
1844
|
+
|
1805
1845
|
try:
|
1806
1846
|
char: ta.Optional[str] = self.src[self.pos]
|
1807
1847
|
except IndexError:
|
1808
1848
|
char = None
|
1849
|
+
|
1809
1850
|
if char != '=':
|
1810
1851
|
raise self.suffixed_err("Expected '=' after a key in a key/value pair")
|
1852
|
+
|
1811
1853
|
self.pos += 1
|
1812
1854
|
self.skip_chars(self.WS)
|
1855
|
+
|
1813
1856
|
value = self.parse_value()
|
1814
1857
|
return key, value
|
1815
1858
|
|
1816
1859
|
def parse_key(self) -> TomlKey:
|
1817
1860
|
key_part = self.parse_key_part()
|
1818
1861
|
key: TomlKey = (key_part,)
|
1862
|
+
|
1819
1863
|
self.skip_chars(self.WS)
|
1864
|
+
|
1820
1865
|
while True:
|
1821
1866
|
try:
|
1822
1867
|
char: ta.Optional[str] = self.src[self.pos]
|
1823
1868
|
except IndexError:
|
1824
1869
|
char = None
|
1870
|
+
|
1825
1871
|
if char != '.':
|
1826
1872
|
return key
|
1873
|
+
|
1827
1874
|
self.pos += 1
|
1828
1875
|
self.skip_chars(self.WS)
|
1876
|
+
|
1829
1877
|
key_part = self.parse_key_part()
|
1830
1878
|
key += (key_part,)
|
1879
|
+
|
1831
1880
|
self.skip_chars(self.WS)
|
1832
1881
|
|
1833
1882
|
def parse_key_part(self) -> str:
|
@@ -1835,14 +1884,18 @@ class TomlParser:
|
|
1835
1884
|
char: ta.Optional[str] = self.src[self.pos]
|
1836
1885
|
except IndexError:
|
1837
1886
|
char = None
|
1887
|
+
|
1838
1888
|
if char in self.BARE_KEY_CHARS:
|
1839
1889
|
start_pos = self.pos
|
1840
1890
|
self.skip_chars(self.BARE_KEY_CHARS)
|
1841
1891
|
return self.src[start_pos:self.pos]
|
1892
|
+
|
1842
1893
|
if char == "'":
|
1843
1894
|
return self.parse_literal_str()
|
1895
|
+
|
1844
1896
|
if char == '"':
|
1845
1897
|
return self.parse_one_line_basic_str()
|
1898
|
+
|
1846
1899
|
raise self.suffixed_err('Invalid initial character for a key part')
|
1847
1900
|
|
1848
1901
|
def parse_one_line_basic_str(self) -> str:
|
@@ -1857,6 +1910,7 @@ class TomlParser:
|
|
1857
1910
|
if self.src.startswith(']', self.pos):
|
1858
1911
|
self.pos += 1
|
1859
1912
|
return array
|
1913
|
+
|
1860
1914
|
while True:
|
1861
1915
|
val = self.parse_value()
|
1862
1916
|
array.append(val)
|
@@ -1866,11 +1920,14 @@ class TomlParser:
|
|
1866
1920
|
if c == ']':
|
1867
1921
|
self.pos += 1
|
1868
1922
|
return array
|
1923
|
+
|
1869
1924
|
if c != ',':
|
1870
1925
|
raise self.suffixed_err('Unclosed array')
|
1926
|
+
|
1871
1927
|
self.pos += 1
|
1872
1928
|
|
1873
1929
|
self.skip_comments_and_array_ws()
|
1930
|
+
|
1874
1931
|
if self.src.startswith(']', self.pos):
|
1875
1932
|
self.pos += 1
|
1876
1933
|
return array
|
@@ -1881,54 +1938,72 @@ class TomlParser:
|
|
1881
1938
|
flags = TomlFlags()
|
1882
1939
|
|
1883
1940
|
self.skip_chars(self.WS)
|
1941
|
+
|
1884
1942
|
if self.src.startswith('}', self.pos):
|
1885
1943
|
self.pos += 1
|
1886
1944
|
return nested_dict.dict
|
1945
|
+
|
1887
1946
|
while True:
|
1888
1947
|
key, value = self.parse_key_value_pair()
|
1889
1948
|
key_parent, key_stem = key[:-1], key[-1]
|
1949
|
+
|
1890
1950
|
if flags.is_(key, TomlFlags.FROZEN):
|
1891
1951
|
raise self.suffixed_err(f'Cannot mutate immutable namespace {key}')
|
1952
|
+
|
1892
1953
|
try:
|
1893
1954
|
nest = nested_dict.get_or_create_nest(key_parent, access_lists=False)
|
1894
1955
|
except KeyError:
|
1895
1956
|
raise self.suffixed_err('Cannot overwrite a value') from None
|
1957
|
+
|
1896
1958
|
if key_stem in nest:
|
1897
1959
|
raise self.suffixed_err(f'Duplicate inline table key {key_stem!r}')
|
1960
|
+
|
1898
1961
|
nest[key_stem] = value
|
1899
1962
|
self.skip_chars(self.WS)
|
1963
|
+
|
1900
1964
|
c = self.src[self.pos:self.pos + 1]
|
1901
1965
|
if c == '}':
|
1902
1966
|
self.pos += 1
|
1903
1967
|
return nested_dict.dict
|
1968
|
+
|
1904
1969
|
if c != ',':
|
1905
1970
|
raise self.suffixed_err('Unclosed inline table')
|
1971
|
+
|
1906
1972
|
if isinstance(value, (dict, list)):
|
1907
1973
|
flags.set(key, TomlFlags.FROZEN, recursive=True)
|
1974
|
+
|
1908
1975
|
self.pos += 1
|
1909
1976
|
self.skip_chars(self.WS)
|
1910
1977
|
|
1911
1978
|
def parse_basic_str_escape(self, multiline: bool = False) -> str:
|
1912
1979
|
escape_id = self.src[self.pos:self.pos + 2]
|
1913
1980
|
self.pos += 2
|
1981
|
+
|
1914
1982
|
if multiline and escape_id in {'\\ ', '\\\t', '\\\n'}:
|
1915
1983
|
# Skip whitespace until next non-whitespace character or end of the doc. Error if non-whitespace is found
|
1916
1984
|
# before newline.
|
1917
1985
|
if escape_id != '\\\n':
|
1918
1986
|
self.skip_chars(self.WS)
|
1987
|
+
|
1919
1988
|
try:
|
1920
1989
|
char = self.src[self.pos]
|
1921
1990
|
except IndexError:
|
1922
1991
|
return ''
|
1992
|
+
|
1923
1993
|
if char != '\n':
|
1924
1994
|
raise self.suffixed_err("Unescaped '\\' in a string")
|
1995
|
+
|
1925
1996
|
self.pos += 1
|
1997
|
+
|
1926
1998
|
self.skip_chars(self.WS_AND_NEWLINE)
|
1927
1999
|
return ''
|
2000
|
+
|
1928
2001
|
if escape_id == '\\u':
|
1929
2002
|
return self.parse_hex_char(4)
|
2003
|
+
|
1930
2004
|
if escape_id == '\\U':
|
1931
2005
|
return self.parse_hex_char(8)
|
2006
|
+
|
1932
2007
|
try:
|
1933
2008
|
return self.BASIC_STR_ESCAPE_REPLACEMENTS[escape_id]
|
1934
2009
|
except KeyError:
|
@@ -1943,12 +2018,16 @@ class TomlParser:
|
|
1943
2018
|
|
1944
2019
|
def parse_hex_char(self, hex_len: int) -> str:
|
1945
2020
|
hex_str = self.src[self.pos:self.pos + hex_len]
|
2021
|
+
|
1946
2022
|
if len(hex_str) != hex_len or not self.HEXDIGIT_CHARS.issuperset(hex_str):
|
1947
2023
|
raise self.suffixed_err('Invalid hex value')
|
2024
|
+
|
1948
2025
|
self.pos += hex_len
|
1949
2026
|
hex_int = int(hex_str, 16)
|
2027
|
+
|
1950
2028
|
if not self.is_unicode_scalar_value(hex_int):
|
1951
2029
|
raise self.suffixed_err('Escaped character is not a Unicode scalar value')
|
2030
|
+
|
1952
2031
|
return chr(hex_int)
|
1953
2032
|
|
1954
2033
|
def parse_literal_str(self) -> str:
|
@@ -1974,6 +2053,7 @@ class TomlParser:
|
|
1974
2053
|
)
|
1975
2054
|
result = self.src[start_pos:self.pos]
|
1976
2055
|
self.pos += 3
|
2056
|
+
|
1977
2057
|
else:
|
1978
2058
|
delim = '"'
|
1979
2059
|
result = self.parse_basic_str(multiline=True)
|
@@ -1981,9 +2061,11 @@ class TomlParser:
|
|
1981
2061
|
# Add at maximum two extra apostrophes/quotes if the end sequence is 4 or 5 chars long instead of just 3.
|
1982
2062
|
if not self.src.startswith(delim, self.pos):
|
1983
2063
|
return result
|
2064
|
+
|
1984
2065
|
self.pos += 1
|
1985
2066
|
if not self.src.startswith(delim, self.pos):
|
1986
2067
|
return result + delim
|
2068
|
+
|
1987
2069
|
self.pos += 1
|
1988
2070
|
return result + (delim * 2)
|
1989
2071
|
|
@@ -1994,6 +2076,7 @@ class TomlParser:
|
|
1994
2076
|
else:
|
1995
2077
|
error_on = self.ILLEGAL_BASIC_STR_CHARS
|
1996
2078
|
parse_escapes = self.parse_basic_str_escape
|
2079
|
+
|
1997
2080
|
result = ''
|
1998
2081
|
start_pos = self.pos
|
1999
2082
|
while True:
|
@@ -2001,25 +2084,31 @@ class TomlParser:
|
|
2001
2084
|
char = self.src[self.pos]
|
2002
2085
|
except IndexError:
|
2003
2086
|
raise self.suffixed_err('Unterminated string') from None
|
2087
|
+
|
2004
2088
|
if char == '"':
|
2005
2089
|
if not multiline:
|
2006
2090
|
end_pos = self.pos
|
2007
2091
|
self.pos += 1
|
2008
2092
|
return result + self.src[start_pos:end_pos]
|
2093
|
+
|
2009
2094
|
if self.src.startswith('"""', self.pos):
|
2010
2095
|
end_pos = self.pos
|
2011
2096
|
self.pos += 3
|
2012
2097
|
return result + self.src[start_pos:end_pos]
|
2098
|
+
|
2013
2099
|
self.pos += 1
|
2014
2100
|
continue
|
2101
|
+
|
2015
2102
|
if char == '\\':
|
2016
2103
|
result += self.src[start_pos:self.pos]
|
2017
2104
|
parsed_escape = parse_escapes()
|
2018
2105
|
result += parsed_escape
|
2019
2106
|
start_pos = self.pos
|
2020
2107
|
continue
|
2108
|
+
|
2021
2109
|
if char in error_on:
|
2022
2110
|
raise self.suffixed_err(f'Illegal character {char!r}')
|
2111
|
+
|
2023
2112
|
self.pos += 1
|
2024
2113
|
|
2025
2114
|
def parse_value(self) -> ta.Any: # noqa: C901
|
@@ -2047,6 +2136,7 @@ class TomlParser:
|
|
2047
2136
|
if self.src.startswith('true', self.pos):
|
2048
2137
|
self.pos += 4
|
2049
2138
|
return True
|
2139
|
+
|
2050
2140
|
if char == 'f':
|
2051
2141
|
if self.src.startswith('false', self.pos):
|
2052
2142
|
self.pos += 5
|
@@ -2067,8 +2157,10 @@ class TomlParser:
|
|
2067
2157
|
datetime_obj = self.match_to_datetime(datetime_match)
|
2068
2158
|
except ValueError as e:
|
2069
2159
|
raise self.suffixed_err('Invalid date or datetime') from e
|
2160
|
+
|
2070
2161
|
self.pos = datetime_match.end()
|
2071
2162
|
return datetime_obj
|
2163
|
+
|
2072
2164
|
localtime_match = self.RE_LOCALTIME.match(self.src, self.pos)
|
2073
2165
|
if localtime_match:
|
2074
2166
|
self.pos = localtime_match.end()
|
@@ -2086,6 +2178,7 @@ class TomlParser:
|
|
2086
2178
|
if first_three in {'inf', 'nan'}:
|
2087
2179
|
self.pos += 3
|
2088
2180
|
return self.parse_float(first_three)
|
2181
|
+
|
2089
2182
|
first_four = self.src[self.pos:self.pos + 4]
|
2090
2183
|
if first_four in {'-inf', '+inf', '-nan', '+nan'}:
|
2091
2184
|
self.pos += 4
|
@@ -2096,11 +2189,13 @@ class TomlParser:
|
|
2096
2189
|
def coord_repr(self, pos: TomlPos) -> str:
|
2097
2190
|
if pos >= len(self.src):
|
2098
2191
|
return 'end of document'
|
2192
|
+
|
2099
2193
|
line = self.src.count('\n', 0, pos) + 1
|
2100
2194
|
if line == 1:
|
2101
2195
|
column = pos + 1
|
2102
2196
|
else:
|
2103
2197
|
column = pos - self.src.rindex('\n', 0, pos)
|
2198
|
+
|
2104
2199
|
return f'line {line}, column {column}'
|
2105
2200
|
|
2106
2201
|
def suffixed_err(self, msg: str, *, pos: ta.Optional[TomlPos] = None) -> TomlDecodeError:
|
@@ -2167,11 +2262,16 @@ class TomlParser:
|
|
2167
2262
|
offset_hour_str,
|
2168
2263
|
offset_minute_str,
|
2169
2264
|
) = match.groups()
|
2265
|
+
|
2170
2266
|
year, month, day = int(year_str), int(month_str), int(day_str)
|
2267
|
+
|
2171
2268
|
if hour_str is None:
|
2172
2269
|
return datetime.date(year, month, day)
|
2270
|
+
|
2173
2271
|
hour, minute, sec = int(hour_str), int(minute_str), int(sec_str)
|
2272
|
+
|
2174
2273
|
micros = int(micros_str.ljust(6, '0')) if micros_str else 0
|
2274
|
+
|
2175
2275
|
if offset_sign_str:
|
2176
2276
|
tz: ta.Optional[datetime.tzinfo] = toml_cached_tz(
|
2177
2277
|
offset_hour_str, offset_minute_str, offset_sign_str,
|
@@ -2180,6 +2280,7 @@ class TomlParser:
|
|
2180
2280
|
tz = datetime.UTC
|
2181
2281
|
else: # local date-time
|
2182
2282
|
tz = None
|
2283
|
+
|
2183
2284
|
return datetime.datetime(year, month, day, hour, minute, sec, micros, tzinfo=tz)
|
2184
2285
|
|
2185
2286
|
@classmethod
|