@@ -63,7 +63,7 @@ def maybe_nullable(beam_type, nullable):
6363
6464 json_type = json_schema .get ('type' , None )
6565 if json_type != 'object' :
66- raise ValueError ('Expected object type, got {json_type}.' )
66+ raise ValueError (f 'Expected object type, got { json_type } .' )
6767 if 'properties' not in json_schema :
6868 # Technically this is a valid (vacuous) schema, but as it's not generally
6969 # meaningful, throw an informative error instead.
@@ -314,24 +314,34 @@ def _validate_compatible(weak_schema, strong_schema):
314314 return
315315 if weak_schema ['type' ] != strong_schema ['type' ]:
316316 raise ValueError (
317- 'Incompatible types: %r vs %r' %
318- (weak_schema ['type' ] != strong_schema ['type' ]))
317+ f"Incompatible types: { weak_schema ['type' ]} vs { strong_schema ['type' ]} " )
319318 if weak_schema ['type' ] == 'array' :
320319 _validate_compatible (weak_schema ['items' ], strong_schema ['items' ])
321- elif weak_schema == 'object' :
320+ elif weak_schema ['type' ] == 'object' :
321+ # If the weak schema allows for arbitrary keys (is a map),
322+ # the strong schema must also allow for arbitrary keys.
323+ if weak_schema .get ('additionalProperties' ):
324+ if not strong_schema .get ('additionalProperties' , True ):
325+ raise ValueError ('Incompatible types: map vs object' )
326+ _validate_compatible (
327+ weak_schema ['additionalProperties' ],
328+ strong_schema ['additionalProperties' ])
322329 for required in strong_schema .get ('required' , []):
323330 if required not in weak_schema ['properties' ]:
324- raise ValueError ('Missing or unkown property %r' % required )
325- for name , spec in weak_schema .get ('properties' , {}):
331+ raise ValueError (f"Missing or unknown property '{ required } '" )
332+ for name , spec in weak_schema .get ('properties' , {}).items ():
333+
326334 if name in strong_schema ['properties' ]:
327335 try :
328336 _validate_compatible (spec , strong_schema ['properties' ][name ])
329337 except Exception as exn :
330- raise ValueError ('Incompatible schema for %r' % name ) from exn
331- elif not strong_schema .get ('additionalProperties' ):
338+ raise ValueError (f"Incompatible schema for '{ name } '" ) from exn
339+ elif not strong_schema .get ('additionalProperties' , True ):
340+ # The property is not explicitly in the strong schema, and the strong
341+ # schema does not allow for extra properties.
332342 raise ValueError (
333- ' Prohibited property: {property}; '
334- ' perhaps additionalProperties: False is missing?' )
343+ f" Prohibited property: ' { name } '; "
344+ " perhaps additionalProperties: False is missing?" )
335345
336346
337347def row_validator (beam_schema : schema_pb2 .Schema ,
0 commit comments