-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Apply mypy-tests custom config to other mypy-based tests #13825
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
b3011c8
4624afd
d637e45
3f97ef1
0111d5d
ae7cc8d
23b2d02
4ee3ac5
378f669
99c6260
fc55a22
2dc0a2a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
from __future__ import annotations | ||
|
||
import os | ||
import sys | ||
import tempfile | ||
from collections.abc import Generator, Iterable | ||
from contextlib import contextmanager | ||
from typing import Any, NamedTuple | ||
|
||
import tomli | ||
|
||
from ts_utils.metadata import metadata_path | ||
|
||
|
||
class MypyDistConf(NamedTuple): | ||
module_name: str | ||
values: dict[str, dict[str, Any]] | ||
|
||
|
||
# The configuration section in the metadata file looks like the following, with multiple module sections possible | ||
# [mypy-tests] | ||
# [mypy-tests.yaml] | ||
# module_name = "yaml" | ||
# [mypy-tests.yaml.values] | ||
# disallow_incomplete_defs = true | ||
# disallow_untyped_defs = true | ||
|
||
|
||
def mypy_configuration_from_distribution(distribution: str) -> list[MypyDistConf]: | ||
with metadata_path(distribution).open("rb") as f: | ||
data = tomli.load(f) | ||
|
||
# TODO: This could be added to ts_utils.metadata | ||
mypy_tests_conf: dict[str, dict[str, Any]] = data.get("mypy-tests", {}) | ||
if not mypy_tests_conf: | ||
return [] | ||
|
||
def validate_configuration(section_name: str, mypy_section: dict[str, Any]) -> MypyDistConf: | ||
assert isinstance(mypy_section, dict), f"{section_name} should be a section" | ||
module_name = mypy_section.get("module_name") | ||
|
||
assert module_name is not None, f"{section_name} should have a module_name key" | ||
assert isinstance(module_name, str), f"{section_name} should be a key-value pair" | ||
|
||
assert "values" in mypy_section, f"{section_name} should have a values section" | ||
values: dict[str, dict[str, Any]] = mypy_section["values"] | ||
assert isinstance(values, dict), "values should be a section" | ||
return MypyDistConf(module_name, values.copy()) | ||
|
||
assert isinstance(mypy_tests_conf, dict), "mypy-tests should be a section" | ||
return [validate_configuration(section_name, mypy_section) for section_name, mypy_section in mypy_tests_conf.items()] | ||
|
||
|
||
@contextmanager | ||
def temporary_mypy_config_file( | ||
configurations: Iterable[MypyDistConf], | ||
) -> Generator[tempfile._TemporaryFileWrapper[str]]: # pyright: ignore[reportPrivateUsage] | ||
|
||
# We need to work around a limitation of tempfile.NamedTemporaryFile on Windows | ||
# For details, see https://github.com/python/typeshed/pull/13620#discussion_r1990185997 | ||
# Python 3.12 added a workaround with `tempfile.NamedTemporaryFile("w+", delete_on_close=False)` | ||
temp = tempfile.NamedTemporaryFile("w+", delete=sys.platform != "win32") # noqa: SIM115 | ||
try: | ||
for dist_conf in configurations: | ||
temp.write(f"[mypy-{dist_conf.module_name}]\n") | ||
for k, v in dist_conf.values.items(): | ||
temp.write(f"{k} = {v}\n") | ||
temp.write("[mypy]\n") | ||
temp.flush() | ||
yield temp | ||
finally: | ||
temp.close() | ||
if sys.platform == "win32": | ||
os.remove(temp.name) |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this should be a docstring ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually prefer this to be a comment. It doesn't really feel like something that's relevant to the API. That said, it would probably be better to document it in
CONTRIBUTING
instead.