diff --git a/jsonschema/compat.py b/jsonschema/compat.py index 952b14633..ce946a75b 100644 --- a/jsonschema/compat.py +++ b/jsonschema/compat.py @@ -1,3 +1,4 @@ +import contextlib import operator import sys @@ -27,7 +28,10 @@ urljoin, urlunsplit, SplitResult, urlsplit as _urlsplit # noqa ) from urllib import unquote # noqa - from urllib2 import urlopen # noqa + import urllib2 # noqa + def urlopen(*args, **kwargs): + return contextlib.closing(urllib2.urlopen(*args, **kwargs)) + str_types = basestring int_types = int, long iteritems = operator.methodcaller("iteritems") diff --git a/jsonschema/tests/test_validators.py b/jsonschema/tests/test_validators.py index 8bb38802e..f5d9872e6 100644 --- a/jsonschema/tests/test_validators.py +++ b/jsonschema/tests/test_validators.py @@ -4,7 +4,9 @@ from io import BytesIO from unittest import TestCase import json +import os import sys +import tempfile import unittest from twisted.trial.unittest import SynchronousTestCase @@ -22,6 +24,12 @@ from jsonschema.tests.compat import mock +if PY3: + from urllib.request import pathname2url +else: + from urllib import pathname2url + + def startswith(validator, startswith, instance, schema): if not instance.startswith(startswith): yield ValidationError(u"Whoops!") @@ -1341,6 +1349,15 @@ def fake_urlopen(url): pass self.assertEqual(resolved, 12) + def test_it_retrieves_local_refs_via_urlopen(self): + with tempfile.NamedTemporaryFile(delete=False, mode='wt') as tempf: + self.addCleanup(os.remove, tempf.name) + json.dump({'foo': 'bar'}, tempf) + + ref = "file://{}#foo".format(pathname2url(tempf.name)) + with self.resolver.resolving(ref) as resolved: + self.assertEqual(resolved, 'bar') + def test_it_can_construct_a_base_uri_from_a_schema(self): schema = {"id": "foo"} resolver = validators.RefResolver.from_schema(