Skip to content

Commit 263ba7f

Browse files
authored
Support FIXME names for unknown types in dmypy suggest (#7679)
This PR adds an option to `dmypy suggest` to replace `Any` in suggested signatures with a dummy name like `FIXME` or `UNKNOWN`. The main question here is whether we should replace only the top-level `Any`s , or also nested one. I am leaning towards the former, but this is not a strong opinion.
1 parent 40f4d66 commit 263ba7f

File tree

5 files changed

+48
-4
lines changed

5 files changed

+48
-4
lines changed

mypy/dmypy/client.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ def __init__(self, prog: str) -> None:
114114
help="Try using unicode wherever str is inferred")
115115
p.add_argument('--callsites', action='store_true',
116116
help="Find callsites instead of suggesting a type")
117+
p.add_argument('--use-fixme', metavar='NAME', type=str,
118+
help="A dummy name to use instead of Any for types that can't be inferred")
117119

118120
hang_parser = p = subparsers.add_parser('hang', help="Hang for 100 seconds")
119121

@@ -367,7 +369,8 @@ def do_suggest(args: argparse.Namespace) -> None:
367369
"""
368370
response = request(args.status_file, 'suggest', function=args.function,
369371
json=args.json, callsites=args.callsites, no_errors=args.no_errors,
370-
no_any=args.no_any, flex_any=args.flex_any, try_text=args.try_text)
372+
no_any=args.no_any, flex_any=args.flex_any, try_text=args.try_text,
373+
use_fixme=args.use_fixme)
371374
check_output(response, verbose=False, junit_xml=None, perf_stats_file=None)
372375

373376

mypy/semanal.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
from contextlib import contextmanager
5151

5252
from typing import (
53-
List, Dict, Set, Tuple, cast, TypeVar, Union, Optional, Callable, Iterator, Iterable,
53+
List, Dict, Set, Tuple, cast, TypeVar, Union, Optional, Callable, Iterator, Iterable
5454
)
5555
from typing_extensions import Final
5656

mypy/suggestions.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,8 @@ def __init__(self, fgmanager: FineGrainedBuildManager,
160160
no_errors: bool = False,
161161
no_any: bool = False,
162162
try_text: bool = False,
163-
flex_any: Optional[float] = None) -> None:
163+
flex_any: Optional[float] = None,
164+
use_fixme: Optional[str] = None) -> None:
164165
self.fgmanager = fgmanager
165166
self.manager = fgmanager.manager
166167
self.plugin = self.manager.plugin
@@ -175,6 +176,7 @@ def __init__(self, fgmanager: FineGrainedBuildManager,
175176
self.flex_any = 1.0
176177

177178
self.max_guesses = 16
179+
self.use_fixme = use_fixme
178180

179181
def suggest(self, function: str) -> str:
180182
"""Suggest an inferred type for function."""
@@ -592,6 +594,8 @@ def format_signature(self, sig: PyAnnotateSignature) -> str:
592594
)
593595

594596
def format_type(self, cur_module: Optional[str], typ: Type) -> str:
597+
if self.use_fixme and isinstance(get_proper_type(typ), AnyType):
598+
return self.use_fixme
595599
return typ.accept(TypeFormatter(cur_module, self.graph))
596600

597601
def score_type(self, t: Type, arg_pos: bool) -> int:

mypy/test/testfinegrained.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,10 +281,12 @@ def maybe_suggest(self, step: int, server: Server, src: str, tmp_dir: str) -> Li
281281
try_text = '--try-text' in flags
282282
m = re.match('--flex-any=([0-9.]+)', flags)
283283
flex_any = float(m.group(1)) if m else None
284+
m = re.match(r'--use-fixme=(\w+)', flags)
285+
use_fixme = m.group(1) if m else None
284286
res = cast(Dict[str, Any],
285287
server.cmd_suggest(
286288
target.strip(), json=json, no_any=no_any, no_errors=no_errors,
287-
try_text=try_text, flex_any=flex_any,
289+
try_text=try_text, flex_any=flex_any, use_fixme=use_fixme,
288290
callsites=callsites))
289291
val = res['error'] if 'error' in res else res['out'] + res['err']
290292
if json:

test-data/unit/fine-grained-suggest.test

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,3 +733,38 @@ func('test')
733733
[out]
734734
(str) -> int
735735
==
736+
737+
[case testSuggestUseFixmeBasic]
738+
# suggest: --use-fixme=UNKNOWN foo.foo
739+
# suggest: --use-fixme=UNKNOWN foo.bar
740+
[file foo.py]
741+
742+
def foo():
743+
return g()
744+
745+
def bar(x):
746+
return None
747+
748+
def g(): ...
749+
x = bar(g())
750+
[out]
751+
() -> UNKNOWN
752+
(UNKNOWN) -> None
753+
==
754+
755+
[case testSuggestUseFixmeNoNested]
756+
# suggest: --use-fixme=UNKNOWN foo.foo
757+
[file foo.py]
758+
from typing import List, Any
759+
760+
def foo(x, y):
761+
return x, y
762+
763+
def f() -> List[Any]: ...
764+
def g(): ...
765+
766+
z = foo(f(), g())
767+
[builtins fixtures/isinstancelist.pyi]
768+
[out]
769+
(foo.List[Any], UNKNOWN) -> Tuple[foo.List[Any], Any]
770+
==

0 commit comments

Comments
 (0)