From 54e11fcd0451067f0ed4d626e95b85537a1b8200 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Lamotte Date: Fri, 22 Nov 2013 14:27:03 +0100 Subject: [PATCH 1/4] issue #35 Add long simple type support. --- src/pyws/functions/args/types/__init__.py | 12 +++++++++++- src/pyws/functions/args/types/simple.py | 23 ++++++++++++++++++++++- src/pyws/protocols/soap/xsd.py | 17 ++++++++++++++--- 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/pyws/functions/args/types/__init__.py b/src/pyws/functions/args/types/__init__.py index c3dfb51..5239c4b 100644 --- a/src/pyws/functions/args/types/__init__.py +++ b/src/pyws/functions/args/types/__init__.py @@ -15,7 +15,17 @@ def __str__(self): # The order matters: DateTime should be placed before Date. # date is a superclass of datetime, thus Date will catch all DateTime fields. -__types__ = (String, Boolean, Integer, Float, DateTime, Date, Dict, List) +__types__ = (String, + Boolean, + Long, + Integer, + Float, + DateTime, + Date, + Dict, + List, + FunctionPointerDict + ) def TypeFactory(type_): diff --git a/src/pyws/functions/args/types/simple.py b/src/pyws/functions/args/types/simple.py index c377e5d..cd9766d 100644 --- a/src/pyws/functions/args/types/simple.py +++ b/src/pyws/functions/args/types/simple.py @@ -5,7 +5,13 @@ from pyws.functions.args.types.base import Type -__all__ = ('String', 'Boolean', 'Integer', 'Float', 'Date', 'DateTime', ) +__all__ = ('String', + 'Boolean', + 'Long', + 'Integer', + 'Float', + 'Date', + 'DateTime',) class String(Type): @@ -27,6 +33,7 @@ def _validate(cls, value): except UnicodeDecodeError: return unicode(value, 'utf-8') + class Boolean(Type): """ Represents boolean values, simplified form is ``bool``, default @@ -49,6 +56,19 @@ def serialize(cls, value): return unicode(value).lower() +class Long(Type): + """ + Represents long numbers, simplified form is ``long``, default + ``none_value`` is ``None``. + """ + + _represents = long + + @classmethod + def _validate(cls, value): + return long(value) + + class Integer(Type): """ Represents integer numbers, simplified form is ``int``, default @@ -99,6 +119,7 @@ def serialize(cls, value): tz_re = re.compile('((\\+|-)(\d\d):?(\d\d))$') + class DateTime(Date): """ Represents datetime values, simplified form is ``datetime``, default diff --git a/src/pyws/protocols/soap/xsd.py b/src/pyws/protocols/soap/xsd.py index 8731f14..4bab6cb 100644 --- a/src/pyws/protocols/soap/xsd.py +++ b/src/pyws/protocols/soap/xsd.py @@ -48,6 +48,7 @@ class String(SimpleType): def get_name(self): return 'string', 'http://www.w3.org/2001/XMLSchema' + class Boolean(SimpleType): _represents = args.Boolean @@ -55,6 +56,15 @@ class Boolean(SimpleType): def get_name(self): return 'boolean', 'http://www.w3.org/2001/XMLSchema' + +class Long(SimpleType): + + _represents = args.Long + + def get_name(self): + return 'long', 'http://www.w3.org/2001/XMLSchema' + + class Integer(SimpleType): _represents = args.Integer @@ -119,7 +129,7 @@ def get_children(self, sequence, types): type = TypeFactory(field.type, self.ns, self.nsmap) element = et.SubElement(sequence, xsd_name('element'), name=field.name, - type=qname(*(type.name + (self.nsmap, )))) + type=qname(*(type.name + (self.nsmap,)))) element.set('nillable', 'true') type.get_types(types) @@ -135,14 +145,15 @@ def get_children(self, sequence, types): type = TypeFactory(self.type.element_type, self.ns, self.nsmap) et.SubElement(sequence, xsd_name('element'), name='item', - type=qname(*(type.name + (self.nsmap, ))), + type=qname(*(type.name + (self.nsmap,))), minOccurs='0', maxOccurs='unbounded') type.get_types(types) # The order matters: DateTime should be placed before Date. # Date is a superclass of DateTime, thus Date will catch all DateTime fields. -__types__ = (String, Boolean, Integer, Float, DateTime, Date, Dict, List) +__types__ = (String, Boolean, Long, Integer, Float, DateTime, Date, Dict, List) + def TypeFactory(type, ns=None, nsmap=None): for x in __types__: From 6cec946a7ac97b1d993c20f6aea28623ad867db4 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Lamotte Date: Fri, 22 Nov 2013 14:27:36 +0100 Subject: [PATCH 2/4] issue #36 Add support for complex type self referencing --- src/pyws/functions/args/types/complex.py | 64 ++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 3 deletions(-) diff --git a/src/pyws/functions/args/types/complex.py b/src/pyws/functions/args/types/complex.py index 265b5a9..e867ae2 100644 --- a/src/pyws/functions/args/types/complex.py +++ b/src/pyws/functions/args/types/complex.py @@ -1,14 +1,72 @@ from pyws.functions.args.types.base import Type -__all__ = ('DICT_NAME_KEY', 'Dict', 'List', 'DictOf', 'ListOf') - +__all__ = ('DICT_NAME_KEY', + 'Dict', + 'List', + 'DictOf', + 'ListOf', + 'FunctionPointerDict' + ) +__cached_function_pointer_dict_type__ = {} DICT_NAME_KEY = 0 + class BadType(Exception): pass +class FunctionPointerDict(Type): + """ + Represents dicts, returned by a function pointer (for complex type tree) + """ + + fields = [] + + @classmethod + def represents(cls, type_): + import operator + if operator.isCallable(type_) and not isinstance(type_, type): + return isinstance(type_(), dict) + return False + + @classmethod + def get(cls, type_): + type_ = type_() + try: + dict_name = type_[DICT_NAME_KEY] + except KeyError: + raise BadType('%s is required for Dict type' % repr(DICT_NAME_KEY)) + + if dict_name in __cached_function_pointer_dict_type__: + return __cached_function_pointer_dict_type__[dict_name] + + ret = type(dict_name, (Dict,), {'fields': []}) + __cached_function_pointer_dict_type__[dict_name] = ret + + fields = [ + isinstance(type_, tuple) and (name,) + type_ or (name, type_) + for name, type_ in type_.iteritems() if name != DICT_NAME_KEY] + + ret.add_fields(*fields) + + return ret + + @classmethod + def add_fields(cls, *fields): + from pyws.functions.args.field import FieldFactory + fields_ = [] + for field in fields: + fields_.append(FieldFactory(field)) + cls.fields += fields_ + + @classmethod + def _validate(cls, value): + return dict( + (field.name, field.validate(field.get_value(value))) + for field in cls.fields) + + class Dict(Type): """ Represents dicts, simplified form is @@ -100,7 +158,7 @@ def DictOf(name, *fields): 2 """ ret = type(name, (Dict,), {'fields': []}) - #noinspection PyUnresolvedReferences + # noinspection PyUnresolvedReferences ret.add_fields(*fields) return ret From da88f2d63b96e876682b23164e3fee34ba046900 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Lamotte Date: Fri, 29 Nov 2013 13:55:05 +0100 Subject: [PATCH 3/4] pep8 syntax fix --- src/pyws/functions/args/types/__init__.py | 14 +++----------- src/pyws/functions/args/types/complex.py | 12 ++++-------- src/pyws/functions/args/types/simple.py | 9 ++------- src/pyws/protocols/soap/xsd.py | 4 ++-- 4 files changed, 11 insertions(+), 28 deletions(-) diff --git a/src/pyws/functions/args/types/__init__.py b/src/pyws/functions/args/types/__init__.py index 5239c4b..c158909 100644 --- a/src/pyws/functions/args/types/__init__.py +++ b/src/pyws/functions/args/types/__init__.py @@ -15,17 +15,9 @@ def __str__(self): # The order matters: DateTime should be placed before Date. # date is a superclass of datetime, thus Date will catch all DateTime fields. -__types__ = (String, - Boolean, - Long, - Integer, - Float, - DateTime, - Date, - Dict, - List, - FunctionPointerDict - ) +__types__ = ( + String, Boolean, Long, Integer, Float, DateTime, Date, Dict, List, + FunctionPointerDict) def TypeFactory(type_): diff --git a/src/pyws/functions/args/types/complex.py b/src/pyws/functions/args/types/complex.py index e867ae2..aec6a3e 100644 --- a/src/pyws/functions/args/types/complex.py +++ b/src/pyws/functions/args/types/complex.py @@ -1,12 +1,7 @@ from pyws.functions.args.types.base import Type -__all__ = ('DICT_NAME_KEY', - 'Dict', - 'List', - 'DictOf', - 'ListOf', - 'FunctionPointerDict' - ) +__all__ = ( + 'DICT_NAME_KEY', 'Dict', 'List', 'DictOf', 'ListOf', 'FunctionPointerDict') __cached_function_pointer_dict_type__ = {} DICT_NAME_KEY = 0 @@ -18,7 +13,8 @@ class BadType(Exception): class FunctionPointerDict(Type): """ - Represents dicts, returned by a function pointer (for complex type tree) + Represents dicts, returned by a function pointer, like lambda. + Refer to type ``Dict`` for additionnal informations. """ fields = [] diff --git a/src/pyws/functions/args/types/simple.py b/src/pyws/functions/args/types/simple.py index cd9766d..e3b5491 100644 --- a/src/pyws/functions/args/types/simple.py +++ b/src/pyws/functions/args/types/simple.py @@ -5,13 +5,8 @@ from pyws.functions.args.types.base import Type -__all__ = ('String', - 'Boolean', - 'Long', - 'Integer', - 'Float', - 'Date', - 'DateTime',) +__all__ = ( + 'String', 'Boolean', 'Long', 'Integer', 'Float', 'Date', 'DateTime',) class String(Type): diff --git a/src/pyws/protocols/soap/xsd.py b/src/pyws/protocols/soap/xsd.py index 4bab6cb..1c89554 100644 --- a/src/pyws/protocols/soap/xsd.py +++ b/src/pyws/protocols/soap/xsd.py @@ -129,7 +129,7 @@ def get_children(self, sequence, types): type = TypeFactory(field.type, self.ns, self.nsmap) element = et.SubElement(sequence, xsd_name('element'), name=field.name, - type=qname(*(type.name + (self.nsmap,)))) + type=qname(*(type.name + (self.nsmap, )))) element.set('nillable', 'true') type.get_types(types) @@ -145,7 +145,7 @@ def get_children(self, sequence, types): type = TypeFactory(self.type.element_type, self.ns, self.nsmap) et.SubElement(sequence, xsd_name('element'), name='item', - type=qname(*(type.name + (self.nsmap,))), + type=qname(*(type.name + (self.nsmap, ))), minOccurs='0', maxOccurs='unbounded') type.get_types(types) From fc2e624fdf670a20fbf5d70b67c765619bfe6eca Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Lamotte Date: Fri, 29 Nov 2013 17:51:00 +0100 Subject: [PATCH 4/4] Add long & functionptr type documentation --- docs/function.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/function.rst b/docs/function.rst index b112323..21ba2a9 100644 --- a/docs/function.rst +++ b/docs/function.rst @@ -54,7 +54,7 @@ forms: pyws supports the following types: .. automodule:: pyws.functions.args.types - :members: String,Integer,Float,Boolean,Date,DateTime,Dict,List + :members: String,Integer,Long,Float,Boolean,Date,DateTime,Dict,List,FunctionPointerDict Three helper functions are also at your disposal: