# Generates mplex_foundation_cases.inc: expected values for mplex_foundation_test.cpp, produced by # the real CPython (run with the same python3 -I that the repo targets, TZ=UTC). # Usage: TZ=UTC python3 -I mplex_foundation_gen.py > mplex_foundation_cases.inc import fnmatch import json import math import os import random import re import shlex import sys import textwrap import time import tomllib import datetime os.environ["TZ"] = "UTC" time.tzset() def lit(text): data = text if isinstance(text, bytes) else text.encode("utf-8", "surrogatepass") out = ['"'] for b in data: ch = chr(b) if 32 <= b < 127 and ch not in '"\\?': out.append(ch) else: out.append("\\%03o" % b) out.append('"sv') return "".join(out) def emit(suite, *args): parts = ", ".join(lit(a) if isinstance(a, (str, bytes)) else lit(str(a)) for a in args) print("{%s, {%s}}," % (lit(suite), parts)) def lst(items): return "%d:" % len(items) + "\x1e".join(items) random.seed(20251025) TEXTS = ["", " ", "abc", " abc ", "\tab\n", "ÀÉîõü", "ß", "straße", "ΑΣ", "ΑΣ.Β", "ΑΣ Β", "Σ", "aΣ", "İstanbul", "Dž", "ffi", "Lj", "日本語 テキスト", "a b", "x y
z", "\x1c\x1d\x1e\x1f", "a\x85b", "😀 emoji", "ͅ", "ʼn", "ΐ", "ẞ", "tab\there", "line1\nline2\r\nline3\rline4\x0bline5\x0cline6", "a,b, c ,,d", " lead", "trail ", "é"] for t in TEXTS: emit("lower", t, t.lower()) emit("upper", t, t.upper()) emit("strip", t, t.strip()) emit("rstrip", t, t.rstrip()) emit("split_ws", t, lst(t.split())) emit("splitlines", t, lst(t.splitlines())) emit("len", t, len(t)) emit("repr", t, repr(t)) for a, b in [(0, 2), (1, 100), (-2, 100), (-100, 1), (2, 1), (-3, -1), (0, -1)]: emit("slice", t, a, b, t[a:b]) emit("ljust", t, 5, t.ljust(5)) emit("ljust", t, 40, t.ljust(40)) for t, ch in [("xxabcxx", "x"), (" abc ", " "), ("éabcé", "é"), ("abc", ""), ("--a--", "-+"), ("", "x")]: emit("strip_chars", t, ch, t.strip(ch)) emit("lstrip_chars", t, ch, t.lstrip(ch)) emit("rstrip_chars", t, ch, t.rstrip(ch)) for t, sep, mx in [("a,b,c", ",", -1), ("a,b,c", ",", 1), (",a,", ",", -1), ("abc", ",", -1), ("", ",", -1), ("a--b--c", "--", -1), ("a--b--c", "--", 1), ("é,é", ",", -1), ("a,b,c,d", ",", 2), ("aaa", "aa", -1), (",,", ",", -1)]: emit("split", t, sep, mx, lst(t.split(sep, mx))) emit("rsplit", t, sep, mx, lst(t.rsplit(sep, mx))) for t, a, b in [("hello world", "o", "0"), ("aaa", "a", "bb"), ("abc", "", "-"), ("", "", "-"), ("éé", "é", "e"), ("abc", "d", "x"), ("aaaa", "aa", "b"), ("x", "x", "")]: emit("replace", t, a, b, t.replace(a, b)) for t in ["foo", "foo bar", "", "a b", "path/to file", "it's", "x=1", "a@b%c+d:e,f./-", "$HOME", "é", "a\nb", "'", "~", "*", "tab\t"]: emit("shlex_quote", t, shlex.quote(t)) # predicates over code points: a deterministic sample incl. block boundaries cps = set(range(0, 0x300)) | set(random.sample(range(0x300, 0x110000), 6000)) cps |= {0x1680, 0x2000, 0x200a, 0x2028, 0x2029, 0x202f, 0x205f, 0x3000, 0x85, 0xa0, 0x1c, 0x1f, 0xad, 0x600, 0x2060, 0xfeff, 0xe000, 0xf8ff, 0x10ffff, 0x10fffd, 0xd7ff, 0xe0001, 0x1d7ce, 0x1d7ff, 0x0660, 0x0669, 0x00b2, 0x00bd, 0x2155, 0x3007, 0x1f600, 0x16fe4, 0x2ffff, 0x30000} for cp in sorted(cps): if 0xD800 <= cp <= 0xDFFF: continue ch = chr(cp) flags = "".join("1" if f else "0" for f in (ch.isalpha(), ch.isdigit(), ch.isalnum(), ch.isspace(), ch.isprintable())) emit("pred", cp, flags, ch.lower(), ch.upper()) INTS = ["0", "12", "-5", "+7", " 42 ", "1_000", "1__0", "_1", "1_", "0x10", "", " ", "-", "+", "1.5", "abc", "٣٤", "-٣", "007", "9223372036854775807", "-9223372036854775808", "1 2", "1e5", "²", "\t9\n"] for t in INTS: try: v = int(t) emit("int", t, "1", str(v) if -(2 ** 63) <= v < 2 ** 63 else "BIG") except ValueError as e: emit("int", t, "0", str(e)) FLOATS = ["1", "1.5", "-2.5e3", "+.5", "5.", ".", "", "1e", "e5", "inf", "-Infinity", "NaN", "+nan", " 3.25 ", "1_0.5", "1__0", "_1.0", "1.5_", "0x1p3", "1,5", "abc", "1e400", "-1e-400", "١.٢", "infinit", "1_0e1_0", "1.e5", "0.1", "123456789012345678"] for t in FLOATS: try: v = float(t) emit("float", t, "1", "nan" if math.isnan(v) else repr(v)) except ValueError as e: emit("float", t, "0", str(e)) for v in [0.0, -0.0, 1.0, 1.5, 0.1, 1e16, 1e15, 123456789012345678.0, 1e-4, 1e-5, 1.5e-7, 5e-324, 1.7976931348623157e308, 100.0, 12345.678, 0.30000000000000004, 1e22, 1e23, 2.5e-10, 1234567890123456.0, 12345678901234567.0, -3.14159, float("inf"), float("-inf"), float("nan"), 9007199254740993.0, 0.00001234, 0.0001234]: emit("format_float", float.hex(v), "nan" if math.isnan(v) else repr(v)) # textwrap WRAP_TEXTS = ["", "hello", "Hello there -- you goof-ball, use the -b option!", "a" * 50, "word " * 30, "one two three\tfour\nfive", "e-mail me at foo-bar-baz.com or x--y or well-known-fact", "éè ê" * 10, "para one\n\npara two is a little longer than the first", " leading and trailing ", "supercalifragilisticexpialidocious and short", "a-b-c-d-e-f-g-h", "x - y -- z --- w", "tabs\tand\ttabs\tmore\ttabs\tand\ttabs", "12-34-56-78 90-12", "foo-éar-bar", "hyphen-ated-long-word-that-goes-on-and-on-and-on-forever", "a b c d " * 6, "-- leading dashes", "trailing dashes --", "ab-cd-ef", "snake_case_word-with-hyphen", "end.\nNew sentence."] for t in WRAP_TEXTS: for w in (1, 2, 3, 5, 8, 10, 20, 40, 70): emit("wrap", t, w, lst(textwrap.wrap(t, w))) emit("wrap_bad", "x", 0, "ValueError: invalid width 0 (must be > 0)") # fnmatch PATS = [("foo.txt", "*.txt"), ("foo.txt", "f?o.*"), ("foo", "f[o]o"), ("foo", "f[!o]o"), ("fxo", "f[!o]o"), ("a-b", "a[-]b"), ("a]b", "a[]]b"), ("abc", "[a-c][a-c][a-c]"), ("abd", "[a-c][a-c][a-c]"), ("", "*"), ("", "?"), ("a", "[]"), ("[", "["), ("ab[", "ab["), ("x*y", "x[*]y"), ("a\nb", "a*b"), ("A", "a"), ("main", "ma*n"), ("mainn", "ma*n"), ("a/b", "*"), ("abc", "a**c"), ("a^b", "a[^]b"), ("axb", "a[^x]b"), ("a\\b", "a[\\]b"), ("a&b", "a[&]b"), ("a|b", "a[|]b"), ("a~b", "a[~]b"), ("z", "[z-a]"), ("m", "[a-z&&b]"), ("-", "[a-]"), ("a", "[a-]"), ("b", "[a-c-e]"), ("d", "[a-c-e]"), ("e", "[a-c-e]"), ("é", "[à-ÿ]"), ("été", "?t?"), ("5", "[0-9]"), ("a", "[!a-z]"), ("1", "[!a-z]"), ("!", "[!]]"), ("]", "[!]]"), ("a]", "[!]]]"), ("x", "[!]"), ("abc", "*b*"), ("abc", "*d*"), ("aXb", "a?b"), ("ab", "a?b"), ("window-1", "window-*"), ("1", "[0-9]*"), ("session", "sess*ion"), ("a", "[a-a]"), ("b", "[b-a]")] for name, pat in PATS: emit("fnmatch", name, pat, "1" if fnmatch.fnmatchcase(name, pat) else "0") # os.path for p in ["", "/", "a", "a/b", "/a/b", "/a/b/", "//a//b", "a//", "///", "../x", "x/", "é/è"]: emit("basename", p, os.path.basename(p)) emit("dirname", p, os.path.dirname(p)) for a, b in [("", ""), ("a", "b"), ("a/", "b"), ("a", "/b"), ("", "b"), ("a", ""), ("/", "x"), ("a//", "b")]: emit("join_path", a, b, os.path.join(a, b)) os.environ["HOME"] = "/home/tester/" for p in ["~", "~/x", "~/", "x", "", "~nonexistentuser12345/x", "~root", "~root/y", "/~/x"]: emit("expanduser", p, os.path.expanduser(p)) # strftime (TZ=UTC) for fmt in ["%Y-%m-%d %H:%M:%S", "%H:%M", "%a %b %d %H:%M:%S %Y", "%d-%b-%y", "%I:%M%p", "%%", "plain", "", "%j %U %w", "%e|%k|%l", "[%Z]", "%s"]: for stamp in (0, 86399, 1700000000, 1234567890.75, 951782400): emit("strftime", fmt, repr(float(stamp)), time.strftime(fmt, time.localtime(stamp))) # regex RE_CASES = [ (r"a*", "baaac"), (r"x|", "axb"), (r"\w+", "hi there"), (r"b*?", "abb"), (r"", "abc"), (r"^a", "aa"), (r"a$", "a\n"), (r"a$", "ba"), (r"(\d+)-(\d+)", "10-20 30-40"), (r"[a-c]+", "xxabcabcxx"), (r"foo", "FOO foo"), (r"o+?", "foooo"), (r"(a)|(b)", "ab"), (r"a{2,3}", "aaaaa"), (r"a{,2}", "aaa"), (r"a{2}", "aaa"), (r"{", "a{b"), (r"a{", "a{"), (r"a{x}", "a{x}"), (r"}", "a}b"), (r"[]a]", "]a"), (r"[^]a]", "]ab"), (r"[a\]]", "]"), (r"\.", "a.b"), (r"\bfoo\b", "a foo b"), (r"\Bo", "foo"), (r"(?:ab)+", "ababab"), (r"a(?=b)", "ab ac"), (r"a(?!b)", "ab ac"), (r"(?Pa)(?P=x)", "aa"), (r"(a)\1", "aa"), (r".", "\n\r"), (r".+", "ab\ncd"), (r"\s+", "a \t b"), (r"\d+", "a٣٤b"), (r"[\d]+", "٣x"), (r"\S+", "ab cd"), (r"\W+", "a-- b"), (r"\x41", "A"), (r"é", "é"), (r"[\x41-\x43]+", "ABCD"), (r"\a", "\x07"), (r"[\b]", "\x08"), (r"\0", "\x00"), (r"\101", "A"), (r"\Aab", "ab"), (r"ab\Z", "ab"), (r"ab\Z", "ab\n"), (r"[[]", "["), (r"[a[]", "["), (r"\/", "/"), (r"\-", "-"), (r"[\-a]", "-"), (r"\ ", " "), (r"\#", "#"), (r"x*", ""), (r"x*", "xx"), (r"(a*)*", "aa"), (r"a|ab", "ab"), (r"(?#comment)a", "a"), (r"é+", "éé"), (r"\w+", "héllo"), (r"[^a]", "ab"), (r"a.c", "abc"), (r"(?i)abc", "ABC"), (r"(?iu)abc", "aBc"), (r"a+|b", "caab"), (r"^", "ab"), (r"$", "ab"), (r"$", "ab\n"), (r"\b", "ab cd"), (r"x?", "xaxx"), (r"(x)?y", "y xy"), (r"[a-z]*", "ab12cd"), ] for pat, text in RE_CASES: try: rx = re.compile(pat) except re.error: emit("re_err", pat, "") continue m = rx.search(text) emit("re_search", pat, text, "none" if not m else "%d,%d" % m.span()) for frm in (1, 2): m = rx.search(text, frm) emit("re_search_from", pat, text, frm, "none" if not m else "%d,%d" % m.span()) emit("re_finditer", pat, text, lst(["%d,%d" % m.span() for m in rx.finditer(text)])) for rep in ["<\\g<0>>", "-", "[\\1]" if rx.groups >= 1 else "!", "\\n", "\\\\", "\\g<1>\\g<1>" if rx.groups >= 1 else "x"]: try: emit("re_sub", pat, text, rep, rx.sub(rep, text)) except re.error as e: emit("re_sub_err", pat, text, rep, "") emit("re_ic", "abc", "xABCx", "1,4") for pat in [r"(?<=a)b", r"(?a)", r"(?i:a)", r"a(?i)b", r"(", r")", r"[", r"\p", r"\N{DASH}", r"(?P