Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/openapi_schema_validator/_keywords.py: 26%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

121 statements  

1from copy import deepcopy 

2from typing import Any 

3from typing import Dict 

4from typing import Hashable 

5from typing import ItemsView 

6from typing import Iterator 

7from typing import List 

8from typing import Mapping 

9from typing import Union 

10 

11from jsonschema._keywords import allOf as _allOf 

12from jsonschema._keywords import anyOf as _anyOf 

13from jsonschema._keywords import oneOf as _oneOf 

14from jsonschema._utils import extras_msg 

15from jsonschema._utils import find_additional_properties 

16from jsonschema.exceptions import FormatError 

17from jsonschema.exceptions import ValidationError 

18from jsonschema.protocols import Validator 

19 

20 

21def handle_discriminator( 

22 validator: Validator, _: Any, instance: Any, schema: Mapping[Hashable, Any] 

23) -> Iterator[ValidationError]: 

24 """ 

25 Handle presence of discriminator in anyOf, oneOf and allOf. 

26 The behaviour is the same in all 3 cases because at most 1 schema will match. 

27 """ 

28 discriminator = schema["discriminator"] 

29 prop_name = discriminator["propertyName"] 

30 prop_value = instance.get(prop_name) 

31 if not prop_value: 

32 # instance is missing $propertyName 

33 yield ValidationError( 

34 f"{instance!r} does not contain discriminating property {prop_name!r}", 

35 context=[], 

36 ) 

37 return 

38 

39 # Use explicit mapping if available, otherwise try implicit value 

40 ref = ( 

41 discriminator.get("mapping", {}).get(prop_value) 

42 or f"#/components/schemas/{prop_value}" 

43 ) 

44 

45 if not isinstance(ref, str): 

46 # this is a schema error 

47 yield ValidationError( 

48 "{!r} mapped value for {!r} should be a string, was {!r}".format( 

49 instance, prop_value, ref 

50 ), 

51 context=[], 

52 ) 

53 return 

54 

55 try: 

56 validator._validate_reference(ref=ref, instance=instance) 

57 except: 

58 yield ValidationError( 

59 f"{instance!r} reference {ref!r} could not be resolved", 

60 context=[], 

61 ) 

62 return 

63 

64 yield from validator.descend(instance, {"$ref": ref}) 

65 

66 

67def anyOf( 

68 validator: Validator, 

69 anyOf: List[Mapping[Hashable, Any]], 

70 instance: Any, 

71 schema: Mapping[Hashable, Any], 

72) -> Iterator[ValidationError]: 

73 if "discriminator" not in schema: 

74 yield from _anyOf(validator, anyOf, instance, schema) 

75 else: 

76 yield from handle_discriminator(validator, anyOf, instance, schema) 

77 

78 

79def oneOf( 

80 validator: Validator, 

81 oneOf: List[Mapping[Hashable, Any]], 

82 instance: Any, 

83 schema: Mapping[Hashable, Any], 

84) -> Iterator[ValidationError]: 

85 if "discriminator" not in schema: 

86 yield from _oneOf(validator, oneOf, instance, schema) 

87 else: 

88 yield from handle_discriminator(validator, oneOf, instance, schema) 

89 

90 

91def allOf( 

92 validator: Validator, 

93 allOf: List[Mapping[Hashable, Any]], 

94 instance: Any, 

95 schema: Mapping[Hashable, Any], 

96) -> Iterator[ValidationError]: 

97 if "discriminator" not in schema: 

98 yield from _allOf(validator, allOf, instance, schema) 

99 else: 

100 yield from handle_discriminator(validator, allOf, instance, schema) 

101 

102 

103def type( 

104 validator: Validator, 

105 data_type: str, 

106 instance: Any, 

107 schema: Mapping[Hashable, Any], 

108) -> Iterator[ValidationError]: 

109 if instance is None: 

110 # nullable implementation based on OAS 3.0.3 

111 # * nullable is only meaningful if its value is true 

112 # * nullable: true is only meaningful in combination with a type 

113 # assertion specified in the same Schema Object. 

114 # * nullable: true operates within a single Schema Object 

115 if "nullable" in schema and schema["nullable"] == True: 

116 return 

117 yield ValidationError("None for not nullable") 

118 

119 if not validator.is_type(instance, data_type): 

120 data_repr = repr(data_type) 

121 yield ValidationError(f"{instance!r} is not of type {data_repr}") 

