Skip to content

Commit 7938f5d

Browse files
authored
Adding config file for stubtest.py (python#9203)
1 parent 5a9d022 commit 7938f5d

File tree

3 files changed

+61
-2
lines changed

3 files changed

+61
-2
lines changed

mypy/stubtest.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import mypy.modulefinder
2424
import mypy.types
2525
from mypy import nodes
26+
from mypy.config_parser import parse_config_file
2627
from mypy.options import Options
2728
from mypy.util import FancyFormatter
2829

@@ -1040,6 +1041,12 @@ def test_stubs(args: argparse.Namespace) -> int:
10401041
options = Options()
10411042
options.incremental = False
10421043
options.custom_typeshed_dir = args.custom_typeshed_dir
1044+
options.config_file = args.mypy_config_file
1045+
1046+
if options.config_file:
1047+
def set_strict_flags() -> None: # not needed yet
1048+
return
1049+
parse_config_file(options, set_strict_flags, options.config_file, sys.stdout, sys.stderr)
10431050

10441051
try:
10451052
modules = build_stubs(modules, options, find_submodules=not args.check_typeshed)
@@ -1133,6 +1140,19 @@ def parse_options(args: List[str]) -> argparse.Namespace:
11331140
action="store_true",
11341141
help="Ignore unused whitelist entries",
11351142
)
1143+
config_group = parser.add_argument_group(
1144+
title='mypy config file',
1145+
description="Use a config file instead of command line arguments. "
1146+
"Plugins and mypy path are the only supported "
1147+
"configurations.",
1148+
)
1149+
config_group.add_argument(
1150+
'--mypy-config-file',
1151+
help=(
1152+
"An existing mypy configuration file, currently used by stubtest to help "
1153+
"determine mypy path and plugins"
1154+
),
1155+
)
11361156

11371157
return parser.parse_args(args)
11381158

mypy/test/teststubtest.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
import mypy.stubtest
1313
from mypy.stubtest import parse_options, test_stubs
14+
from mypy.test.data import root_dir
1415

1516

1617
@contextlib.contextmanager
@@ -27,13 +28,18 @@ def use_tmp_dir() -> Iterator[None]:
2728
TEST_MODULE_NAME = "test_module"
2829

2930

30-
def run_stubtest(stub: str, runtime: str, options: List[str]) -> str:
31+
def run_stubtest(
32+
stub: str, runtime: str, options: List[str], config_file: Optional[str] = None,
33+
) -> str:
3134
with use_tmp_dir():
3235
with open("{}.pyi".format(TEST_MODULE_NAME), "w") as f:
3336
f.write(stub)
3437
with open("{}.py".format(TEST_MODULE_NAME), "w") as f:
3538
f.write(runtime)
36-
39+
if config_file:
40+
with open("{}_config.ini".format(TEST_MODULE_NAME), "w") as f:
41+
f.write(config_file)
42+
options = options + ["--mypy-config-file", "{}_config.ini".format(TEST_MODULE_NAME)]
3743
if sys.path[0] != ".":
3844
sys.path.insert(0, ".")
3945
if TEST_MODULE_NAME in sys.modules:
@@ -753,3 +759,18 @@ class StubtestIntegration(unittest.TestCase):
753759
def test_typeshed(self) -> None:
754760
# check we don't crash while checking typeshed
755761
test_stubs(parse_options(["--check-typeshed"]))
762+
763+
def test_config_file(self) -> None:
764+
runtime = "temp = 5\n"
765+
stub = "from decimal import Decimal\ntemp: Decimal\n"
766+
config_file = (
767+
"[mypy]\n"
768+
"plugins={}/test-data/unit/plugins/decimal_to_int.py\n".format(root_dir)
769+
)
770+
output = run_stubtest(stub=stub, runtime=runtime, options=[])
771+
assert output == (
772+
"error: test_module.temp variable differs from runtime type Literal[5]\n"
773+
"Stub: at line 2\ndecimal.Decimal\nRuntime:\n5\n\n"
774+
)
775+
output = run_stubtest(stub=stub, runtime=runtime, options=[], config_file=config_file)
776+
assert output == ""
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import builtins
2+
from typing import Optional, Callable
3+
4+
from mypy.plugin import Plugin, AnalyzeTypeContext
5+
from mypy.types import CallableType, Type
6+
7+
8+
class MyPlugin(Plugin):
9+
def get_type_analyze_hook(self, fullname):
10+
if fullname == "decimal.Decimal":
11+
return decimal_to_int_hook
12+
return None
13+
14+
def plugin(version):
15+
return MyPlugin
16+
17+
def decimal_to_int_hook(ctx):
18+
return ctx.api.named_type('builtins.int', [])

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy