Provide own version of urlsplit and urldefrag that work with unknown schemes, fix #104

This commit is contained in:
Chase Sterling
2013-05-13 11:40:28 -04:00
parent fc75480f09
commit f50e4538ca
4 changed files with 33 additions and 12 deletions

View File

@@ -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()

View File

@@ -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

View File

@@ -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)

View File

@@ -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):