-
-
Notifications
You must be signed in to change notification settings - Fork 610
Description
There are already quite a few issues related to RefResolver not working correctly for complex schemas, but many of them don't include much code, and none that I saw includes multiple subdirectories.
In this issue I included code that shows that jsonschema doesn't resolve file references correctly for nested references in multiple directories.
System info:
OSX
Python 3.6.8
jsonschema version: '3.0.1'
Project setup:
.
└── my_complex_schemas
├── basic_shapes
│ ├── circle.json
│ └── rectangle.json
├── complex_shapes
│ └── rectangle_with_hole.json
└── point.jsonmy_complex_schemas/point.json
{
"type": "object",
"properties": {
"x": { "type": "number" },
"y": { "type": "number" }
},
"required": ["x", "y"]
}my_complex_schemas/basic_shapes/circle.json
{
"type": "object",
"properties": {
"center": { "$ref": "point.json" },
"radius": {"type": "number"}
},
"required": ["center", "radius"]
}my_complex_schemas/basic_shapes/rectangle.json
{
"type": "object",
"properties": {
"top_left": { "$ref": "point.json" },
"top_right": { "$ref": "point.json" },
"bottom_left": { "$ref": "point.json" },
"bottom_right": { "$ref": "point.json" }
},
"required": ["top_left", "top_right", "bottom_left", "bottom_right"]
}my_complex_schemas/complex_shapes/rectangle_with_hole.json
{
"type": "object",
"allOf": [
{ "$ref": "basic_shapes/rectangle.json" }
],
"properties": {
"hole": { "$ref": "basic_shapes/circle.json" }
},
"required": ["hole"]
}With above, when running from directory above my_complex_schemas directory, I can correctly validate circle schema that reference point schema, e.g.:
with open("./my_complex_schemas/basic_shapes/circle.json") as file:
schema = json.load(file)
base_uri = "file://{}/".format(os.path.abspath("./my_complex_schemas"))
resolver = jsonschema.RefResolver(base_uri=base_uri, referrer=schema)
valid_data = {"center": {"x": 10, "y": 20}, "radius": 2}
jsonschema.validate(valid_data, schema, resolver=resolver)and similar test passes for rectangle schema.
However, I can't validate rectangle_with_hole schema that references circle and rectangle schemas.
For code
with open("./my_complex_schemas/complex_shapes/rectangle_with_hole.json") as file:
schema = json.load(file)
base_uri = "file://{}/".format(os.path.abspath("./my_complex_schemas"))
resolver = jsonschema.RefResolver(base_uri=base_uri, referrer=schema)
valid_data = {
"top_left": {"x": 10, "y": 10},
"top_right": {"x": 20, "y": 10},
"bottom_left": {"x": 10, "y": 20},
"bottom_right": {"x": 20, "y": 20},
"hole": {"center": {"x": 20, "y": 20}, "radius": 7}
}
jsonschema.validate(valid_data, schema, resolver=resolver)I get exception
jsonschema.exceptions.RefResolutionError: <urlopen error [Errno 2] No such file or directory: '/Users/kuba/Projects/code/sketchpad/python/python_sketchpad/my_complex_schemas/basic_shapes/point.json'>That means that when resolver encounters "$ref": "basic_shapes/circle.json" inside my_complex_schemas/complex_shapes/rectangle_with_hole.json, enters basic_shapes/circle.json and encounters "$ref": "point.json", it tries to read it from my_complex_schemas/basic_shapes/point.json instead of my_complex_schemas/point.json, even though base_uri is set to base_uri = "file://{}/".format(os.path.abspath("./my_complex_schemas")).
I can get my_complex_schemas/complex_shapes/rectangle_with_hole.json to validate if I change references in basic_shapes/circle.json and basic_shapes/rectangle.json to "$ref": "../point.json". But if I do that,
with open("./my_complex_schemas/basic_shapes/circle.json") as file:
schema = json.load(file)
base_uri = "file://{}/".format(os.path.abspath("./my_complex_schemas"))
resolver = jsonschema.RefResolver(base_uri=base_uri, referrer=schema)
valid_data = {"center": {"x": 10, "y": 20}, "radius": 2}
jsonschema.validate(valid_data, schema, resolver=resolver)fails with
jsonschema.exceptions.RefResolutionError: <urlopen error [Errno 2] No such file or directory: '/Users/kuba/Projects/code/sketchpad/python/python_sketchpad/point.json'>that is in this case resolves looks for point.json in ./my_complex_schemas/.. instead of ./my_complex_schemas, which is expected.
Hope above will help to make a unit test that fixes resolver.
Or maybe the problem is between the chair and the keyboard, and I missed some important setting?