1
1
import string
2
2
from typing import TYPE_CHECKING
3
3
from typing import Any
4
+ from typing import Sequence
4
5
from typing import Iterator
5
6
from typing import List
6
7
from typing import Optional
@@ -78,7 +79,8 @@ def _collect_properties(self, schema: SchemaPath) -> set[str]:
78
79
props : set [str ] = set ()
79
80
80
81
if "properties" in schema :
81
- props .update ((schema / "properties" ).keys ())
82
+ schema_props = (schema / "properties" ).keys ()
83
+ props .update (cast (Sequence [str ], schema_props ))
82
84
83
85
for kw in ("allOf" , "anyOf" , "oneOf" ):
84
86
if kw in schema :
@@ -96,11 +98,12 @@ def _collect_properties(self, schema: SchemaPath) -> set[str]:
96
98
def __call__ (
97
99
self , schema : SchemaPath , require_properties : bool = True
98
100
) -> Iterator [ValidationError ]:
99
- if not hasattr (schema .content (), "__getitem__" ):
101
+ schema_value = schema .read_value ()
102
+ if not hasattr (schema_value , "__getitem__" ):
100
103
return
101
104
102
105
assert self .schema_ids_registry is not None
103
- schema_id = id (schema . content () )
106
+ schema_id = id (schema_value )
104
107
if schema_id in self .schema_ids_registry :
105
108
return
106
109
self .schema_ids_registry .append (schema_id )
@@ -151,8 +154,8 @@ def __call__(
151
154
require_properties = False ,
152
155
)
153
156
154
- required = schema . getkey ( "required" , [])
155
- properties = schema . get ( "properties" , {} ).keys ()
157
+ required = "required" in schema and ( schema / "required" ). read_value () or []
158
+ properties = "properties" in schema and ( schema / "properties" ).keys () or []
156
159
if "allOf" in schema :
157
160
extra_properties = list (
158
161
set (required ) - set (properties ) - set (nested_properties )
@@ -166,10 +169,12 @@ def __call__(
166
169
)
167
170
168
171
if "default" in schema :
169
- default = schema ["default" ]
170
- nullable = schema .get ("nullable" , False )
171
- if default is not None or nullable is not True :
172
- yield from self .default_validator (schema , default )
172
+ default_value = (schema / "default" ).read_value ()
173
+ nullable_value = False
174
+ if "nullable" in schema :
175
+ nullable_value = (schema / "nullable" ).read_value ()
176
+ if default_value is not None or nullable_value is not True :
177
+ yield from self .default_validator (schema , default_value )
173
178
174
179
175
180
class SchemasValidator (KeywordValidator ):
@@ -203,9 +208,9 @@ def __call__(self, parameter: SchemaPath) -> Iterator[ValidationError]:
203
208
204
209
if "default" in parameter :
205
210
# only possible in swagger 2.0
206
- default = parameter . getkey ( "default" )
207
- if default is not None :
208
- yield from self .default_validator (parameter , default )
211
+ if "default" in parameter :
212
+ default_value = ( parameter / "default" ). read_value ()
213
+ yield from self .default_validator (parameter , default_value )
209
214
210
215
211
216
class ParametersValidator (KeywordValidator ):
@@ -246,6 +251,7 @@ def media_type_validator(self) -> MediaTypeValidator:
246
251
247
252
def __call__ (self , content : SchemaPath ) -> Iterator [ValidationError ]:
248
253
for mimetype , media_type in content .items ():
254
+ assert isinstance (mimetype , str )
249
255
yield from self .media_type_validator (mimetype , media_type )
250
256
251
257
@@ -291,6 +297,7 @@ def response_validator(self) -> ResponseValidator:
291
297
292
298
def __call__ (self , responses : SchemaPath ) -> Iterator [ValidationError ]:
293
299
for response_code , response in responses .items ():
300
+ assert isinstance (response_code , str )
294
301
yield from self .response_validator (response_code , response )
295
302
296
303
@@ -317,15 +324,17 @@ def __call__(
317
324
) -> Iterator [ValidationError ]:
318
325
assert self .operation_ids_registry is not None
319
326
320
- operation_id = operation .getkey ("operationId" )
321
- if (
322
- operation_id is not None
323
- and operation_id in self .operation_ids_registry
324
- ):
325
- yield DuplicateOperationIDError (
326
- f"Operation ID '{ operation_id } ' for '{ name } ' in '{ url } ' is not unique"
327
- )
328
- self .operation_ids_registry .append (operation_id )
327
+ if "operationId" in operation :
328
+ operation_id_value = (operation / "operationId" ).read_value ()
329
+ if (
330
+ operation_id_value is not None
331
+ and operation_id_value in self .operation_ids_registry
332
+ ):
333
+ yield DuplicateOperationIDError (
334
+ f"Operation ID '{ operation_id_value } ' for "
335
+ f"'{ name } ' in '{ url } ' is not unique"
336
+ )
337
+ self .operation_ids_registry .append (operation_id_value )
329
338
330
339
if "responses" in operation :
331
340
responses = operation / "responses"
@@ -392,6 +401,7 @@ def __call__(
392
401
yield from self .parameters_validator (parameters )
393
402
394
403
for field_name , operation in path_item .items ():
404
+ assert isinstance (field_name , str )
395
405
if field_name not in self .OPERATIONS :
396
406
continue
397
407
@@ -407,6 +417,7 @@ def path_validator(self) -> PathValidator:
407
417
408
418
def __call__ (self , paths : SchemaPath ) -> Iterator [ValidationError ]:
409
419
for url , path_item in paths .items ():
420
+ assert isinstance (url , str )
410
421
yield from self .path_validator (url , path_item )
411
422
412
423
@@ -416,8 +427,9 @@ def schemas_validator(self) -> SchemasValidator:
416
427
return cast (SchemasValidator , self .registry ["schemas" ])
417
428
418
429
def __call__ (self , components : SchemaPath ) -> Iterator [ValidationError ]:
419
- schemas = components .get ("schemas" , {})
420
- yield from self .schemas_validator (schemas )
430
+ if "schemas" in components :
431
+ schemas = components / "schemas"
432
+ yield from self .schemas_validator (schemas )
421
433
422
434
423
435
class RootValidator (KeywordValidator ):
0 commit comments