Skip to content

Commit

Permalink
Merge branch 'release/0.8.38'
Browse files Browse the repository at this point in the history
  • Loading branch information
mission-liao committed Jun 24, 2018
2 parents ed0d508 + 05adf2f commit 4a33366
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 9 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ branches:

python:
- "2.7"
- "3.3"
- "3.4"
- "3.5"
- "3.6"
install:
Expand Down
5 changes: 5 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
## Changes

### 0.8.38

- Allow to access headers with case insensitive keys
- Drop support to py3.3 because of Tornado

### 0.8.37

- Fix loading error on 'yaml' document
Expand Down
2 changes: 1 addition & 1 deletion pyswagger/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = '0.8.37'
__version__ = '0.8.38'

from .getter import Getter
from .core import App, Security
Expand Down
8 changes: 4 additions & 4 deletions pyswagger/io.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import absolute_import
from .primitives.comm import PrimJSONEncoder
from .utils import final, deref
from .utils import final, deref, CaseInsensitiveDict
from pyswagger import errs
from uuid import uuid4
import six
Expand Down Expand Up @@ -33,7 +33,7 @@ def __init__(self, op, params):
self.__p = params
self.__url = self.__op.url
self.__path = self.__op.path
self.__header = {}
self.__header = CaseInsensitiveDict()

self.__consume = None
self.__produce = None
Expand All @@ -42,7 +42,7 @@ def __init__(self, op, params):
def reset(self):
self.__url = self.__op.url
self.__path = self.__op.path
self.__header = {}
self.__header = CaseInsensitiveDict()
self.__data = None

def consume(self, consume):
Expand Down Expand Up @@ -350,7 +350,7 @@ def __init__(self, op):

# init properties
self.__status = None
self.__header = {}
self.__header = CaseInsensitiveDict()

# options
self.__raw_body_only = False
Expand Down
6 changes: 5 additions & 1 deletion pyswagger/primitives/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,11 @@ def __init__(self):

def get(self, _type, _format=None):
r = self._map.get(_type, None)
return (None, None) if r == None else r.get(_format, (None, None))
if r is None:
return (None, None)
if _format in r:
return r.get(_format)
return r.get(None)

def register(self, _type, _format, creater, _2nd_pass=None):
""" register a type/format handler when producing primitives
Expand Down
2 changes: 1 addition & 1 deletion pyswagger/primitives/_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def __init__(self):
super(Model, self).__init__()

def apply_with(self, obj, val, ctx):
""" recursivly apply Schema object
""" recursively apply Schema object
:param obj.Model obj: model object to instruct how to create this model
:param dict val: things used to construct this model
Expand Down
2 changes: 1 addition & 1 deletion pyswagger/primitives/_str.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def validate_str(obj, ret, val, ctx):
if obj.maxLength and len(ret) > obj.maxLength:
raise ValidationError('[{0}] is longer than {1} characters'.format(ret, str(obj.maxLength)))
if obj.minLength and len(ret) < obj.minLength:
raise ValidationError('[{0}] is shoter than {1} characters'.format(ret, str(obj.minLength)))
raise ValidationError('[{0}] is shorter than {1} characters'.format(ret, str(obj.minLength)))

# TODO: handle pattern
return val
Expand Down
25 changes: 25 additions & 0 deletions pyswagger/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,3 +429,28 @@ def test_multiple_cycles_2(self):
[2, 3, 5, 4, 2],
[2, 3 ,4, 2]
]))

def test_case_insensitive_dict(self):
""" test utils.CaseInsensitiveDict
"""
normal = utils.CaseInsensitiveDict()
normal['Content-Type'] = 'application/json'
self.assertTrue('Content-Type' in normal)
self.assertTrue('content-type' in normal)
self.assertEqual(normal['content-type'], 'application/json')

# test iteration
for k, v in normal.iteritems():
self.assertEqual(k, 'Content-Type')
self.assertEqual(v, 'application/json')
break
else:
# should not reach here
self.assertTrue(False)

for v in normal.itervalues():
self.assertEqual(v, 'application/json')
break
else:
# should not reach here
self.assertTrue(False)
43 changes: 43 additions & 0 deletions pyswagger/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import os
import operator
import functools
import collections

#TODO: accept varg
def scope_compose(scope, name, sep=private.SCOPE_SEPARATOR):
Expand Down Expand Up @@ -593,3 +594,45 @@ def patch_path(base_path, path):
path = path[1:]

return path


class CaseInsensitiveDict(collections.MutableMapping):
""" a case insensitive dict:
- allow to query with case insensitive keys (get, in)
- iteration would return original key
A reference implementation could be found in
https://github.com/requests/
"""

def __init__(self):
self._store = dict()

def __setitem__(self, key, value):
self._store[key.lower()] = (key, value)

def __getitem__(self, key):
return self._store[key.lower()][1]

def __delitem__(self, key):
del self._store[key.lower()]

def __iter__(self):
return (original_key for original_key, _ in six.itervalues(self._store))

def iteritems(self):
return six.itervalues(self._store)

def itervalues(self):
return (value for _, value in six.itervalues(self._store))

def __in__(self, key):
return key.lower() in self._store

def __len__(self):
return len(self._store)

def __repr__(self):
return str(dict(self.items()))

0 comments on commit 4a33366

Please sign in to comment.