Skip to content

Commit dc50b60

Browse files
authored
Fix the type annotation for 'argmap' (#989)
The ArgMap type alias defined the mapping option (for `Schema.from_dict`) to allow `Field` or `type[Field]`, but this is incorrect. The following construction does not work: Schema.from_dict({"a": fields.Str}) Correct by simply removing `type[Field]` from the alias. A quick included improvement is to make the handling of type narrowing for `argmap` a little bit more uniform in style (we had it 3 different ways in different places), and to use a cast to replace a type ignore with something a little easier to read.
1 parent 50a7b66 commit dc50b60

File tree

1 file changed

+7
-14
lines changed

1 file changed

+7
-14
lines changed

src/webargs/core.py

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,9 @@
2626

2727

2828
Request = typing.TypeVar("Request")
29+
ArgMapCallable = typing.Callable[[Request], ma.Schema]
2930
ArgMap = typing.Union[
30-
ma.Schema,
31-
type[ma.Schema],
32-
typing.Mapping[str, typing.Union[ma.fields.Field, type[ma.fields.Field]]],
33-
typing.Callable[[Request], ma.Schema],
31+
ma.Schema, type[ma.Schema], typing.Mapping[str, ma.fields.Field], ArgMapCallable
3432
]
3533

3634
ValidateArg = typing.Union[None, typing.Callable, typing.Iterable[typing.Callable]]
@@ -328,15 +326,11 @@ def _get_schema(self, argmap: ArgMap, req: Request) -> ma.Schema:
328326
elif isinstance(argmap, type) and issubclass(argmap, ma.Schema):
329327
schema = argmap()
330328
elif isinstance(argmap, collections.abc.Mapping):
331-
if isinstance(argmap, dict):
332-
argmap_dict = argmap
333-
else:
334-
argmap_dict = dict(argmap)
329+
argmap_dict = argmap if isinstance(argmap, dict) else dict(argmap)
335330
schema = self.schema_class.from_dict(argmap_dict)()
336331
elif callable(argmap):
337-
# type-ignore because mypy seems to incorrectly deduce the type
338-
# as `[def (Request) -> Schema] | object`
339-
schema = argmap(req) # type: ignore[call-arg, assignment]
332+
argmap_callable = typing.cast(ArgMapCallable, argmap)
333+
schema = argmap_callable(req)
340334
else:
341335
raise TypeError(f"argmap was of unexpected type {type(argmap)}")
342336
return schema
@@ -585,9 +579,8 @@ def greet(querystring_args):
585579
# Optimization: If argmap is passed as a dictionary, we only need
586580
# to generate a Schema once
587581
if isinstance(argmap, typing.Mapping):
588-
if not isinstance(argmap, dict):
589-
argmap = dict(argmap)
590-
argmap = self.schema_class.from_dict(argmap)()
582+
argmap_dict = argmap if isinstance(argmap, dict) else dict(argmap)
583+
argmap = self.schema_class.from_dict(argmap_dict)()
591584

592585
if arg_name is not None and as_kwargs:
593586
raise ValueError("arg_name and as_kwargs are mutually exclusive")

0 commit comments

Comments
 (0)