From 7592eda3f5bc6e10af72ced8a90d48bd32be7a0d Mon Sep 17 00:00:00 2001 From: zenglanmu Date: Wed, 29 Apr 2020 19:11:11 +0800 Subject: [PATCH 1/2] add unknown optional keywords to parse and use_args --- src/webargs/core.py | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/webargs/core.py b/src/webargs/core.py index 4888fe0ca..35051bfca 100644 --- a/src/webargs/core.py +++ b/src/webargs/core.py @@ -191,7 +191,7 @@ def _validate_arguments(self, data, validators): msg = self.DEFAULT_VALIDATION_MESSAGE raise ValidationError(msg, data=data) - def _get_schema(self, argmap, req): + def _get_schema(self, argmap, req, unknown): """Return a `marshmallow.Schema` for the given argmap and request. :param argmap: Either a `marshmallow.Schema`, `dict` @@ -207,7 +207,14 @@ def _get_schema(self, argmap, req): elif callable(argmap): schema = argmap(req) else: - schema = dict2schema(argmap, schema_class=self.schema_class)() + if 'unknown' in argmap: + unknown = argmap['unknown'] + else: + pass + if unknown is None: + schema = dict2schema(argmap, schema_class=self.schema_class)() + else: + schema = dict2schema(argmap, schema_class=self.schema_class)(unknown=unknown) if MARSHMALLOW_VERSION_INFO[0] < 3 and not schema.strict: warnings.warn( "It is highly recommended that you set strict=True on your schema " @@ -224,7 +231,8 @@ def parse( location=None, validate=None, error_status_code=None, - error_headers=None + error_headers=None, + unknown=None ): """Main request parsing method. @@ -252,7 +260,7 @@ def parse( raise ValueError("Must pass req object") data = None validators = _ensure_list_of_callables(validate) - schema = self._get_schema(argmap, req) + schema = self._get_schema(argmap, req, unknown) try: location_data = self._load_location_data( schema=schema, req=req, location=location @@ -310,7 +318,8 @@ def use_args( as_kwargs=False, validate=None, error_status_code=None, - error_headers=None + error_headers=None, + unknown=None ): """Decorator that injects parsed arguments into a view function or method. @@ -339,7 +348,10 @@ def greet(args): # Optimization: If argmap is passed as a dictionary, we only need # to generate a Schema once if isinstance(argmap, Mapping): - argmap = dict2schema(argmap, schema_class=self.schema_class)() + if unknown is None: + argmap = dict2schema(argmap, schema_class=self.schema_class)() + else: + argmap = dict2schema(argmap, schema_class=self.schema_class)(unknown = unknown) def decorator(func): req_ = request_obj From e8dc2c473db65b1774777d1b8d93bcddefed5e9b Mon Sep 17 00:00:00 2001 From: zenglanmu Date: Wed, 29 Apr 2020 19:28:23 +0800 Subject: [PATCH 2/2] add unknown args to asyncparser.py as well --- src/webargs/asyncparser.py | 13 +++++++++---- src/webargs/core.py | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/webargs/asyncparser.py b/src/webargs/asyncparser.py index 1ba77c702..fb8111e94 100644 --- a/src/webargs/asyncparser.py +++ b/src/webargs/asyncparser.py @@ -30,7 +30,8 @@ async def parse( location: str = None, validate: Validate = None, error_status_code: typing.Union[int, None] = None, - error_headers: typing.Union[typing.Mapping[str, str], None] = None + error_headers: typing.Union[typing.Mapping[str, str], None] = None, + unknown=None ) -> typing.Union[typing.Mapping, None]: """Coroutine variant of `webargs.core.Parser`. @@ -42,7 +43,7 @@ async def parse( raise ValueError("Must pass req object") data = None validators = core._ensure_list_of_callables(validate) - schema = self._get_schema(argmap, req) + schema = self._get_schema(argmap, req, unknown=unknown) try: location_data = await self._load_location_data( schema=schema, req=req, location=location @@ -114,7 +115,8 @@ def use_args( as_kwargs: bool = False, validate: Validate = None, error_status_code: typing.Optional[int] = None, - error_headers: typing.Union[typing.Mapping[str, str], None] = None + error_headers: typing.Union[typing.Mapping[str, str], None] = None, + unknown = None ) -> typing.Callable[..., typing.Callable]: """Decorator that injects parsed arguments into a view function or method. @@ -125,7 +127,10 @@ def use_args( # Optimization: If argmap is passed as a dictionary, we only need # to generate a Schema once if isinstance(argmap, Mapping): - argmap = core.dict2schema(argmap, schema_class=self.schema_class)() + if unknown is None: + argmap = core.dict2schema(argmap, schema_class=self.schema_class)() + else: + argmap = core.dict2schema(argmap, schema_class=self.schema_class)(unknown=unknown) def decorator(func: typing.Callable) -> typing.Callable: req_ = request_obj diff --git a/src/webargs/core.py b/src/webargs/core.py index 35051bfca..14757a080 100644 --- a/src/webargs/core.py +++ b/src/webargs/core.py @@ -191,7 +191,7 @@ def _validate_arguments(self, data, validators): msg = self.DEFAULT_VALIDATION_MESSAGE raise ValidationError(msg, data=data) - def _get_schema(self, argmap, req, unknown): + def _get_schema(self, argmap, req, unknown=None): """Return a `marshmallow.Schema` for the given argmap and request. :param argmap: Either a `marshmallow.Schema`, `dict`