Skip to content

Commit f50e453

Browse files
committed
Provide own version of urlsplit and urldefrag that work with unknown schemes, fix #104
1 parent fc75480 commit f50e453

File tree

4 files changed

+33
-12
lines changed

4 files changed

+33
-12
lines changed

jsonschema/_utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import re
44
import os
55

6-
from jsonschema.compat import str_types, urlparse, MutableMapping
6+
from jsonschema.compat import str_types, MutableMapping, urlsplit
77

88

99
class URIDict(MutableMapping):
@@ -13,7 +13,7 @@ class URIDict(MutableMapping):
1313
"""
1414

1515
def normalize(self, uri):
16-
return urlparse.urlsplit(uri).geturl()
16+
return urlsplit(uri).geturl()
1717

1818
def __init__(self, *args, **kwargs):
1919
self.store = dict()

jsonschema/compat.py

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,41 @@
1111

1212
if PY3:
1313
zip = zip
14-
from urllib import parse as urlparse
15-
from urllib.parse import unquote
14+
from urllib.parse import (
15+
unquote, urljoin, urlunsplit, SplitResult, urlsplit as _urlsplit
16+
)
1617
from urllib.request import urlopen
1718
str_types = str,
1819
int_types = int,
1920
iteritems = operator.methodcaller("items")
2021
else:
2122
from itertools import izip as zip # noqa
22-
import urlparse # noqa
23+
from urlparse import (
24+
urljoin, urlunsplit, SplitResult, urlsplit as _urlsplit # noqa
25+
)
2326
from urllib import unquote # noqa
2427
from urllib2 import urlopen # noqa
2528
str_types = basestring
2629
int_types = int, long
2730
iteritems = operator.methodcaller("iteritems")
2831

2932

33+
# On python < 3.3 fragments are not handled properly with unknown schemes
34+
def urlsplit(url):
35+
scheme, netloc, path, query, fragment = _urlsplit(url)
36+
if "#" in path:
37+
path, fragment = path.split("#", 1)
38+
return SplitResult(scheme, netloc, path, query, fragment)
39+
40+
41+
def urldefrag(url):
42+
if "#" in url:
43+
s, n, p, q, frag = urlsplit(url)
44+
defrag = urlunsplit((s, n, p, q, ''))
45+
else:
46+
defrag = url
47+
frag = ''
48+
return defrag, frag
49+
50+
3051
# flake8: noqa

jsonschema/validators.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
from jsonschema import _utils
1717
from jsonschema.compat import (
18-
PY3, Sequence, urlparse, unquote, urlopen, str_types, int_types, iteritems,
18+
PY3, Sequence, urljoin, urlsplit, urldefrag, unquote, urlopen, str_types, int_types, iteritems,
1919
)
2020
from jsonschema._format import FormatError
2121

@@ -629,7 +629,7 @@ def from_schema(cls, schema, *args, **kwargs):
629629
@contextlib.contextmanager
630630
def in_scope(self, scope):
631631
old_scope = self.resolution_scope
632-
self.resolution_scope = urlparse.urljoin(old_scope, scope)
632+
self.resolution_scope = urljoin(old_scope, scope)
633633
try:
634634
yield
635635
finally:
@@ -645,8 +645,8 @@ def resolving(self, ref):
645645
646646
"""
647647

648-
full_uri = urlparse.urljoin(self.resolution_scope, ref)
649-
uri, fragment = urlparse.urldefrag(full_uri)
648+
full_uri = urljoin(self.resolution_scope, ref)
649+
uri, fragment = urldefrag(full_uri)
650650
if not uri:
651651
uri = self.base_uri
652652

@@ -718,7 +718,7 @@ def resolve_remote(self, uri):
718718
719719
"""
720720

721-
scheme = urlparse.urlsplit(uri).scheme
721+
scheme = urlsplit(uri).scheme
722722

723723
if scheme in self.handlers:
724724
result = self.handlers[scheme](uri)

test_jsonschema.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -861,11 +861,11 @@ def test_it_resolves_local_refs(self):
861861
self.assertEqual(resolved, self.referrer["properties"]["foo"])
862862

863863
def test_it_resolves_local_refs_with_id(self):
864-
schema = {"id": "/bar/schema#", "a": {"foo": "bar"}}
864+
schema = {"id": "foo://bar/schema#", "a": {"foo": "bar"}}
865865
resolver = RefResolver.from_schema(schema)
866866
with resolver.resolving("#/a") as resolved:
867867
self.assertEqual(resolved, schema["a"])
868-
with resolver.resolving("/bar/schema#/a") as resolved:
868+
with resolver.resolving("foo://bar/schema#/a") as resolved:
869869
self.assertEqual(resolved, schema["a"])
870870

871871
def test_it_retrieves_stored_refs(self):

0 commit comments

Comments
 (0)