From 61e51e424e5895148f5c0e0ed78ee83b5a73675d Mon Sep 17 00:00:00 2001 From: ShaharNaveh <50263213+ShaharNaveh@users.noreply.github.com> Date: Fri, 4 Jul 2025 14:41:08 +0300 Subject: [PATCH] Update tomllib from 3.13.5 --- Lib/test/test_tomllib/__main__.py | 2 +- Lib/test/test_tomllib/test_misc.py | 27 +++++++++++++++++++-------- Lib/tomllib/_parser.py | 14 +++++++------- Lib/tomllib/_re.py | 6 +++--- Lib/tomllib/mypy.ini | 17 +++++++++++++++++ 5 files changed, 47 insertions(+), 19 deletions(-) create mode 100644 Lib/tomllib/mypy.ini diff --git a/Lib/test/test_tomllib/__main__.py b/Lib/test/test_tomllib/__main__.py index f309c7ec72..dd06365343 100644 --- a/Lib/test/test_tomllib/__main__.py +++ b/Lib/test/test_tomllib/__main__.py @@ -1,6 +1,6 @@ import unittest -from test.test_tomllib import load_tests +from . import load_tests unittest.main() diff --git a/Lib/test/test_tomllib/test_misc.py b/Lib/test/test_tomllib/test_misc.py index a477a219fd..9e677a337a 100644 --- a/Lib/test/test_tomllib/test_misc.py +++ b/Lib/test/test_tomllib/test_misc.py @@ -9,6 +9,7 @@ import sys import tempfile import unittest +from test import support from . import tomllib @@ -92,13 +93,23 @@ def test_deepcopy(self): self.assertEqual(obj_copy, expected_obj) def test_inline_array_recursion_limit(self): - # 465 with default recursion limit - nest_count = int(sys.getrecursionlimit() * 0.465) - recursive_array_toml = "arr = " + nest_count * "[" + nest_count * "]" - tomllib.loads(recursive_array_toml) + with support.infinite_recursion(max_depth=100): + available = support.get_recursion_available() + nest_count = (available // 2) - 2 + # Add details if the test fails + with self.subTest(limit=sys.getrecursionlimit(), + available=available, + nest_count=nest_count): + recursive_array_toml = "arr = " + nest_count * "[" + nest_count * "]" + tomllib.loads(recursive_array_toml) def test_inline_table_recursion_limit(self): - # 310 with default recursion limit - nest_count = int(sys.getrecursionlimit() * 0.31) - recursive_table_toml = nest_count * "key = {" + nest_count * "}" - tomllib.loads(recursive_table_toml) + with support.infinite_recursion(max_depth=100): + available = support.get_recursion_available() + nest_count = (available // 3) - 1 + # Add details if the test fails + with self.subTest(limit=sys.getrecursionlimit(), + available=available, + nest_count=nest_count): + recursive_table_toml = nest_count * "key = {" + nest_count * "}" + tomllib.loads(recursive_table_toml) diff --git a/Lib/tomllib/_parser.py b/Lib/tomllib/_parser.py index 45ca7a8963..9c80a6a547 100644 --- a/Lib/tomllib/_parser.py +++ b/Lib/tomllib/_parser.py @@ -142,7 +142,7 @@ class Flags: EXPLICIT_NEST = 1 def __init__(self) -> None: - self._flags: dict[str, dict] = {} + self._flags: dict[str, dict[Any, Any]] = {} self._pending_flags: set[tuple[Key, int]] = set() def add_pending(self, key: Key, flag: int) -> None: @@ -200,7 +200,7 @@ def get_or_create_nest( key: Key, *, access_lists: bool = True, - ) -> dict: + ) -> dict[str, Any]: cont: Any = self.dict for k in key: if k not in cont: @@ -210,7 +210,7 @@ def get_or_create_nest( cont = cont[-1] if not isinstance(cont, dict): raise KeyError("There is no nest behind this key") - return cont + return cont # type: ignore[no-any-return] def append_nest_to_list(self, key: Key) -> None: cont = self.get_or_create_nest(key[:-1]) @@ -409,9 +409,9 @@ def parse_one_line_basic_str(src: str, pos: Pos) -> tuple[Pos, str]: return parse_basic_str(src, pos, multiline=False) -def parse_array(src: str, pos: Pos, parse_float: ParseFloat) -> tuple[Pos, list]: +def parse_array(src: str, pos: Pos, parse_float: ParseFloat) -> tuple[Pos, list[Any]]: pos += 1 - array: list = [] + array: list[Any] = [] pos = skip_comments_and_array_ws(src, pos) if src.startswith("]", pos): @@ -433,7 +433,7 @@ def parse_array(src: str, pos: Pos, parse_float: ParseFloat) -> tuple[Pos, list] return pos + 1, array -def parse_inline_table(src: str, pos: Pos, parse_float: ParseFloat) -> tuple[Pos, dict]: +def parse_inline_table(src: str, pos: Pos, parse_float: ParseFloat) -> tuple[Pos, dict[str, Any]]: pos += 1 nested_dict = NestedDict() flags = Flags() @@ -679,7 +679,7 @@ def make_safe_parse_float(parse_float: ParseFloat) -> ParseFloat: instead of returning illegal types. """ # The default `float` callable never returns illegal types. Optimize it. - if parse_float is float: # type: ignore[comparison-overlap] + if parse_float is float: return float def safe_parse_float(float_str: str) -> Any: diff --git a/Lib/tomllib/_re.py b/Lib/tomllib/_re.py index 994bb7493f..a97cab2f9d 100644 --- a/Lib/tomllib/_re.py +++ b/Lib/tomllib/_re.py @@ -49,7 +49,7 @@ ) -def match_to_datetime(match: re.Match) -> datetime | date: +def match_to_datetime(match: re.Match[str]) -> datetime | date: """Convert a `RE_DATETIME` match to `datetime.datetime` or `datetime.date`. Raises ValueError if the match does not correspond to a valid date @@ -95,13 +95,13 @@ def cached_tz(hour_str: str, minute_str: str, sign_str: str) -> timezone: ) -def match_to_localtime(match: re.Match) -> time: +def match_to_localtime(match: re.Match[str]) -> time: hour_str, minute_str, sec_str, micros_str = match.groups() micros = int(micros_str.ljust(6, "0")) if micros_str else 0 return time(int(hour_str), int(minute_str), int(sec_str), micros) -def match_to_number(match: re.Match, parse_float: ParseFloat) -> Any: +def match_to_number(match: re.Match[str], parse_float: ParseFloat) -> Any: if match.group("floatpart"): return parse_float(match.group()) return int(match.group(), 0) diff --git a/Lib/tomllib/mypy.ini b/Lib/tomllib/mypy.ini new file mode 100644 index 0000000000..1761dce455 --- /dev/null +++ b/Lib/tomllib/mypy.ini @@ -0,0 +1,17 @@ +# Config file for running mypy on tomllib. +# Run mypy by invoking `mypy --config-file Lib/tomllib/mypy.ini` +# on the command-line from the repo root + +[mypy] +files = Lib/tomllib +mypy_path = $MYPY_CONFIG_FILE_DIR/../../Misc/mypy +explicit_package_bases = True +python_version = 3.12 +pretty = True + +# Enable most stricter settings +enable_error_code = ignore-without-code +strict = True +strict_bytes = True +local_partial_types = True +warn_unreachable = True