mirror of
https://github.com/davidhalter/typeshed.git
synced 2026-05-06 21:43:59 +08:00
Add mypy plugin support to stubtest configuration (#13948)
This commit is contained in:
@@ -11,7 +11,7 @@ import urllib.parse
|
||||
from collections.abc import Mapping
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import Annotated, Final, NamedTuple, final
|
||||
from typing import Annotated, Any, Final, NamedTuple, final
|
||||
from typing_extensions import TypeGuard
|
||||
|
||||
import tomli
|
||||
@@ -42,6 +42,10 @@ def _is_list_of_strings(obj: object) -> TypeGuard[list[str]]:
|
||||
return isinstance(obj, list) and all(isinstance(item, str) for item in obj)
|
||||
|
||||
|
||||
def _is_nested_dict(obj: object) -> TypeGuard[dict[str, dict[str, Any]]]:
|
||||
return isinstance(obj, dict) and all(isinstance(k, str) and isinstance(v, dict) for k, v in obj.items())
|
||||
|
||||
|
||||
@functools.cache
|
||||
def _get_oldest_supported_python() -> str:
|
||||
with PYPROJECT_PATH.open("rb") as config:
|
||||
@@ -71,6 +75,8 @@ class StubtestSettings:
|
||||
ignore_missing_stub: bool
|
||||
platforms: list[str]
|
||||
stubtest_requirements: list[str]
|
||||
mypy_plugins: list[str]
|
||||
mypy_plugins_config: dict[str, dict[str, Any]]
|
||||
|
||||
def system_requirements_for_platform(self, platform: str) -> list[str]:
|
||||
assert platform in _STUBTEST_PLATFORM_MAPPING, f"Unrecognised platform {platform!r}"
|
||||
@@ -93,6 +99,8 @@ def read_stubtest_settings(distribution: str) -> StubtestSettings:
|
||||
ignore_missing_stub: object = data.get("ignore_missing_stub", False)
|
||||
specified_platforms: object = data.get("platforms", ["linux"])
|
||||
stubtest_requirements: object = data.get("stubtest_requirements", [])
|
||||
mypy_plugins: object = data.get("mypy_plugins", [])
|
||||
mypy_plugins_config: object = data.get("mypy_plugins_config", {})
|
||||
|
||||
assert type(skip) is bool
|
||||
assert type(ignore_missing_stub) is bool
|
||||
@@ -104,6 +112,8 @@ def read_stubtest_settings(distribution: str) -> StubtestSettings:
|
||||
assert _is_list_of_strings(choco_dependencies)
|
||||
assert _is_list_of_strings(extras)
|
||||
assert _is_list_of_strings(stubtest_requirements)
|
||||
assert _is_list_of_strings(mypy_plugins)
|
||||
assert _is_nested_dict(mypy_plugins_config)
|
||||
|
||||
unrecognised_platforms = set(specified_platforms) - _STUBTEST_PLATFORM_MAPPING.keys()
|
||||
assert not unrecognised_platforms, f"Unrecognised platforms specified for {distribution!r}: {unrecognised_platforms}"
|
||||
@@ -124,6 +134,8 @@ def read_stubtest_settings(distribution: str) -> StubtestSettings:
|
||||
ignore_missing_stub=ignore_missing_stub,
|
||||
platforms=specified_platforms,
|
||||
stubtest_requirements=stubtest_requirements,
|
||||
mypy_plugins=mypy_plugins,
|
||||
mypy_plugins_config=mypy_plugins_config,
|
||||
)
|
||||
|
||||
|
||||
@@ -179,6 +191,8 @@ _KNOWN_METADATA_TOOL_FIELDS: Final = {
|
||||
"ignore_missing_stub",
|
||||
"platforms",
|
||||
"stubtest_requirements",
|
||||
"mypy_plugins",
|
||||
"mypy_plugins_config",
|
||||
}
|
||||
}
|
||||
_DIST_NAME_RE: Final = re.compile(r"^[a-z0-9]([a-z0-9._-]*[a-z0-9])?$", re.IGNORECASE)
|
||||
|
||||
+15
-2
@@ -6,7 +6,7 @@ from typing import Any, NamedTuple
|
||||
|
||||
import tomli
|
||||
|
||||
from ts_utils.metadata import metadata_path
|
||||
from ts_utils.metadata import StubtestSettings, metadata_path
|
||||
from ts_utils.utils import NamedTemporaryFile, TemporaryFileWrapper
|
||||
|
||||
|
||||
@@ -50,7 +50,9 @@ def mypy_configuration_from_distribution(distribution: str) -> list[MypyDistConf
|
||||
|
||||
|
||||
@contextmanager
|
||||
def temporary_mypy_config_file(configurations: Iterable[MypyDistConf]) -> Generator[TemporaryFileWrapper[str]]:
|
||||
def temporary_mypy_config_file(
|
||||
configurations: Iterable[MypyDistConf], stubtest_settings: StubtestSettings | None = None
|
||||
) -> Generator[TemporaryFileWrapper[str]]:
|
||||
temp = NamedTemporaryFile("w+")
|
||||
try:
|
||||
for dist_conf in configurations:
|
||||
@@ -58,6 +60,17 @@ def temporary_mypy_config_file(configurations: Iterable[MypyDistConf]) -> Genera
|
||||
for k, v in dist_conf.values.items():
|
||||
temp.write(f"{k} = {v}\n")
|
||||
temp.write("[mypy]\n")
|
||||
|
||||
if stubtest_settings:
|
||||
if stubtest_settings.mypy_plugins:
|
||||
temp.write(f"plugins = {'.'.join(stubtest_settings.mypy_plugins)}\n")
|
||||
|
||||
if stubtest_settings.mypy_plugins_config:
|
||||
for plugin_name, plugin_dict in stubtest_settings.mypy_plugins_config.items():
|
||||
temp.write(f"[mypy.plugins.{plugin_name}]\n")
|
||||
for k, v in plugin_dict.items():
|
||||
temp.write(f"{k} = {v}\n")
|
||||
|
||||
temp.flush()
|
||||
yield temp
|
||||
finally:
|
||||
|
||||
Reference in New Issue
Block a user