Skip to content
19 changes: 19 additions & 0 deletions Lib/test/test_tomllib/test_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
from pathlib import Path
import sys
import tempfile
import textwrap
import unittest
from test import support
from test.support.script_helper import assert_python_ok

from . import tomllib

Expand Down Expand Up @@ -124,3 +126,20 @@ def test_types_import(self):
never imported by tests.
"""
importlib.import_module(f"{tomllib.__name__}._types")

def test_lazy_import(self):
# Test the TOML file can be parsed without importing regular
# expressions (tomllib._re)
code = textwrap.dedent("""
import sys, tomllib, textwrap
document = textwrap.dedent('''
[metadata]
key = "text"
array = ["array", "of", "text"]
booleans = [true, false]
''')
tomllib.loads(document)
print("lazy import?", 'tomllib._re' not in sys.modules)
""")
proc = assert_python_ok("-c", code)
self.assertIn(b"lazy import? True", proc.out)
6 changes: 4 additions & 2 deletions Lib/tomllib/_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

from __future__ import annotations

from types import MappingProxyType
# Defer loading regular expressions until we actually need them in
# parse_value().
__lazy_modules__ = ["tomllib._re"]

from ._re import (
Comment thread
vstinner marked this conversation as resolved.
RE_DATETIME,
Expand Down Expand Up @@ -42,7 +44,7 @@
KEY_INITIAL_CHARS: Final = BARE_KEY_CHARS | frozenset("\"'")
HEXDIGIT_CHARS: Final = frozenset("abcdef" "ABCDEF" "0123456789")

BASIC_STR_ESCAPE_REPLACEMENTS: Final = MappingProxyType(
BASIC_STR_ESCAPE_REPLACEMENTS: Final = frozendict( # type: ignore[name-defined]
{
"\\b": "\u0008", # backspace
"\\t": "\u0009", # tab
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Improve :mod:`tomllib` import time (up to 10x faster). Patch by Victor
Stinner.
Loading