Skip to content

Commit 263ba7f

Browse files
authored
Support FIXME names for unknown types in dmypy suggest (python#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)
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