Skip to content

Commit 30c05c5

Browse files
authored
Merge pull request #146 from N3X15/develop
Fixes some issues on Windows
2 parents 9510c38 + c60a15e commit 30c05c5

5 files changed

Lines changed: 53 additions & 13 deletions

File tree

pyswagger/consts/private.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,18 @@
33

44
FILE_EXT_JSON = 'json'
55
FILE_EXT_YAML = 'yaml'
6+
FILE_EXT_YML = 'yml'
67

78
VALID_FILE_EXT = [
89
'.'+FILE_EXT_JSON,
910
'.'+FILE_EXT_YAML,
11+
'.'+FILE_EXT_YML,
1012
]
1113
SWAGGER_FILE_NAMES = [
1214
'resource_list' + '.' + FILE_EXT_JSON,
1315
'swagger' + '.' + FILE_EXT_JSON,
1416
'swagger' + '.' + FILE_EXT_YAML,
17+
'swagger' + '.' + FILE_EXT_YML,
1518
]
1619

1720
SCOPE_SEPARATOR = '!##!'

pyswagger/getter.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import six
77
import os
88
import logging
9+
import re
910

1011

1112
logger = logging.getLogger(__name__)
@@ -64,6 +65,12 @@ class LocalGetter(Getter):
6465
def __init__(self, path):
6566
super(LocalGetter, self).__init__(path)
6667

68+
if path.startswith('file://'):
69+
parsed = six.moves.urllib.parse.urlparse(path)
70+
path = parsed.path
71+
if re.match('^/[A-Z]+:', path) is not None:
72+
path = os.path.abspath(path[1:])
73+
6774
for n in private.SWAGGER_FILE_NAMES:
6875
if self.base_path.endswith(n):
6976
self.base_path = os.path.dirname(self.base_path)
@@ -82,13 +89,14 @@ def __init__(self, path):
8289
# - when 'path' points to a specific file, and its
8390
# extension is either 'json' or 'yaml'.
8491
_, ext = os.path.splitext(path)
85-
for e in [private.FILE_EXT_JSON, private.FILE_EXT_YAML]:
92+
for e in [private.FILE_EXT_JSON, private.FILE_EXT_YAML, private.FILE_EXT_YML]:
8693
if ext.endswith(e):
8794
self.base_path = os.path.dirname(path)
8895
self.urls = [path]
8996
break
9097
else:
91-
for e in [private.FILE_EXT_JSON, private.FILE_EXT_YAML]:
98+
for e in [private.FILE_EXT_JSON, private.FILE_EXT_YAML, private.FILE_EXT_YML]:
99+
#print(path + '.' + e)
92100
if os.path.isfile(path + '.' + e):
93101
self.urls = [path + '.' + e]
94102
break
@@ -163,4 +171,3 @@ def load(self, path):
163171
logger.info('to load: [{0}]'.format(path))
164172

165173
return self._path2dict.get(path, {})
166-

pyswagger/primitives/_model.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def apply_with(self, obj, val, ctx):
4646

4747
not_found = set(obj.required) - set(six.iterkeys(self))
4848
if len(not_found):
49-
raise ValueError('requirement not meet: {0}'.format(not_found))
49+
raise ValueError('Model missing required key(s): {0}'.format(', '.join(not_found)))
5050

5151
# remove assigned properties to avoid duplicated
5252
# primitive creation
@@ -75,7 +75,7 @@ def cleanup(self, val, ctx):
7575
return {}
7676

7777
def __eq__(self, other):
78-
""" equality operater,
78+
""" equality operater,
7979
will skip checking when both value are None or no attribute.
8080
8181
:param other: another model
@@ -97,4 +97,3 @@ def __eq__(self, other):
9797

9898
def __ne__(self, other):
9999
return not self.__eq__(other)
100-

pyswagger/tests/test_utils.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ def test_json_pointer(self):
4747
self.assertEqual(utils.jp_split(None), [])
4848
self.assertEqual(utils.jp_split('/~1~0test/qq/~0test/~1test/'), ['', '/~test', 'qq', '~test', '/test', ''])
4949

