FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

gh-142956: Update `tomllib` to parse TOML 1.1.0 by hukkin · Pull Request #144243 · python/cpython · GitHub

Repository navigation

Prev Previous commit
Next Next commit
tomllib: Sync with Tomli to reduce diff
  • Loading branch information
hukkin committed Jan 26, 2026
commit 329e049c0cab0f2f0cc949cb2fcb405a0018b561
33 changes: 8 additions & 25 deletions Lib/test/test_tomllib/burntsushi.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,8 @@
import datetime
from typing import Any

# Aliases for converting TOML compliance format [1] to BurntSushi format [2]
# [1] https://github.com/toml-lang/compliance/blob/db7c3211fda30ff9ddb10292f4aeda7e2e10abc4/docs/json-encoding.md # noqa: E501
# [2] https://github.com/BurntSushi/toml-test/blob/4634fdf3a6ecd6aaea5f4cdcd98b2733c2694993/README.md # noqa: E501
_aliases = {
"boolean": "bool",
"offset datetime": "datetime",
"local datetime": "datetime-local",
"local date": "date-local",
"local time": "time-local",
}


def convert(obj): # noqa: C901

def convert(obj):
if isinstance(obj, str):
return {"type": "string", "value": obj}
elif isinstance(obj, bool):
Expand Down Expand Up @@ -53,31 +42,25 @@ def convert(obj): # noqa: C901
def normalize(obj: Any) -> Any:
"""Normalize test objects.

This normalizes primitive values (e.g. floats), and also converts from
TOML compliance format [1] to BurntSushi format [2].

[1] https://github.com/toml-lang/compliance/blob/db7c3211fda30ff9ddb10292f4aeda7e2e10abc4/docs/json-encoding.md # noqa: E501
[2] https://github.com/BurntSushi/toml-test/blob/4634fdf3a6ecd6aaea5f4cdcd98b2733c2694993/README.md # noqa: E501
"""
This normalizes primitive values (e.g. floats)."""
if isinstance(obj, list):
return [normalize(item) for item in obj]
if isinstance(obj, dict):
if "type" in obj and "value" in obj:
type_ = obj["type"]
norm_type = _aliases.get(type_, type_)
value = obj["value"]
if norm_type == "float":
if type_ == "float":
norm_value = _normalize_float_str(value)
elif norm_type in {"datetime", "datetime-local"}:
elif type_ in {"datetime", "datetime-local"}:
norm_value = _normalize_datetime_str(value)
elif norm_type == "time-local":
elif type_ == "time-local":
norm_value = _normalize_localtime_str(value)
else:
norm_value = value

if norm_type == "array":
if type_ == "array":
return [normalize(item) for item in value]
return {"type": norm_type, "value": norm_value}
return {"type": type_, "value": norm_value}
return {k: normalize(v) for k, v in obj.items()}
raise AssertionError("Burntsushi fixtures should be dicts/lists only")

Expand Down
19 changes: 1 addition & 18 deletions Lib/test/test_tomllib/test_data.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,6 @@

from . import burntsushi, tomllib


class MissingFile:
def __init__(self, path: Path):
self.path = path


DATA_DIR = Path(__file__).parent / "data"

VALID_FILES = tuple((DATA_DIR / "valid").glob("**/*.toml"))
Expand All @@ -22,10 +16,7 @@ def __init__(self, path: Path):
_expected_files = []
for p in VALID_FILES:
json_path = p.with_suffix(".json")
try:
text = json.loads(json_path.read_bytes().decode())
except FileNotFoundError:
text = MissingFile(json_path)
text = json.loads(json_path.read_bytes().decode())
_expected_files.append(text)
VALID_FILES_EXPECTED = tuple(_expected_files)

Expand All @@ -49,14 +40,6 @@ def test_invalid(self):
def test_valid(self):
for valid, expected in zip(VALID_FILES, VALID_FILES_EXPECTED):
with self.subTest(msg=valid.stem):
if isinstance(expected, MissingFile):
# For a poor man's xfail, assert that this is one of the
# test cases where expected data is known to be missing.
assert valid.stem in {
"qa-array-inline-nested-1000",
"qa-table-inline-nested-1000",
}
continue
toml_str = valid.read_bytes().decode()
actual = tomllib.loads(toml_str)
actual = burntsushi.convert(actual)
Expand Down
46 changes: 23 additions & 23 deletions Lib/tomllib/_parser.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -18,40 +18,40 @@
TYPE_CHECKING = False
if TYPE_CHECKING:
from collections.abc import Iterable
from typing import IO, Any
from typing import IO, Any, Final

from ._types import Key, ParseFloat, Pos

ASCII_CTRL = frozenset(chr(i) for i in range(32)) | frozenset(chr(127))
ASCII_CTRL: Final = frozenset(chr(i) for i in range(32)) | frozenset(chr(127))

# Neither of these sets include quotation mark or backslash. They are
# currently handled as separate cases in the parser functions.
ILLEGAL_BASIC_STR_CHARS = ASCII_CTRL - frozenset("\t")
ILLEGAL_MULTILINE_BASIC_STR_CHARS = ASCII_CTRL - frozenset("\t\n")
ILLEGAL_BASIC_STR_CHARS: Final = ASCII_CTRL - frozenset("\t")
ILLEGAL_MULTILINE_BASIC_STR_CHARS: Final = ASCII_CTRL - frozenset("\t\n")

ILLEGAL_LITERAL_STR_CHARS = ILLEGAL_BASIC_STR_CHARS
ILLEGAL_MULTILINE_LITERAL_STR_CHARS = ILLEGAL_MULTILINE_BASIC_STR_CHARS
ILLEGAL_LITERAL_STR_CHARS: Final = ILLEGAL_BASIC_STR_CHARS
ILLEGAL_MULTILINE_LITERAL_STR_CHARS: Final = ILLEGAL_MULTILINE_BASIC_STR_CHARS

ILLEGAL_COMMENT_CHARS = ILLEGAL_BASIC_STR_CHARS
ILLEGAL_COMMENT_CHARS: Final = ILLEGAL_BASIC_STR_CHARS

TOML_WS = frozenset(" \t")
TOML_WS_AND_NEWLINE = TOML_WS | frozenset("\n")
BARE_KEY_CHARS = frozenset(
TOML_WS: Final = frozenset(" \t")
TOML_WS_AND_NEWLINE: Final = TOML_WS | frozenset("\n")
BARE_KEY_CHARS: Final = frozenset(
"abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789" "-_"
)
KEY_INITIAL_CHARS = BARE_KEY_CHARS | frozenset("\"'")
HEXDIGIT_CHARS = frozenset("abcdef" "ABCDEF" "0123456789")
KEY_INITIAL_CHARS: Final = BARE_KEY_CHARS | frozenset("\"'")
HEXDIGIT_CHARS: Final = frozenset("abcdef" "ABCDEF" "0123456789")

BASIC_STR_ESCAPE_REPLACEMENTS = MappingProxyType(
BASIC_STR_ESCAPE_REPLACEMENTS: Final = MappingProxyType(
{
"\\b": "\u0008", # backspace
"\\t": "\u0009", # tab
"\\n": "\u000A", # linefeed
"\\f": "\u000C", # form feed
"\\r": "\u000D", # carriage return
"\\n": "\u000a", # linefeed
"\\f": "\u000c", # form feed
"\\r": "\u000d", # carriage return
"\\e": "\u001b", # escape
'\\"': "\u0022", # quote
"\\\\": "\u005C", # backslash
"\\\\": "\u005c", # backslash
}
)

Expand Down Expand Up @@ -134,7 +134,7 @@ def load(fp: IO[bytes], /, *, parse_float: ParseFloat = float) -> dict[str, Any]
return loads(s, parse_float=parse_float)


def loads(s: str, /, *, parse_float: ParseFloat = float) -> dict[str, Any]: # noqa: C901
def loads(s: str, /, *, parse_float: ParseFloat = float) -> dict[str, Any]:
"""Parse TOML from a string."""

# The spec allows converting "\r\n" to "\n", even in string
Expand Down Expand Up @@ -209,10 +209,10 @@ class Flags:
"""Flags that map to parsed keys/namespaces."""

# Marks an immutable namespace (inline array or inline table).
FROZEN = 0
FROZEN: Final = 0
# Marks a nest that has been explicitly created and can no longer
# be opened using the "[table]" syntax.
EXPLICIT_NEST = 1
EXPLICIT_NEST: Final = 1

def __init__(self) -> None:
self._flags: dict[str, dict[Any, Any]] = {}
Expand Down Expand Up @@ -258,8 +258,8 @@ def is_(self, key: Key, flag: int) -> bool:
cont = inner_cont["nested"]
key_stem = key[-1]
if key_stem in cont:
cont = cont[key_stem]
return flag in cont["flags"] or flag in cont["recursive_flags"]
inner_cont = cont[key_stem]
return flag in inner_cont["flags"] or flag in inner_cont["recursive_flags"]
return False


Expand Down Expand Up @@ -665,7 +665,7 @@ def parse_basic_str(src: str, pos: Pos, *, multiline: bool) -> tuple[Pos, str]:
pos += 1


def parse_value( # noqa: C901
def parse_value(
src: str, pos: Pos, parse_float: ParseFloat
) -> tuple[Pos, Any]:
try:
Expand Down
10 changes: 5 additions & 5 deletions Lib/tomllib/_re.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@

TYPE_CHECKING = False
if TYPE_CHECKING:
from typing import Any
from typing import Any, Final

from ._types import ParseFloat

_TIME_RE_STR = r"""
_TIME_RE_STR: Final = r"""
([01][0-9]|2[0-3]) # hours
:([0-5][0-9]) # minutes
(?:
Expand All @@ -23,7 +23,7 @@
)?
"""

RE_NUMBER = re.compile(
RE_NUMBER: Final = re.compile(
r"""
0
(?:
Expand All @@ -42,8 +42,8 @@
""",
flags=re.VERBOSE,
)
RE_LOCALTIME = re.compile(_TIME_RE_STR, flags=re.VERBOSE)
RE_DATETIME = re.compile(
RE_LOCALTIME: Final = re.compile(_TIME_RE_STR, flags=re.VERBOSE)
RE_DATETIME: Final = re.compile(
rf"""
([0-9]{{4}})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01]) # date, e.g. 1988-10-27
(?:
Expand Down

Back | FazBrowse Home | New Git URL