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
Add a context manager to RefResolver #60
Add a context manager to RefResolver #60
Conversation
I'm confused, I've been slightly busy this week so haven't been following so closely, but what problem is this aiming to solve? |
So, for example, in these tests, (which currently fail,) we are validating a schema with a $ref to another schema. This schema in turn has $refs to itself (#), currently, when evaluating those $refs, our resolver still looks them up in the context of our original schema, this branch keeps track of the proper context for which we should be resolving the $refs. Did that make sense? It's a bit confusing. |
I also have remote URIs adding to the RefResolver store in this branch. That has nothing to do with this change and I didn't intend to include it. |
I specifically avoided the latter. Caching is good and we should have one way to make a ref resolver that caches, but I'm not sure I like it as the default. Actually I guess now thinking again I do like it, but there should be a cache_remote=False flag or the like in the constructor to turn it off. |
As for the main bug here, I have to think about this a bit more but doesn't it just sound like the referring document should be provided to resolve, not init? |
Yeah, I thought about that, we don't necessarily have access to it from validate_ref though, as the |
Ah, OK. How about removing it from with resolver.enter_context(schema):
resolver.resolve(whatever) which is fairly close to what you have I guess. And then having refresolver raise an error if no context is set during a resolve where one is needed. |
Or maybe |
That could be better, we still have the issue of not necessarily having the proper context available from validate_ref though. The |
Oh it should be the whole schema? then just always use self.schema no? |
How about when we are inside a remote $ref though? In that case the context needs to be the base of the remote schema. |
In which case resolve_remote would call in_context as well. I'm probably still not thinking clearly here? |
Probably going to have to fiddle with this later to see where the problems crop up |
Hmm, you could be right, let me see what I can come up with. |
Yeah, I'm not coming up with any better ways where we track the context outside of RefResolver. RefResolver is the one who needs to calculate the new context, so it seems like we shouldn't be worried about it externally. If we set the current context from outside we'd end up with something like:
Which doesn't feel any better to me. Maybe I'm missing something, see if you come up with something better while playing around. |
Also, even with my above idea we'd still need to set the initial context in RefResolver.init I don't know where we'd put the |
@Julian I guess the crux of the matter is this:
For these reasons, I picked to keep the current context entirely within RefResolver, and combine the context change with a document lookup. One thing is clear however, if there is not a better way to do this, the name |
Added a couple tests to the suite that should test the current problem. json-schema-org/JSON-Schema-Test-Suite#29 |
Made a separate PR for the remote caching stuff, I might have a better idea for the ref context stuff, I'll give it a try. |
@Julian Okay, scrapped the old stuff, did it slightly differently. I think it's at least slightly better now, not sure about the method names still, especially |
Maybe scrap |
I'm not neglecting this :P I'll try to give it some poking tonight. |
I think at least the method name is a bit better now. |
Okay, I think I have a better idea. We move the store to be a class attribute of def validate_ref(self, ref, instance, schema):
with self.with_resolver(self.resolver.from_uri(ref)):
resolved = self.resolver.resolve(ref)
for error in self.iter_errors(instance, resolved):
yield error |
I think I like that idea. We could also then add inline addressing support by scanning through the schema on EDIT: Hmm, that might not be as easy as I thought, as there can be id keys in dicts which are not schemas. Well, that bit will need more thought. |
Seems whatever solution we settle on needs to be expanded more than what I currently have here. I explained the issue in #66 |
Going to close this. We can discuss further in #66, I'll make another pull request once we have more tests going. |
3cef243 Applies to Draft4 as well. f323723 Check comparisons for very negative numbers as well. c73cf22 Merge pull request #60 from gilesbowkett/added-jsck-to-who-uses-it e77c86a jsck uses JSON Schema Test Suite 1a96775 Merge pull request #57 from tanaka-tatsuya/fix/max-length-test-case b124928 fixed maxLength test case git-subtree-dir: json git-subtree-split: 3cef243acce1290c8bbbc546f7f3fcbd6c10ff8b
@Julian Still need to come up with some more tests, and fix one current test to work with the new method to make sure this is working as intended. Just wanted to get your thoughts on this method of handling nested $ref resolution before proceeding.