@@ -108,7 +108,11 @@ def test_parse(parser, web_request):
108108@pytest .mark .skipif (
109109 MARSHMALLOW_VERSION_INFO [0 ] < 3 , reason = "unknown=... added in marshmallow3"
110110)
111- def test_parse_with_unknown_behavior_specified (parser , web_request ):
111+ @pytest .mark .parametrize (
112+ "set_location" ,
113+ ["schema_instance" , "parse_call" , "parser_default" , "parser_class_default" ],
114+ )
115+ def test_parse_with_unknown_behavior_specified (parser , web_request , set_location ):
112116 # This is new in webargs 6.x ; it's the way you can "get back" the behavior
113117 # of webargs 5.x in which extra args are ignored
114118 from marshmallow import EXCLUDE , INCLUDE , RAISE
@@ -119,17 +123,65 @@ class CustomSchema(Schema):
119123 username = fields .Field ()
120124 password = fields .Field ()
121125
126+ def parse_with_desired_behavior (value ):
127+ if set_location == "schema_instance" :
128+ if value is not None :
129+ return parser .parse (CustomSchema (unknown = value ), web_request )
130+ else :
131+ return parser .parse (CustomSchema (), web_request )
132+ elif set_location == "parse_call" :
133+ return parser .parse (CustomSchema (), web_request , unknown = value )
134+ elif set_location == "parser_default" :
135+ parser .unknown = value
136+ return parser .parse (CustomSchema (), web_request )
137+ elif set_location == "parser_class_default" :
138+
139+ class CustomParser (MockRequestParser ):
140+ DEFAULT_UNKNOWN = value
141+
142+ return CustomParser ().parse (CustomSchema (), web_request )
143+ else :
144+ raise NotImplementedError
145+
122146 # with no unknown setting or unknown=RAISE, it blows up
123147 with pytest .raises (ValidationError , match = "Unknown field." ):
124- parser . parse ( CustomSchema (), web_request )
148+ parse_with_desired_behavior ( None )
125149 with pytest .raises (ValidationError , match = "Unknown field." ):
126- parser . parse ( CustomSchema ( unknown = RAISE ), web_request )
150+ parse_with_desired_behavior ( RAISE )
127151
128152 # with unknown=EXCLUDE the data is omitted
129- ret = parser . parse ( CustomSchema ( unknown = EXCLUDE ), web_request )
153+ ret = parse_with_desired_behavior ( EXCLUDE )
130154 assert {"username" : 42 , "password" : 42 } == ret
131155 # with unknown=INCLUDE it is added even though it isn't part of the schema
132- ret = parser .parse (CustomSchema (unknown = INCLUDE ), web_request )
156+ ret = parse_with_desired_behavior (INCLUDE )
157+ assert {"username" : 42 , "password" : 42 , "fjords" : 42 } == ret
158+
159+
160+ @pytest .mark .skipif (
161+ MARSHMALLOW_VERSION_INFO [0 ] < 3 , reason = "unknown=... added in marshmallow3"
162+ )
163+ def test_parse_with_explicit_unknown_overrides_schema (parser , web_request ):
164+ # this test ensures that if you specify unknown=... in your parse call (or
165+ # use_args) it takes precedence over a setting in the schema object
166+ from marshmallow import EXCLUDE , INCLUDE , RAISE
167+
168+ web_request .json = {"username" : 42 , "password" : 42 , "fjords" : 42 }
169+
170+ class CustomSchema (Schema ):
171+ username = fields .Field ()
172+ password = fields .Field ()
173+
174+ # setting RAISE in the parse call overrides schema setting
175+ with pytest .raises (ValidationError , match = "Unknown field." ):
176+ parser .parse (CustomSchema (unknown = EXCLUDE ), web_request , unknown = RAISE )
177+ with pytest .raises (ValidationError , match = "Unknown field." ):
178+ parser .parse (CustomSchema (unknown = INCLUDE ), web_request , unknown = RAISE )
179+
180+ # and the reverse -- setting EXCLUDE or INCLUDE in the parse call overrides
181+ # a schema with RAISE already set
182+ ret = parser .parse (CustomSchema (unknown = RAISE ), web_request , unknown = EXCLUDE )
183+ assert {"username" : 42 , "password" : 42 } == ret
184+ ret = parser .parse (CustomSchema (unknown = RAISE ), web_request , unknown = INCLUDE )
133185 assert {"username" : 42 , "password" : 42 , "fjords" : 42 } == ret
134186
135187
@@ -756,22 +808,18 @@ def test_warning_raised_if_schema_is_not_in_strict_mode(self, web_request, parse
756808 assert "strict=True" in str (warning .message )
757809
758810 def test_use_kwargs_stacked (self , web_request , parser ):
811+ parse_kwargs = {}
759812 if MARSHMALLOW_VERSION_INFO [0 ] >= 3 :
760813 from marshmallow import EXCLUDE
761814
762- class PageSchema (Schema ):
763- page = fields .Int ()
764-
765- pageschema = PageSchema (unknown = EXCLUDE )
766- userschema = self .UserSchema (unknown = EXCLUDE )
767- else :
768- pageschema = {"page" : fields .Int ()}
769- userschema = self .UserSchema (** strict_kwargs )
815+ parse_kwargs = {"unknown" : EXCLUDE }
770816
771817 web_request .json = {"email" : "foo@bar.com" , "password" : "bar" , "page" : 42 }
772818
773- @parser .use_kwargs (pageschema , web_request )
774- @parser .use_kwargs (userschema , web_request )
819+ @parser .use_kwargs ({"page" : fields .Int ()}, web_request , ** parse_kwargs )
820+ @parser .use_kwargs (
821+ self .UserSchema (** strict_kwargs ), web_request , ** parse_kwargs
822+ )
775823 def viewfunc (email , password , page ):
776824 return {"email" : email , "password" : password , "page" : page }
777825
0 commit comments