diff --git a/jsonschema/tests/test_validators.py b/jsonschema/tests/test_validators.py index 7e773776b..1b21804ef 100644 --- a/jsonschema/tests/test_validators.py +++ b/jsonschema/tests/test_validators.py @@ -1260,7 +1260,7 @@ def test_custom_uri_scheme_handlers(self): ) with resolver.resolving(ref) as resolved: self.assertEqual(resolved, schema) - foo_handler.assert_called_once_with(ref) + foo_handler.assert_called_once_with(ref, referrer={}) def test_cache_remote_on(self): ref = "foo://bar" @@ -1272,7 +1272,7 @@ def test_cache_remote_on(self): pass with resolver.resolving(ref): pass - foo_handler.assert_called_once_with(ref) + foo_handler.assert_called_once_with(ref, referrer={}) def test_cache_remote_off(self): ref = "foo://bar" @@ -1302,6 +1302,36 @@ def test_helpful_error_message_on_failed_pop_scope(self): resolver.pop_scope() self.assertIn("Failed to pop the scope", str(exc.exception)) + def test_scheme_default_fallback(self): + ref = './paths.json' + file_handler = mock.Mock() + resolver = validators.RefResolver( + "", "", handlers={"file": file_handler} + ) + with resolver.resolving(ref): + pass + file_handler.assert_called_with(ref, referrer='') + + def test_relative_resolver(self): + def file_handler(uri, referrer=None): + # Crude, do not use as a reference implementation + import os.path + no_scheme = referrer[7:] # file:/// 0-based + return 'file://' + os.path.abspath(os.path.join(no_scheme, uri)) + + ref = '../../schemas/common.json' + base = 'file:///home/julian/spec/' + referrer = base + 'components/common.json' + expected = base + 'schemas/common.json' + resolver = validators.RefResolver( + "", referrer, handlers={"file": file_handler} + ) + with resolver.resolving(ref): + pass + + self.assertTrue(ref in resolver.store) + self.assertEqual(resolver.store[ref], expected) + class UniqueTupleItemsMixin(object): """ diff --git a/jsonschema/validators.py b/jsonschema/validators.py index 28f2f6f8f..38e7ed1e9 100644 --- a/jsonschema/validators.py +++ b/jsonschema/validators.py @@ -541,6 +541,8 @@ class RefResolver(object): Whether remote refs should be cached after first resolution """ + default_scheme = 'file' + """ If urlsplit() does not find a scheme, we use this one. """ def __init__( self, @@ -739,9 +741,11 @@ def resolve_remote(self, uri): requests = None scheme = urlsplit(uri).scheme + if not scheme: + scheme = self.default_scheme if scheme in self.handlers: - result = self.handlers[scheme](uri) + result = self.handlers[scheme](uri, referrer=self.referrer) elif ( scheme in [u"http", u"https"] and requests and