Provide own version of urlsplit and urldefrag that work with unknown schemes, fix #104
This commit is contained in:
@@ -3,7 +3,7 @@ import json
|
|||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from jsonschema.compat import str_types, urlparse, MutableMapping
|
from jsonschema.compat import str_types, MutableMapping, urlsplit
|
||||||
|
|
||||||
|
|
||||||
class URIDict(MutableMapping):
|
class URIDict(MutableMapping):
|
||||||
@@ -13,7 +13,7 @@ class URIDict(MutableMapping):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def normalize(self, uri):
|
def normalize(self, uri):
|
||||||
return urlparse.urlsplit(uri).geturl()
|
return urlsplit(uri).geturl()
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.store = dict()
|
self.store = dict()
|
||||||
|
@@ -11,15 +11,18 @@ PY3 = sys.version_info[0] >= 3
|
|||||||
|
|
||||||
if PY3:
|
if PY3:
|
||||||
zip = zip
|
zip = zip
|
||||||
from urllib import parse as urlparse
|
from urllib.parse import (
|
||||||
from urllib.parse import unquote
|
unquote, urljoin, urlunsplit, SplitResult, urlsplit as _urlsplit
|
||||||
|
)
|
||||||
from urllib.request import urlopen
|
from urllib.request import urlopen
|
||||||
str_types = str,
|
str_types = str,
|
||||||
int_types = int,
|
int_types = int,
|
||||||
iteritems = operator.methodcaller("items")
|
iteritems = operator.methodcaller("items")
|
||||||
else:
|
else:
|
||||||
from itertools import izip as zip # noqa
|
from itertools import izip as zip # noqa
|
||||||
import urlparse # noqa
|
from urlparse import (
|
||||||
|
urljoin, urlunsplit, SplitResult, urlsplit as _urlsplit # noqa
|
||||||
|
)
|
||||||
from urllib import unquote # noqa
|
from urllib import unquote # noqa
|
||||||
from urllib2 import urlopen # noqa
|
from urllib2 import urlopen # noqa
|
||||||
str_types = basestring
|
str_types = basestring
|
||||||
@@ -27,4 +30,22 @@ else:
|
|||||||
iteritems = operator.methodcaller("iteritems")
|
iteritems = operator.methodcaller("iteritems")
|
||||||
|
|
||||||
|
|
||||||
|
# On python < 3.3 fragments are not handled properly with unknown schemes
|
||||||
|
def urlsplit(url):
|
||||||
|
scheme, netloc, path, query, fragment = _urlsplit(url)
|
||||||
|
if "#" in path:
|
||||||
|
path, fragment = path.split("#", 1)
|
||||||
|
return SplitResult(scheme, netloc, path, query, fragment)
|
||||||
|
|
||||||
|
|
||||||
|
def urldefrag(url):
|
||||||
|
if "#" in url:
|
||||||
|
s, n, p, q, frag = urlsplit(url)
|
||||||
|
defrag = urlunsplit((s, n, p, q, ''))
|
||||||
|
else:
|
||||||
|
defrag = url
|
||||||
|
frag = ''
|
||||||
|
return defrag, frag
|
||||||
|
|
||||||
|
|
||||||
# flake8: noqa
|
# flake8: noqa
|
||||||
|
@@ -15,7 +15,7 @@ except ImportError:
|
|||||||
|
|
||||||
from jsonschema import _utils
|
from jsonschema import _utils
|
||||||
from jsonschema.compat import (
|
from jsonschema.compat import (
|
||||||
PY3, Sequence, urlparse, unquote, urlopen, str_types, int_types, iteritems,
|
PY3, Sequence, urljoin, urlsplit, urldefrag, unquote, urlopen, str_types, int_types, iteritems,
|
||||||
)
|
)
|
||||||
from jsonschema._format import FormatError
|
from jsonschema._format import FormatError
|
||||||
|
|
||||||
@@ -629,7 +629,7 @@ class RefResolver(object):
|
|||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def in_scope(self, scope):
|
def in_scope(self, scope):
|
||||||
old_scope = self.resolution_scope
|
old_scope = self.resolution_scope
|
||||||
self.resolution_scope = urlparse.urljoin(old_scope, scope)
|
self.resolution_scope = urljoin(old_scope, scope)
|
||||||
try:
|
try:
|
||||||
yield
|
yield
|
||||||
finally:
|
finally:
|
||||||
@@ -645,8 +645,8 @@ class RefResolver(object):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
full_uri = urlparse.urljoin(self.resolution_scope, ref)
|
full_uri = urljoin(self.resolution_scope, ref)
|
||||||
uri, fragment = urlparse.urldefrag(full_uri)
|
uri, fragment = urldefrag(full_uri)
|
||||||
if not uri:
|
if not uri:
|
||||||
uri = self.base_uri
|
uri = self.base_uri
|
||||||
|
|
||||||
@@ -718,7 +718,7 @@ class RefResolver(object):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
scheme = urlparse.urlsplit(uri).scheme
|
scheme = urlsplit(uri).scheme
|
||||||
|
|
||||||
if scheme in self.handlers:
|
if scheme in self.handlers:
|
||||||
result = self.handlers[scheme](uri)
|
result = self.handlers[scheme](uri)
|
||||||
|
@@ -861,11 +861,11 @@ class TestRefResolver(unittest.TestCase):
|
|||||||
self.assertEqual(resolved, self.referrer["properties"]["foo"])
|
self.assertEqual(resolved, self.referrer["properties"]["foo"])
|
||||||
|
|
||||||
def test_it_resolves_local_refs_with_id(self):
|
def test_it_resolves_local_refs_with_id(self):
|
||||||
schema = {"id": "/bar/schema#", "a": {"foo": "bar"}}
|
schema = {"id": "foo://bar/schema#", "a": {"foo": "bar"}}
|
||||||
resolver = RefResolver.from_schema(schema)
|
resolver = RefResolver.from_schema(schema)
|
||||||
with resolver.resolving("#/a") as resolved:
|
with resolver.resolving("#/a") as resolved:
|
||||||
self.assertEqual(resolved, schema["a"])
|
self.assertEqual(resolved, schema["a"])
|
||||||
with resolver.resolving("/bar/schema#/a") as resolved:
|
with resolver.resolving("foo://bar/schema#/a") as resolved:
|
||||||
self.assertEqual(resolved, schema["a"])
|
self.assertEqual(resolved, schema["a"])
|
||||||
|
|
||||||
def test_it_retrieves_stored_refs(self):
|
def test_it_retrieves_stored_refs(self):
|
||||||
|
Reference in New Issue
Block a user