50+
51+
def test_derelativize_url(self):
52+
self.assertEquals(utils.derelativise_url('https://localhost/hurf/durf.json'), 'https://localhost/hurf/durf.json')
53+
self.assertEquals(utils.derelativise_url('https://localhost/hurf/./durf.json'), 'https://localhost/hurf/durf.json')
54+
self.assertEquals(utils.derelativise_url('https://localhost/hurf/../durf.json'), 'https://localhost/durf.json')
55+
self.assertEquals(utils.derelativise_url('https://localhost/hurf/.../durf.json'), 'https://localhost/durf.json')
5056
def test_scope_dict(self):
5157
""" ScopeDict """
5258
obj = {
@@ -386,4 +392,3 @@ def test_multiple_cycles_2(self):
386392
[2, 3, 5, 4, 2],
387393
[2, 3 ,4, 2]
388394
]))
389-

pyswagger/utils.py

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -297,9 +297,14 @@ def nv_tuple_list_replace(l, v):
297297
def path2url(p):
298298
""" Return file:// URL from a filename.
299299
"""
300-
return six.moves.urllib.parse.urljoin(
301-
'file:', six.moves.urllib.request.pathname2url(p)
302-
)
300+
# Python 3 is a bit different and does a better job.
301+
if sys.version_info[0] >= 3:
302+
import pathlib
303+
return pathlib.Path(p).as_uri()
304+
else:
305+
return six.moves.urllib.parse.urljoin(
306+
'file:', six.moves.urllib.request.pathname2url(p)
307+
)
303308

304309
def normalize_url(url):
305310
""" Normalize url
@@ -334,9 +339,10 @@ def url_join(url, path):
334339
""" url version of os.path.join
335340
"""
336341
p = six.moves.urllib.parse.urlparse(url)
342+
t = ('/'.join([p.path, path]),)
337343
return six.moves.urllib.parse.urlunparse(
338344
p[:2]+
339-
(os.path.join(p.path, path),)+
345+
t+ # os.sep is different on windows, don't use it here.
340346
p[3:]
341347
)
342348

@@ -366,7 +372,8 @@ def normalize_jr(jr, url=None):
366372
if p.scheme == '' and url:
367373
p = six.moves.urllib.parse.urlparse(url)
368374
# it's the path of relative file
369-
path = six.moves.urllib.parse.urlunparse(p[:2]+(os.path.join(os.path.dirname(p.path), path),)+p[3:])
375+
path = six.moves.urllib.parse.urlunparse(p[:2]+('/'.join([os.path.dirname(p.path), path]),)+p[3:])
376+
path = derelativise_url(path)
370377
else:
371378
path = url
372379

@@ -375,6 +382,26 @@ def normalize_jr(jr, url=None):
375382
else:
376383
return '#' + jp
377384

385+
def derelativise_url(url):
386+
'''
387+
Normalizes URLs, gets rid of .. and .
388+
'''
389+
parsed = six.moves.urllib.parse.urlparse(url)
390+
newpath=[]
391+
for chunk in parsed.path[1:].split('/'):
392+
if chunk == '.':
393+
continue
394+
elif chunk == '..':
395+
# parent dir.
396+
newpath=newpath[:-1]
397+
continue
398+
# TODO: Verify this behaviour.
399+
elif re.fullmatch(r'\.{3,}', chunk) is not None:
400+
# parent dir.
401+
newpath=newpath[:-1]
402+
continue
403+
newpath += [chunk]
404+
return six.moves.urllib.parse.urlunparse(parsed[:2]+('/'+('/'.join(newpath)),)+parsed[3:])
378405
def is_file_url(url):
379406
return url.startswith('file://')
380407

@@ -549,4 +576,3 @@ def patch_path(base_path, path):
549576
path = path[1:]
550577

551578
return path
552-

0 commit comments

Comments
 (0)