diff --git a/mypy_primer/model.py b/mypy_primer/model.py index 0458435..a0b8116 100644 --- a/mypy_primer/model.py +++ b/mypy_primer/model.py @@ -27,6 +27,7 @@ class Project: mypy_cmd: str pyright_cmd: str | None + paths: list[str] | None = None install_cmd: str | None = None deps: list[str] | None = None @@ -55,6 +56,8 @@ def __repr__(self) -> str: result += f", name_override={self.name_override!r}" if self.pyright_cmd: result += f", pyright_cmd={self.pyright_cmd!r}" + if self.paths: + result += f", paths={self.paths!r}" if self.install_cmd: result += f", install_cmd={self.install_cmd!r}" if self.deps: @@ -168,7 +171,7 @@ async def setup(self) -> None: def get_mypy_cmd(self, mypy: str | Path, additional_flags: Sequence[str] = ()) -> str: mypy_cmd = self.mypy_cmd assert "{mypy}" in self.mypy_cmd - mypy_cmd = mypy_cmd.format(mypy=mypy) + mypy_cmd = mypy_cmd.format_map(_FormatMap(mypy=mypy, paths=self.paths)) python_exe = self.venv.python mypy_cmd += f" --python-executable={quote_path(python_exe)}" @@ -250,7 +253,11 @@ def get_pyright_cmd(self, pyright: Path, additional_flags: Sequence[str] = ()) - assert "{pyright}" in pyright_cmd if additional_flags: pyright_cmd += " " + " ".join(additional_flags) - pyright_cmd = pyright_cmd.format(pyright=f"node {pyright}") + + pyright_cmd = pyright_cmd.format_map( + _FormatMap(pyright=f"node {pyright}", paths=self.paths) + ) + return pyright_cmd async def run_pyright( @@ -345,6 +352,21 @@ def from_location(cls, location: str) -> Project: ) +class _FormatMap: + def __init__(self, **map: str | Path | list[str] | None) -> None: + self.map = map + + def __getitem__(self, key: str) -> str | Path: + if key not in self.map: + raise KeyError(key) + value = self.map[key] + if value is None: + raise ValueError(f"Required {key} to be specified") + if isinstance(value, list): + value = " ".join(value) + return value + + @dataclass(frozen=True) class TypeCheckResult: command: str diff --git a/mypy_primer/projects.py b/mypy_primer/projects.py index 1be33bf..3ddb7b3 100644 --- a/mypy_primer/projects.py +++ b/mypy_primer/projects.py @@ -75,7 +75,8 @@ def get_projects() -> list[Project]: Project( location="https://github.com/python/mypy", mypy_cmd="{mypy} --config-file mypy_self_check.ini -p mypy -p mypyc", - pyright_cmd="{pyright} mypy mypyc", + pyright_cmd="{pyright} {paths}", + paths=["mypy", "mypyc"], deps=["pytest", "types-psutil", "types-setuptools", "filelock", "tomli"], expected_mypy_success=True, cost={"mypy": 15, "pyright": 50}, @@ -88,8 +89,9 @@ def get_projects() -> list[Project]: ), Project( location="https://github.com/psf/black", - mypy_cmd="{mypy} src", - pyright_cmd="{pyright} src", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["src"], deps=["aiohttp", "click", "pathspec", "tomli", "platformdirs", "packaging"], expected_mypy_success=True, ), @@ -108,8 +110,9 @@ def get_projects() -> list[Project]: ), Project( location="https://github.com/pandas-dev/pandas", - mypy_cmd="{mypy} pandas", - pyright_cmd="{pyright} pandas", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["pandas"], deps=[ "numpy", "types-python-dateutil", @@ -123,15 +126,17 @@ def get_projects() -> list[Project]: ), Project( location="https://github.com/pycqa/pylint", - mypy_cmd="{mypy} pylint/checkers --ignore-missing-imports", - pyright_cmd="{pyright} pylint/checkers", + mypy_cmd="{mypy} {paths} --ignore-missing-imports", + pyright_cmd="{pyright} {paths}", + paths=["pylint/checkers"], deps=["types-toml"], expected_mypy_success=True, ), Project( location="https://github.com/aio-libs/aiohttp", - mypy_cmd="{mypy} aiohttp", - pyright_cmd="{pyright} aiohttp", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["aiohttp"], deps=["pytest"], install_cmd="AIOHTTP_NO_EXTENSIONS=1 {install} -e .", expected_mypy_success=True, @@ -149,38 +154,43 @@ def get_projects() -> list[Project]: ), Project( location="https://github.com/sphinx-doc/sphinx", - mypy_cmd="{mypy} sphinx", - pyright_cmd="{pyright} sphinx", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["sphinx"], deps=["babel", "docutils-stubs", "types-requests", "packaging", "jinja2"], expected_mypy_success=True, ), Project( location="https://github.com/scikit-learn/scikit-learn", - mypy_cmd="{mypy} sklearn", - pyright_cmd="{pyright} sklearn", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["sklearn"], deps=["joblib", "numpy", "scipy-stubs", "threadpoolctl"], expected_mypy_success=True, cost={"mypy": 15, "pyright": 240}, ), Project( location="https://github.com/pypa/bandersnatch", - mypy_cmd="{mypy} src", - pyright_cmd="{pyright} src", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["src"], deps=["types-filelock", "types-freezegun", "types-setuptools"], expected_mypy_success=True, ), Project( location="https://github.com/hauntsaninja/boostedblob", - mypy_cmd="{mypy} boostedblob", - pyright_cmd="{pyright} boostedblob", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["boostedblob"], deps=["aiohttp", "uvloop", "pycryptodome"], expected_mypy_success=True, supported_platforms=["linux", "darwin"], ), Project( location="https://github.com/quora/asynq", - mypy_cmd="{mypy} asynq", - pyright_cmd="{pyright} asynq", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["asynq"], deps=["qcore"], expected_mypy_success=True, ), @@ -193,15 +203,17 @@ def get_projects() -> list[Project]: ), Project( location="https://github.com/pypa/twine", - mypy_cmd="{mypy} twine", - pyright_cmd="{pyright} twine", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["twine"], deps=["keyring", "types-requests", "rich"], expected_mypy_success=True, ), Project( location="https://github.com/more-itertools/more-itertools", - mypy_cmd="{mypy} more_itertools", - pyright_cmd="{pyright} more_itertools", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["more_itertools"], expected_mypy_success=True, ), Project( @@ -246,8 +258,9 @@ def get_projects() -> list[Project]: ), Project( location="https://github.com/mystor/git-revise", - mypy_cmd="{mypy} gitrevise", - pyright_cmd="{pyright} gitrevise", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["gitrevise"], expected_mypy_success=True, ), Project( @@ -259,8 +272,9 @@ def get_projects() -> list[Project]: ), Project( location="https://github.com/we-like-parsers/pegen", - mypy_cmd="{mypy} src/pegen", - pyright_cmd="{pyright} src/pegen", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["src/pegen"], expected_mypy_success=True, ), Project( @@ -297,8 +311,9 @@ def get_projects() -> list[Project]: ), Project( location="https://github.com/yelp/paasta", - mypy_cmd="{mypy} paasta_tools", - pyright_cmd="{pyright} paasta_tools", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["paasta_tools"], deps=[ "types-retry", "types-tzlocal", @@ -359,21 +374,24 @@ def get_projects() -> list[Project]: ), Project( location="https://github.com/pycqa/isort", - mypy_cmd="{mypy} --ignore-missing-imports isort", - pyright_cmd="{pyright} isort", + mypy_cmd="{mypy} --ignore-missing-imports {paths}", + pyright_cmd="{pyright} {paths}", + paths=["isort"], deps=["types-setuptools"], expected_mypy_success=True, ), Project( location="https://github.com/aio-libs/aioredis", - mypy_cmd="{mypy} aioredis --ignore-missing-imports", - pyright_cmd="{pyright} aioredis", + mypy_cmd="{mypy} {paths} --ignore-missing-imports", + pyright_cmd="{pyright} {paths}", + paths=["aioredis"], expected_mypy_success=True, ), Project( location="https://github.com/agronholm/anyio", - mypy_cmd="{mypy} src", - pyright_cmd="{pyright} src", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["src"], expected_mypy_success=True, ), Project( @@ -404,16 +422,18 @@ def get_projects() -> list[Project]: ), Project( location="https://github.com/google/jax", - mypy_cmd="{mypy} jax", - pyright_cmd="{pyright} jax", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["jax"], deps=["ml_dtypes", "numpy", "scipy-stubs", "types-requests"], expected_mypy_success=True, cost={"mypy": 30, "pyright": 90}, ), Project( location="https://github.com/dulwich/dulwich", - mypy_cmd="{mypy} dulwich", - pyright_cmd="{pyright} dulwich", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["dulwich"], deps=["types-certifi", "types-paramiko"], expected_mypy_success=True, ), @@ -445,8 +465,9 @@ def get_projects() -> list[Project]: ), Project( location="https://github.com/aiortc/aiortc", - mypy_cmd="{mypy} src", - pyright_cmd="{pyright} src", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["src"], deps=["cryptography"], expected_mypy_success=True, ), @@ -467,16 +488,18 @@ def get_projects() -> list[Project]: ), Project( location="https://github.com/schemathesis/schemathesis", - mypy_cmd="{mypy} src/schemathesis", - pyright_cmd="{pyright} src/schemathesis", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["src/schemathesis"], deps=["attrs", "types-requests", "types-PyYAML", "hypothesis"], expected_mypy_success=True, supported_platforms=["linux", "darwin"], ), Project( location="https://github.com/graphql-python/graphql-core", - mypy_cmd="{mypy} src tests", - pyright_cmd="{pyright} src tests", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["src", "tests"], expected_mypy_success=True, cost={"mypy": 40}, ), @@ -489,8 +512,9 @@ def get_projects() -> list[Project]: ), Project( location="https://github.com/niklasf/python-chess", - mypy_cmd="{mypy} --strict chess", - pyright_cmd="{pyright} chess", + mypy_cmd="{mypy} --strict {paths}", + pyright_cmd="{pyright} {paths}", + paths=["chess"], expected_mypy_success=True, ), Project( @@ -510,8 +534,9 @@ def get_projects() -> list[Project]: ), Project( location="https://github.com/pypa/packaging", - mypy_cmd="{mypy} src", - pyright_cmd="{pyright} src", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["src"], expected_mypy_success=True, ), Project( @@ -555,15 +580,17 @@ def get_projects() -> list[Project]: ), Project( location="https://github.com/davidhalter/parso", - mypy_cmd="{mypy} parso", - pyright_cmd="{pyright} parso", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["parso"], expected_mypy_success=True, cost={"pyright": 75}, ), Project( location="https://github.com/konradhalas/dacite", - mypy_cmd="{mypy} dacite", - pyright_cmd="{pyright} dacite", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["dacite"], expected_mypy_success=True, ), Project( @@ -587,29 +614,33 @@ def get_projects() -> list[Project]: ), Project( location="https://github.com/jpadilla/pyjwt", - mypy_cmd="{mypy} jwt", - pyright_cmd="{pyright} jwt", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["jwt"], deps=["cryptography"], expected_mypy_success=True, ), Project( location="https://github.com/apache/spark", mypy_cmd="{mypy} --config python/mypy.ini python/pyspark", - pyright_cmd="{pyright} python/pyspark", + pyright_cmd="{pyright} {paths}", + paths=["python/pyspark"], deps=["numpy"], expected_mypy_success=True, cost={"mypy": 20, "pyright": 110}, ), Project( location="https://github.com/laowantong/paroxython", - mypy_cmd="{mypy} paroxython", - pyright_cmd="{pyright} paroxython", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["paroxython"], expected_mypy_success=True, ), Project( location="https://github.com/Akuli/porcupine", - mypy_cmd="{mypy} --config-file= porcupine", - pyright_cmd="{pyright} porcupine", + mypy_cmd="{mypy} --config-file= {paths}", + pyright_cmd="{pyright} {paths}", + paths=["porcupine"], expected_mypy_success=True, ), Project( @@ -652,8 +683,9 @@ def get_projects() -> list[Project]: ), Project( location="https://github.com/wntrblm/nox", - mypy_cmd="{mypy} nox", - pyright_cmd="{pyright} nox", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["nox"], deps=[ "jinja2", "packaging", @@ -695,8 +727,9 @@ def get_projects() -> list[Project]: ), Project( location="https://github.com/python-jsonschema/check-jsonschema", - mypy_cmd="{mypy} src", - pyright_cmd="{pyright} src", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["src"], deps=["types-jsonschema", "types-requests"], expected_mypy_success=True, ), @@ -740,8 +773,9 @@ def get_projects() -> list[Project]: ), Project( location="https://github.com/sympy/sympy", - mypy_cmd="{mypy} sympy", - pyright_cmd="{pyright} sympy", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["sympy"], deps=["mpmath"], expected_mypy_success=True, cost={"mypy": 35, "pyright": 240}, @@ -754,15 +788,17 @@ def get_projects() -> list[Project]: ), Project( location="https://github.com/PyCQA/flake8-pyi", - mypy_cmd="{mypy} pyi.py", - pyright_cmd="{pyright} pyi.py", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["pyi.py"], deps=["types-pyflakes"], expected_mypy_success=True, ), Project( location="https://github.com/internetarchive/openlibrary", - mypy_cmd="{mypy} openlibrary", - pyright_cmd="{pyright} openlibrary", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["openlibrary"], deps=[ "types-PyYAML", "types-python-dateutil", @@ -877,8 +913,9 @@ def get_projects() -> list[Project]: ), Project( location="https://github.com/home-assistant/core", - mypy_cmd="{mypy} homeassistant", - pyright_cmd="{pyright} homeassistant", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["homeassistant"], deps=[ "attrs", "pydantic", @@ -896,13 +933,15 @@ def get_projects() -> list[Project]: ), Project( location="https://github.com/kornia/kornia", - mypy_cmd="{mypy} kornia", - pyright_cmd="{pyright} kornia", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["kornia"], ), Project( location="https://github.com/ibis-project/ibis", - mypy_cmd="{mypy} --ignore-missing-imports ibis", - pyright_cmd="{pyright} ibis", + mypy_cmd="{mypy} --ignore-missing-imports {paths}", + pyright_cmd="{pyright} {paths}", + paths=["ibis"], deps=[ "SQLAlchemy", "numpy", @@ -938,8 +977,9 @@ def get_projects() -> list[Project]: ), Project( location="https://github.com/dragonchain/dragonchain", - mypy_cmd="{mypy} dragonchain --error-summary", - pyright_cmd="{pyright} dragonchain", + mypy_cmd="{mypy} {paths} --error-summary", + pyright_cmd="{pyright} {paths}", + paths=["dragonchain"], deps=["types-redis", "types-requests"], ), Project( @@ -1042,8 +1082,9 @@ def get_projects() -> list[Project]: ), Project( location="https://gitlab.com/dkg/python-sop", - mypy_cmd="{mypy} --strict sop", - pyright_cmd="{pyright} sop", + mypy_cmd="{mypy} --strict {paths}", + pyright_cmd="{pyright} {paths}", + paths=["sop"], ), Project( location="https://github.com/Rapptz/discord.py", @@ -1130,8 +1171,9 @@ def get_projects() -> list[Project]: ), Project( location="https://github.com/pyodide/pyodide", - mypy_cmd="{mypy} src pyodide-build --exclude 'setup.py|^src/tests|conftest.py'", - pyright_cmd="{pyright} src pyodide-build", + mypy_cmd="{mypy} {paths} --exclude 'setup.py|^src/tests|conftest.py'", + pyright_cmd="{pyright} {paths}", + paths=["src", "pyodide-build"], deps=[ "packaging", "types-docutils", @@ -1181,8 +1223,9 @@ def get_projects() -> list[Project]: ), Project( location="https://github.com/Toufool/AutoSplit", - mypy_cmd="{mypy} src", - pyright_cmd="{pyright} src", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["src"], deps=[ "certifi", "ImageHash", @@ -1249,8 +1292,9 @@ def get_projects() -> list[Project]: ), Project( location="https://github.com/python-trio/trio", - mypy_cmd="{mypy} src/trio", - pyright_cmd="{pyright} src/trio", + mypy_cmd="{mypy} {paths}", + pyright_cmd="{pyright} {paths}", + paths=["src/trio"], deps=[ "types-pyOpenSSL", "types-cffi",