Skip to content

Commit f339f2c

Browse files
authored
handle arg=None in stubgenc (#18768)
resolves #18757
1 parent a067d84 commit f339f2c

File tree

2 files changed

+36
-8
lines changed

2 files changed

+36
-8
lines changed

mypy/stubgenc.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from __future__ import annotations
88

9+
import enum
910
import glob
1011
import importlib
1112
import inspect
@@ -211,6 +212,9 @@ def __get__(self) -> None: # noqa: PLE0302
211212
pass
212213

213214

215+
_Missing = enum.Enum("_Missing", "VALUE")
216+
217+
214218
class InspectionStubGenerator(BaseStubGenerator):
215219
"""Stub generator that does not parse code.
216220
@@ -310,12 +314,12 @@ def get_annotation(key: str) -> str | None:
310314

311315
# Add the arguments to the signature
312316
def add_args(
313-
args: list[str], get_default_value: Callable[[int, str], object | None]
317+
args: list[str], get_default_value: Callable[[int, str], object | _Missing]
314318
) -> None:
315319
for i, arg in enumerate(args):
316320
# Check if the argument has a default value
317321
default_value = get_default_value(i, arg)
318-
if default_value is not None:
322+
if default_value is not _Missing.VALUE:
319323
if arg in annotations:
320324
argtype = annotations[arg]
321325
else:
@@ -330,11 +334,11 @@ def add_args(
330334
else:
331335
arglist.append(ArgSig(arg, get_annotation(arg), default=False))
332336

333-
def get_pos_default(i: int, _arg: str) -> Any | None:
337+
def get_pos_default(i: int, _arg: str) -> Any | _Missing:
334338
if defaults and i >= len(args) - len(defaults):
335339
return defaults[i - (len(args) - len(defaults))]
336340
else:
337-
return None
341+
return _Missing.VALUE
338342

339343
add_args(args, get_pos_default)
340344

@@ -345,11 +349,11 @@ def get_pos_default(i: int, _arg: str) -> Any | None:
345349
elif kwonlyargs:
346350
arglist.append(ArgSig("*"))
347351

348-
def get_kw_default(_i: int, arg: str) -> Any | None:
349-
if kwonlydefaults:
350-
return kwonlydefaults.get(arg)
352+
def get_kw_default(_i: int, arg: str) -> Any | _Missing:
353+
if kwonlydefaults and arg in kwonlydefaults:
354+
return kwonlydefaults[arg]
351355
else:
352-
return None
356+
return _Missing.VALUE
353357

354358
add_args(kwonlyargs, get_kw_default)
355359

mypy/test/teststubgen.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,30 @@ class TestClassVariableCls:
856856
assert_equal(gen.get_imports().splitlines(), ["from typing import ClassVar"])
857857
assert_equal(output, ["class C:", " x: ClassVar[int] = ..."])
858858

859+
def test_generate_c_type_none_default(self) -> None:
860+
class TestClass:
861+
def test(self, arg0=1, arg1=None) -> None: # type: ignore[no-untyped-def]
862+
pass
863+
864+
output: list[str] = []
865+
mod = ModuleType(TestClass.__module__, "")
866+
gen = InspectionStubGenerator(mod.__name__, known_modules=[mod.__name__], module=mod)
867+
gen.is_c_module = False
868+
gen.generate_function_stub(
869+
"test",
870+
TestClass.test,
871+
output=output,
872+
class_info=ClassInfo(
873+
self_var="self",
874+
cls=TestClass,
875+
name="TestClass",
876+
docstring=getattr(TestClass, "__doc__", None),
877+
),
878+
)
879+
assert_equal(
880+
output, ["def test(self, arg0: int = ..., arg1: Incomplete | None = ...) -> None: ..."]
881+
)
882+
859883
def test_non_c_generate_signature_with_kw_only_args(self) -> None:
860884
class TestClass:
861885
def test(

0 commit comments

Comments
 (0)