@@ -32,91 +32,25 @@ def removeprefix(text: str, prefix: str) -> str:
3232 def removesuffix (text : str , suffix : str ) -> str :
3333 return text .removesuffix (suffix )
3434
35- ##
36-
3735 ## used to have compat function before 3.8 for these, keeping for runtime back compatibility
3836 from bisect import bisect_left
3937 from functools import cached_property
4038 from types import NoneType
4139
42- # used to have compat function before 3.9 for these, keeping for runtime back compatibility
40+ ##
41+ ## used to have compat function before 3.9 for these, keeping for runtime back compatibility
4342 from typing import Literal , ParamSpec , Protocol , TypeAlias , TypedDict
4443
4544 _KwOnlyType = TypedDict ("_KwOnlyType" , {"kw_only" : Literal [True ]}) # noqa: UP013
4645 KW_ONLY : _KwOnlyType = {"kw_only" : True }
47- ##
48-
46+ ##
4947
50- from datetime import datetime
48+ ## old compat for python <3.12
49+ from datetime import datetime
5150
52- if sys .version_info [:2 ] >= (3 , 11 ):
5351 fromisoformat = datetime .fromisoformat
54- else :
55- # fromisoformat didn't support Z as "utc" before 3.11
56- # https://docs.python.org/3/library/datetime.html#datetime.datetime.fromisoformat
57-
58- def fromisoformat (date_string : str ) -> datetime :
59- if date_string .endswith ('Z' ):
60- date_string = date_string [:- 1 ] + '+00:00'
61- return datetime .fromisoformat (date_string )
62-
63-
64- def test_fromisoformat () -> None :
65- from datetime import timezone
66-
67- # fmt: off
68- # feedbin has this format
69- assert fromisoformat ('2020-05-01T10:32:02.925961Z' ) == datetime (
70- 2020 , 5 , 1 , 10 , 32 , 2 , 925961 , timezone .utc ,
71- )
72-
73- # polar has this format
74- assert fromisoformat ('2018-11-28T22:04:01.304Z' ) == datetime (
75- 2018 , 11 , 28 , 22 , 4 , 1 , 304000 , timezone .utc ,
76- )
7752
78- # stackexchange, runnerup has this format
79- assert fromisoformat ('2020-11-30T00:53:12Z' ) == datetime (
80- 2020 , 11 , 30 , 0 , 53 , 12 , 0 , timezone .utc ,
81- )
82- # fmt: on
83-
84- # arbtt has this format (sometimes less/more than 6 digits in milliseconds)
85- # TODO doesn't work atm, not sure if really should be supported...
86- # maybe should have flags for weird formats?
87- # assert isoparse('2017-07-18T18:59:38.21731Z') == datetime(
88- # 2017, 7, 18, 18, 59, 38, 217310, timezone.utc,
89- # )
90-
91-
92- if sys .version_info [:2 ] >= (3 , 11 ):
9353 from typing import Never , assert_never , assert_type
94- else :
95- from typing_extensions import Never , assert_never , assert_type
96-
9754
98- if sys .version_info [:2 ] >= (3 , 11 ):
9955 add_note = BaseException .add_note
100- else :
101-
102- def add_note (e : BaseException , note : str ) -> None :
103- """
104- Backport of BaseException.add_note
105- """
106-
107- # The only (somewhat annoying) difference is it will log extra lines for notes past the main exception message:
108- # (i.e. line 2 here:)
109-
110- # 1 [ERROR 2025-02-04 22:12:21] Main exception message
111- # 2 ^ extra note
112- # 3 Traceback (most recent call last):
113- # 4 File "run.py", line 19, in <module>
114- # 5 ee = test()
115- # 6 File "run.py", line 5, in test
116- # 7 raise RuntimeError("Main exception message")
117- # 8 RuntimeError: Main exception message
118- # 9 ^ extra note
119-
120- args = e .args
121- if len (args ) == 1 and isinstance (args [0 ], str ):
122- e .args = (e .args [0 ] + '\n ' + note ,)
56+ ##
0 commit comments