Skip to content

Commit 045ea8c

Browse files
authored
[stubgen] Add known return types to magic methods (#13909)
This is based on the idea of https://github.com/JelleZijlstra/autotyping Other magic methods can be added later. CC @JelleZijlstra
1 parent 874a28f commit 045ea8c

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

mypy/stubgen.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,22 @@
189189
"__iter__",
190190
}
191191

192+
# These magic methods always return the same type.
193+
KNOWN_MAGIC_METHODS_RETURN_TYPES: Final = {
194+
"__len__": "int",
195+
"__length_hint__": "int",
196+
"__init__": "None",
197+
"__del__": "None",
198+
"__bool__": "bool",
199+
"__bytes__": "bytes",
200+
"__format__": "str",
201+
"__contains__": "bool",
202+
"__complex__": "complex",
203+
"__int__": "int",
204+
"__float__": "float",
205+
"__index__": "int",
206+
}
207+
192208

193209
class Options:
194210
"""Represents stubgen options.
@@ -735,6 +751,8 @@ def visit_func_def(
735751
# Always assume abstract methods return Any unless explicitly annotated. Also
736752
# some dunder methods should not have a None return type.
737753
retname = None # implicit Any
754+
elif o.name in KNOWN_MAGIC_METHODS_RETURN_TYPES:
755+
retname = KNOWN_MAGIC_METHODS_RETURN_TYPES[o.name]
738756
elif has_yield_expression(o):
739757
self.add_abc_import("Generator")
740758
yield_name = "None"

test-data/unit/stubgen.test

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2705,3 +2705,32 @@ def f():
27052705
return 0
27062706
[out]
27072707
def f(): ...
2708+
2709+
[case testKnownMagicMethodsReturnTypes]
2710+
class Some:
2711+
def __len__(self): ...
2712+
def __length_hint__(self): ...
2713+
def __init__(self): ...
2714+
def __del__(self): ...
2715+
def __bool__(self): ...
2716+
def __bytes__(self): ...
2717+
def __format__(self, spec): ...
2718+
def __contains__(self, obj): ...
2719+
def __complex__(self): ...
2720+
def __int__(self): ...
2721+
def __float__(self): ...
2722+
def __index__(self): ...
2723+
[out]
2724+
class Some:
2725+
def __len__(self) -> int: ...
2726+
def __length_hint__(self) -> int: ...
2727+
def __init__(self) -> None: ...
2728+
def __del__(self) -> None: ...
2729+
def __bool__(self) -> bool: ...
2730+
def __bytes__(self) -> bytes: ...
2731+
def __format__(self, spec) -> str: ...
2732+
def __contains__(self, obj) -> bool: ...
2733+
def __complex__(self) -> complex: ...
2734+
def __int__(self) -> int: ...
2735+
def __float__(self) -> float: ...
2736+
def __index__(self) -> int: ...

0 commit comments

Comments
 (0)