Crash report
What happened?
I am seeing intermittent corrupted stdlib re state, impossible exceptions inside re._compiler / re._parser, and occasional hard crashes when many freshly spawned multiprocessing workers re-import the main module and compile many stdlib re patterns during the child __mp_main__ import path.
The issue is most reproducible for me on python:3.12-slim / 3.12.13, failing 5 out of 5 runs. I also observed lower-frequency failures on python:3.13-slim / 3.13.14 and python:3.14-slim / 3.14.6 and with forkserver.
I have not yet reproduced this on a non-WSL Linux host, so WSL remains a possible factor.
Reproducible example
"""Reproduce spawn-time regular-expression import stress.
Spawned or forkserver workers re-import this same file. During that child
import path, the script compiles many generic stdlib ``re`` patterns before
running trivial worker tasks.
"""
from __future__ import annotations
import argparse
import multiprocessing as mp
import re
import sys
import traceback
_STORM_COUNT = 0
def _compile_patterns(pattern_count: int) -> list[re.Pattern[str]]:
quote = r"[\"\u201c\u201d\u2018\u2019\u00ab\u00bb]"
not_quote = r"[^\"\u201c\u201d\u2018\u2019\u00ab\u00bb]"
token = r"[A-Za-z_][A-Za-z0-9_-]*"
number = r"(?:0[xX][0-9a-fA-F]+|\d+(?:\.\d+)?)"
patterns: list[re.Pattern[str]] = []
for index in range(pattern_count):
width = 64 + (index % 192)
word_repeat = 2 + (index % 9)
path_repeat = 1 + (index % 5)
patterns.append(
re.compile(
rf"""
(?:^|[\s,;|])
(?P<key>{token})(?:\s*[:=]\s*|\s+)
(?:
{quote}(?P<quoted>{not_quote}{{1,{width}}}){quote}
| (?P<number>{number})
| (?P<path>(?:[A-Za-z]:)?(?:/[A-Za-z0-9_.-]+){{1,{path_repeat}}})
| (?P<words>(?:{token}[\s./-]?){{1,{word_repeat}}})
)
(?:
\s*(?:and|or|then|with)\s*
(?P<trailer>{not_quote}{{0,{32 + (index % 96)}}})
)?
""",
re.IGNORECASE | re.VERBOSE,
)
)
return patterns
def _pattern_count_from_argv() -> int:
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument("--patterns", type=int, default=220)
args, _unknown = parser.parse_known_args()
return args.patterns
def _run_child_import_storm(pattern_count: int) -> int:
patterns = _compile_patterns(pattern_count)
return len(patterns)
if __name__ == "__mp_main__":
_STORM_COUNT = _run_child_import_storm(_pattern_count_from_argv())
def _task(index: int) -> tuple[int, str, str]:
try:
return index, "ok", str(_STORM_COUNT)
except BaseException:
return index, "error", traceback.format_exc()
def _parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--workers", type=int, default=8)
parser.add_argument("--tasks", type=int, default=300)
parser.add_argument("--max-tasks-per-child", type=int, default=1)
parser.add_argument("--patterns", type=int, default=220)
parser.add_argument("--start-method", choices=("spawn", "forkserver"), default="spawn")
return parser.parse_args()
def main() -> int:
args = _parse_args()
print(f"python={sys.version}", flush=True)
print(
"stress="
f"workers={args.workers} tasks={args.tasks} "
f"max_tasks_per_child={args.max_tasks_per_child} "
f"patterns={args.patterns} "
f"start_method={args.start_method}",
flush=True,
)
max_tasks_per_child = args.max_tasks_per_child if args.max_tasks_per_child > 0 else None
ctx = mp.get_context(args.start_method)
with ctx.Pool(processes=args.workers, maxtasksperchild=max_tasks_per_child) as pool:
for completed, (index, status, payload) in enumerate(pool.imap_unordered(_task, range(args.tasks)), 1):
if status != "ok":
print(f"FAIL task={index}", flush=True)
print(payload, flush=True)
pool.terminate()
return 1
if completed % 50 == 0:
print(f"progress={completed} imported_objects={payload}", flush=True)
print("done", flush=True)
return 0
if __name__ == "__main__":
raise SystemExit(main())
Logs
python:3.12-slim / 3.12.13, spawn, workers=8, tasks=300, patterns=220, max_tasks=1:
failures=5/5
observed:
TypeError: 'range_iterator' object is not subscriptable
TypeError: 'int' object is not subscriptable
TypeError: unhashable type: 'bytearray'
python:3.13-slim / 3.13.14, same command shape:
failures=1/5
observed:
KeyError inside re._compiler._optimize_charset
python:3.14-slim / 3.14.6, same command shape:
failures=1/5
observed:
TypeError: 'bytearray' object is not an iterator
Here is one representative traceback from Python 3.12.13:
python=3.12.13 (main, Jun 11 2026, 01:09:00) [GCC 14.2.0]
stress=workers=8 tasks=300 max_tasks_per_child=1 patterns=220 start_method=spawn
Traceback (most recent call last):
File "/usr/local/lib/python3.12/multiprocessing/spawn.py", line 122, in spawn_main
exitcode = _main(fd, parent_sentinel)
File "/usr/local/lib/python3.12/multiprocessing/spawn.py", line 246, in prepare
_fixup_main_from_path(data['init_main_from_path'])
File "/usr/local/lib/python3.12/multiprocessing/spawn.py", line 297, in _fixup_main_from_path
main_content = runpy.run_path(main_path,
File "/work/spawn_import.py", line 65, in <module>
_STORM_COUNT = _run_child_import_storm(_pattern_count_from_argv())
File "/work/spawn_import.py", line 60, in _run_child_import_storm
patterns = _compile_patterns(pattern_count)
File "/work/spawn_import.py", line 31, in _compile_patterns
re.compile(...)
File "/usr/local/lib/python3.12/re/__init__.py", line 307, in _compile
p = _compiler.compile(pattern, flags)
File "/usr/local/lib/python3.12/re/_compiler.py", line 754, in compile
code = _code(p, flags)
File "/usr/local/lib/python3.12/re/_compiler.py", line 587, in _code
_compile(code, p.data, flags)
File "/usr/local/lib/python3.12/re/_compiler.py", line 86, in _compile
charset, hascased = _optimize_charset(av, iscased, tolower, fixes)
File "/usr/local/lib/python3.12/re/_compiler.py", line 375, in _optimize_charset
chunk = charmap[i: i + 256]
TypeError: 'int' object is not subscriptable
Full logs: logs.zip
CPython versions tested on:
3.12, 3.13, 3.14
Operating systems tested on:
Linux
Output from running 'python -VV' on the command line:
No response
Crash report
What happened?
I am seeing intermittent corrupted stdlib re state, impossible exceptions inside
re._compiler/re._parser, and occasional hard crashes when many freshly spawned multiprocessing workers re-import the main module and compile many stdlib re patterns during the child__mp_main__import path.The issue is most reproducible for me on
python:3.12-slim/ 3.12.13, failing 5 out of 5 runs. I also observed lower-frequency failures on python:3.13-slim / 3.13.14 and python:3.14-slim / 3.14.6 and with forkserver.I have not yet reproduced this on a non-WSL Linux host, so WSL remains a possible factor.
Reproducible example
Logs
Here is one representative traceback from Python 3.12.13:
Full logs: logs.zip
CPython versions tested on:
3.12, 3.13, 3.14
Operating systems tested on:
Linux
Output from running 'python -VV' on the command line:
No response