diff --git a/lib/ts_utils/utils.py b/lib/ts_utils/utils.py index 94936cd92057..bf87def015bf 100644 --- a/lib/ts_utils/utils.py +++ b/lib/ts_utils/utils.py @@ -35,6 +35,16 @@ def strip_comments(text: str) -> str: return text.split("#")[0].strip() +def json5_to_json(text: str) -> str: + """Incomplete conversion from JSON5-like input to valid JSON.""" + # Remove full-line // comments only + # (Can not remove inline comments) + text = re.sub(r"(?m)^\s*//.*\n?", "", text) + # Remove trailing commas before } or ] + text = re.sub(r",\s*([}\]])", r"\1", text) + return text + + # ==================================================================== # Printing utilities # ==================================================================== diff --git a/pyrightconfig.stricter.json b/pyrightconfig.stricter.json index c1513a3016ea..7afdcc3eab14 100644 --- a/pyrightconfig.stricter.json +++ b/pyrightconfig.stricter.json @@ -9,16 +9,16 @@ // test cases use a custom pyrightconfig file "**/@tests/test_cases", "stdlib/__main__.pyi", + "stdlib/_tkinter.pyi", "stdlib/distutils/cmd.pyi", "stdlib/distutils/command", "stdlib/distutils/dist.pyi", "stdlib/encodings/__init__.pyi", "stdlib/lib2to3/fixes/*.pyi", "stdlib/numbers.pyi", - "stdlib/_tkinter.pyi", "stdlib/tkinter/__init__.pyi", - "stdlib/tkinter/filedialog.pyi", "stdlib/tkinter/dialog.pyi", + "stdlib/tkinter/filedialog.pyi", "stdlib/tkinter/scrolledtext.pyi", "stdlib/tkinter/tix.pyi", "stdlib/tkinter/ttk.pyi", diff --git a/tests/check_typeshed_structure.py b/tests/check_typeshed_structure.py index a0e905b9974b..dd986b3f3e8b 100755 --- a/tests/check_typeshed_structure.py +++ b/tests/check_typeshed_structure.py @@ -7,15 +7,17 @@ from __future__ import annotations +import json import os import re from pathlib import Path from ts_utils.metadata import read_metadata -from ts_utils.paths import REQUIREMENTS_PATH, STDLIB_PATH, STUBS_PATH, TEST_CASES_DIR, TESTS_DIR, tests_path +from ts_utils.paths import PYRIGHT_CONFIG, REQUIREMENTS_PATH, STDLIB_PATH, STUBS_PATH, TEST_CASES_DIR, TESTS_DIR, tests_path from ts_utils.utils import ( get_all_testcase_directories, get_gitignore_spec, + json5_to_json, parse_requirements, parse_stdlib_versions_file, spec_matches_path, @@ -173,6 +175,19 @@ def check_requirement_pins() -> None: assert str(spec).startswith("=="), msg +def check_pyright_exclude_order() -> None: + """Check that 'exclude' entries in pyrightconfig.stricter.json are sorted alphabetically.""" + text = PYRIGHT_CONFIG.read_text(encoding="utf-8") + text = json5_to_json(text) + data = json.loads(text) + exclude: list[str] = data.get("exclude", []) + + for i in range(len(exclude) - 1): + assert ( + exclude[i].lower() <= exclude[i + 1].lower() + ), f"Entry '{exclude[i]}' should come before '{exclude[i + 1]}' in the {PYRIGHT_CONFIG.name} exclude list" + + if __name__ == "__main__": check_versions_file() check_metadata() @@ -182,3 +197,4 @@ def check_requirement_pins() -> None: check_stubs() check_distutils() check_test_cases() + check_pyright_exclude_order()