-
-
Notifications
You must be signed in to change notification settings - Fork 593
complex schema with parent-child-grandchild references in multiple subdirectories aren't resolved correctly #601
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Thank you!
Very much agreed! Which obviously makes them hard to fix, or know when there's some user error involved. I'll have to read your example more carefully, but the only concrete thing I'd say immediately is "the known bugs are to me essentially the skipped tests in the test suite". So IIRC there are basically 2 there, one for location-independent identifiers, and one for change-of-ID in a subschema. The former is unlikely to be relevant but you might want to have a look at the second one. And the "rule" there is basically that But very much do appreciate the full example! |
Here is the cause of this problem I think: Layer 1 references the file based on base_uri, so does Layer 2. The Hi @Julian, what do you think of the solution? |
@willson-chen certainly happy to review a patch! |
So hopefully I haven't confused myself here, and apologies for this taking so long, but I think having now looked at this yet again that everything is actually correct here as-is. (I still want to add another test upstream regardless, since this case isn't covered, but that's a different story).
This is/was the correct fix -- the If you have a schema which references In your last example, i.e. after you changed to
As you say, it's looking for point.json in ./my_complex_schemas/.. instead of ./my_complex_schemas, but that's because that's the URI you gave for Specifically, if I take the same layout you mentioned:
Then with the modification you mentioned: ⊙ git diff julian@Airm ●
diff --git a/my_complex_schemas/basic_shapes/circle.json b/my_complex_schemas/basic_shapes/circle.json
index 3cf3c39..d73d86d 100644
--- a/my_complex_schemas/basic_shapes/circle.json
+++ b/my_complex_schemas/basic_shapes/circle.json
@@ -1,7 +1,7 @@
{
"type": "object",
"properties": {
- "center": { "$ref": "point.json" },
+ "center": { "$ref": "../point.json" },
"radius": {"type": "number"}
},
"required": ["center", "radius"]
diff --git a/my_complex_schemas/basic_shapes/rectangle.json b/my_complex_schemas/basic_shapes/rectangle.json
index 30bce78..bdf4797 100644
--- a/my_complex_schemas/basic_shapes/rectangle.json
+++ b/my_complex_schemas/basic_shapes/rectangle.json
@@ -1,10 +1,10 @@
{
"type": "object",
"properties": {
- "top_left": { "$ref": "point.json" },
- "top_right": { "$ref": "point.json" },
- "bottom_left": { "$ref": "point.json" },
- "bottom_right": { "$ref": "point.json" }
+ "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"]
} and with code like: from pathlib import Path
import json
import jsonschema
base = Path("./my_complex_schemas/").absolute()
rectangle = base / "basic_shapes/rectangle.json"
rectangle_with_hole = base / "complex_shapes/rectangle_with_hole.json"
# schema = json.loads(rectangle.read_text())
schema = json.loads(rectangle_with_hole.read_text())
resolver = jsonschema.RefResolver(base_uri=f"{base.as_uri()}/", referrer=schema)
valid_data = {"center": {"x": 10, "y": 20}, "radius": 2}
jsonschema.validate(valid_data, schema, resolver=resolver) -- which is essentially the same as what you had just with some Pathlib conveniences that didn't exist awhile ago -- I can now validate with either schema, but you need to be careful to pass a base URI that's really the base URI you mean and have used in whichver root schema you pass -- if you move around which directory your schema lives in, you may need to adjust it. Hopefully some of the above helps -- as I say, I'm reasonably confident this is all working as-is, but |
Ok, so in short I thought that references to schemas should be defined with respect to base uri, but they should be defined with respect to current schema instead! My bad, and thank you for taking time to understand and answer my problem :) |
Precisely! And no problem! |
Uh oh!
There was an error while loading. Please reload this page.
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.json
my_complex_schemas/point.json
my_complex_schemas/basic_shapes/circle.json
my_complex_schemas/basic_shapes/rectangle.json
my_complex_schemas/complex_shapes/rectangle_with_hole.json
With above, when running from directory above
my_complex_schemas
directory, I can correctly validatecircle
schema that referencepoint
schema, e.g.:and similar test passes for rectangle schema.
However, I can't validate
rectangle_with_hole
schema that referencescircle
andrectangle
schemas.For code
I get exception
That means that when resolver encounters
"$ref": "basic_shapes/circle.json"
insidemy_complex_schemas/complex_shapes/rectangle_with_hole.json
, entersbasic_shapes/circle.json
and encounters"$ref": "point.json"
, it tries to read it frommy_complex_schemas/basic_shapes/point.json
instead ofmy_complex_schemas/point.json
, even thoughbase_uri
is set tobase_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 inbasic_shapes/circle.json
andbasic_shapes/rectangle.json
to"$ref": "../point.json"
. But if I do that,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?
The text was updated successfully, but these errors were encountered: