Skip to content

Commit 329054d

Browse files
committed
Fix keyword-only args with defaults
1 parent 3e1aafc commit 329054d

File tree

5 files changed

+26
-8
lines changed

5 files changed

+26
-8
lines changed

tests/test_type_dir.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class Base[T]:
4242

4343
fin: typing.Final[int]
4444

45-
def foo(self, a: T | None, b: int = 0) -> dict[str, T]:
45+
def foo(self, a: T | None, *, b: int = 0) -> dict[str, T]:
4646
pass
4747

4848
def base[Z](self, a: T | Z | None, b: K) -> dict[str, T | Z]:
@@ -166,7 +166,7 @@ class Final:
166166
fin: typing.Final[int]
167167
x: tests.test_type_dir.Wrapper[int | None]
168168
ordinary: str
169-
def foo(self, a: int | None, b: int = 0) -> dict[str, int]: ...
169+
def foo(self, a: int | None, *, b: int = 0) -> dict[str, int]: ...
170170
def base[Z](self, a: int | Z | None, b: ~K) -> dict[str, int | Z]: ...
171171
def cbase(cls, a: int | None, b: ~K) -> dict[str, int]: ...
172172
def sbase[Z](cls, a: int | Literal['gotcha!'] | Z | None, b: ~K) -> dict[str, int | Z]: ...
@@ -260,7 +260,8 @@ def test_type_dir_7():
260260
typing.Callable[[\
261261
typemap.typing.Param[typing.Literal['self'], typing.Any, typing.Never], \
262262
typemap.typing.Param[typing.Literal['a'], int | None, typing.Never], \
263-
typemap.typing.Param[typing.Literal['b'], int, typing.Literal['=']]], \
263+
typemap.typing.Param[typing.Literal['b'], int, typing.Literal['keyword', \
264+
'default']]], \
264265
dict[str, int]], typing.Literal['ClassVar'], tests.test_type_dir.Final]"
265266
)
266267

typemap/type_eval/_apply_generic.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,12 @@ def make_func(
133133
annos: dict[str, Any],
134134
) -> types.FunctionType:
135135
new_func = types.FunctionType(
136-
func.__code__, func.__globals__, "__call__", func.__defaults__, ()
136+
func.__code__,
137+
func.__globals__,
138+
"__call__",
139+
func.__defaults__,
140+
(),
141+
func.__kwdefaults__,
137142
)
138143

139144
new_func.__module__ = func.__module__

typemap/type_eval/_eval_operators.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,10 @@ def _ann(x):
203203
quals.append("*")
204204
if p.kind == inspect.Parameter.VAR_KEYWORD:
205205
quals.append("**")
206+
if p.kind == inspect.Parameter.KEYWORD_ONLY:
207+
quals.append("keyword")
206208
if p.default is not empty:
207-
quals.append("=")
209+
quals.append("default")
208210
params.append(
209211
Param[
210212
typing.Literal[p.name if has_name else None],

typemap/type_eval/_eval_typing.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,12 @@ def _eval_func(func: types.FunctionType | types.MethodType, ctx: EvalContext):
121121
annos = {name: _eval_types(tp, ctx) for name, tp in annos.items()}
122122

123123
new_func = types.FunctionType(
124-
root.__code__, root.__globals__, "__call__", root.__defaults__, ()
124+
root.__code__,
125+
root.__globals__,
126+
"__call__",
127+
root.__defaults__,
128+
(),
129+
root.__kwdefaults__,
125130
)
126131

127132
new_func.__name__ = root.__name__

typemap/typing.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@ class SpecialFormEllipsis:
1717

1818
###
1919

20+
MemberQuals = typing.Literal["ClassVar", "Final"]
2021

21-
class Member[N: str, T, Q: str = typing.Never, D = typing.Never]:
22+
23+
class Member[N: str, T, Q: MemberQuals = typing.Never, D = typing.Never]:
2224
pass
2325

2426

@@ -32,7 +34,10 @@ class Attrs[T]:
3234
pass
3335

3436

35-
class Param[N: str | None, T, Q: str = typing.Never]:
37+
ParamQuals = typing.Literal["*", "**", "="]
38+
39+
40+
class Param[N: str | None, T, Q: ParamQuals = typing.Never]:
3641
pass
3742

3843

0 commit comments

Comments
 (0)