Files
typeshed/tests/stubtest_stdlib.py
Akuli 24afb531ff stubtest_stdlib: get rid of --ignore-missing-stub (#6491)
* get rid of --ignore-missing-stub

* update allowlists based on github actions logs, with script

import re

platforms = ["linux", "win32", "darwin"]
versions = ["py36", "py37", "py38", "py39", "py310"]

entries_by_pv = {}
for p in platforms:
    for v in versions:
        p_name = {"linux": "ubuntu", "darwin": "macos", "win32": "windows"}[p]
        v_name = "3." + v.replace("py3", "")
        if v_name == "3.9":
            v_name = "3.9.7"

        entries = set()
        with open(f"la/Check stdlib with stubtest ({p_name}-latest, {v_name})/6_Run stubtest.txt") as file:
            for line in file:
                m = re.search(r"error: (.*) is not present in stub$", line.strip())
                if m:
                    entries.add(m.group(1))
        entries_by_pv[p, v] = entries

def remove_intersection(sets):
    sets = list(sets)
    result = set(sets[0])
    for s in sets[1:]:
        result &= s
    for s in sets:
        for r in result:
            s.remove(r)
    return result

common_to_all = remove_intersection(entries_by_pv.values())

common_to_version = {}
for v in versions:
    common_to_version[v] = remove_intersection([
        entries
        for (p, v2), entries in entries_by_pv.items()
        if v == v2
    ])

common_to_platform = {}
for p in platforms:
    common_to_platform[p] = remove_intersection([
        entries
        for (p2, v), entries in entries_by_pv.items()
        if p == p2
    ])

def write(fname, entries):
    with open(f"tests/stubtest_allowlists/{fname}.txt", "a") as file:
        file.write("\n# Exists at runtime, but missing from stubs\n")
        for i in sorted(entries):
            file.write(i + "\n")

write("py3_common", common_to_all)
for v, entries in common_to_version.items():
    write(v, entries)
for p, entries in common_to_platform.items():
    write(p, entries)
for (p, v), entries in entries_by_pv.items():
    write(p + "-" + v, entries)

* Manually combine __main__ attributes into a single entry

* move and comment entries manually
2021-12-04 16:58:44 -08:00

66 lines
2.5 KiB
Python
Executable File

#!/usr/bin/env python3
"""Test typeshed's stdlib using stubtest
stubtest is a script in the mypy project that compares stubs to the actual objects at runtime.
Note that therefore the output of stubtest depends on which Python version it is run with.
In typeshed CI, we run stubtest with each currently supported Python minor version, except 2.7.
"""
import subprocess
import sys
from pathlib import Path
def run_stubtest(typeshed_dir: Path) -> int:
allowlist_dir = typeshed_dir / "tests" / "stubtest_allowlists"
version_allowlist = "py{}{}.txt".format(sys.version_info.major, sys.version_info.minor)
platform_allowlist = "{}.txt".format(sys.platform)
combined_allowlist = "{}-py{}{}.txt".format(sys.platform, sys.version_info.major, sys.version_info.minor)
ignore_unused_allowlist = "--ignore-unused-allowlist" in sys.argv[1:]
cmd = [
sys.executable,
"-m",
"mypy.stubtest",
"--check-typeshed",
"--custom-typeshed-dir",
str(typeshed_dir),
"--allowlist",
str(allowlist_dir / "py3_common.txt"),
"--allowlist",
str(allowlist_dir / version_allowlist),
]
if ignore_unused_allowlist:
cmd += ["--ignore-unused-allowlist"]
if (allowlist_dir / platform_allowlist).exists():
cmd += ["--allowlist", str(allowlist_dir / platform_allowlist)]
if (allowlist_dir / combined_allowlist).exists():
cmd += ["--allowlist", str(allowlist_dir / combined_allowlist)]
if sys.version_info < (3, 10):
# As discussed in https://github.com/python/typeshed/issues/3693, we only aim for
# positional-only arg accuracy for the latest Python version.
cmd += ["--ignore-positional-only"]
try:
print(" ".join(cmd), file=sys.stderr)
subprocess.run(cmd, check=True)
except subprocess.CalledProcessError as e:
print(
"\nNB: stubtest output depends on the Python version (and system) it is run with. "
"See README.md for more details.\n"
"NB: We only check positional-only arg accuracy for Python 3.10.\n"
"\nCommand run was: {}\n".format(" ".join(cmd)),
file=sys.stderr,
)
print("\n\n", file=sys.stderr)
print(f'To fix "unused allowlist" errors, remove the corresponding entries from {allowlist_dir}', file=sys.stderr)
return e.returncode
else:
print("stubtest succeeded", file=sys.stderr)
return 0
if __name__ == "__main__":
sys.exit(run_stubtest(typeshed_dir=Path(".")))