122 

123 

124def format( 

125 validator: Validator, 

126 format: str, 

127 instance: Any, 

128 schema: Mapping[Hashable, Any], 

129) -> Iterator[ValidationError]: 

130 if instance is None: 

131 return 

132 

133 if validator.format_checker is not None: 

134 try: 

135 validator.format_checker.check(instance, format) 

136 except FormatError as error: 

137 yield ValidationError(str(error), cause=error.cause) 

138 

139 

140def items( 

141 validator: Validator, 

142 items: Mapping[Hashable, Any], 

143 instance: Any, 

144 schema: Mapping[Hashable, Any], 

145) -> Iterator[ValidationError]: 

146 if not validator.is_type(instance, "array"): 

147 return 

148 

149 for index, item in enumerate(instance): 

150 yield from validator.descend(item, items, path=index) 

151 

152 

153def required( 

154 validator: Validator, 

155 required: List[str], 

156 instance: Any, 

157 schema: Mapping[Hashable, Any], 

158) -> Iterator[ValidationError]: 

159 if not validator.is_type(instance, "object"): 

160 return 

161 for property in required: 

162 if property not in instance: 

163 prop_schema = schema.get("properties", {}).get(property) 

164 if prop_schema: 

165 read_only = prop_schema.get("readOnly", False) 

166 write_only = prop_schema.get("writeOnly", False) 

167 if ( 

168 getattr(validator, "write", True) 

169 and read_only 

170 or getattr(validator, "read", True) 

171 and write_only 

172 ): 

173 continue 

174 yield ValidationError(f"{property!r} is a required property") 

175 

176 

177def read_required( 

178 validator: Validator, 

179 required: List[str], 

180 instance: Any, 

181 schema: Mapping[Hashable, Any], 

182) -> Iterator[ValidationError]: 

183 if not validator.is_type(instance, "object"): 

184 return 

185 for property in required: 

186 if property not in instance: 

187 prop_schema = schema.get("properties", {}).get(property) 

188 if prop_schema: 

189 write_only = prop_schema.get("writeOnly", False) 

190 if getattr(validator, "read", True) and write_only: 

191 continue 

192 yield ValidationError(f"{property!r} is a required property") 

193 

194 

195def write_required( 

196 validator: Validator, 

197 required: List[str], 

198 instance: Any, 

199 schema: Mapping[Hashable, Any], 

200) -> Iterator[ValidationError]: 

201 if not validator.is_type(instance, "object"): 

202 return 

203 for property in required: 

204 if property not in instance: 

205 prop_schema = schema.get("properties", {}).get(property) 

206 if prop_schema: 

207 read_only = prop_schema.get("readOnly", False) 

208 if read_only: 

209 continue 

210 yield ValidationError(f"{property!r} is a required property") 

211 

212 

213def additionalProperties( 

214 validator: Validator, 

215 aP: Union[Mapping[Hashable, Any], bool], 

216 instance: Any, 

217 schema: Mapping[Hashable, Any], 

218) -> Iterator[ValidationError]: 

219 if not validator.is_type(instance, "object"): 

220 return 

221 

222 extras = set(find_additional_properties(instance, schema)) 

223 

224 if not extras: 

225 return 

226 

227 if validator.is_type(aP, "object"): 

228 for extra in extras: 

229 for error in validator.descend(instance[extra], aP, path=extra): 

230 yield error 

231 elif validator.is_type(aP, "boolean"): 

232 if not aP: 

233 error = "Additional properties are not allowed (%s %s unexpected)" 

234 yield ValidationError(error % extras_msg(extras)) 

235 

236 

237def write_readOnly( 

238 validator: Validator, 

239 ro: bool, 

240 instance: Any, 

241 schema: Mapping[Hashable, Any], 

242) -> Iterator[ValidationError]: 

243 yield ValidationError(f"Tried to write read-only property with {instance}") 

244 

245 

246def read_writeOnly( 

247 validator: Validator, 

248 wo: bool, 

249 instance: Any, 

250 schema: Mapping[Hashable, Any], 

251) -> Iterator[ValidationError]: 

252 yield ValidationError(f"Tried to read write-only property with {instance}") 

253 

254 

255def not_implemented( 

256 validator: Validator, 

257 value: Any, 

258 instance: Any, 

259 schema: Mapping[Hashable, Any], 

260) -> Iterator[ValidationError]: 

261 return 

262 yield