From d66f1fd8740eb814a7c05c458e4ea4fa8c19aae4 Mon Sep 17 00:00:00 2001 From: Christophe de Vienne Date: Mon, 19 Sep 2011 23:27:24 +0200 Subject: [PATCH] Implementing the structured types inspection --- wsme/restjson.py | 2 +- wsme/types.py | 45 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/wsme/restjson.py b/wsme/restjson.py index fc4d394..db47226 100644 --- a/wsme/restjson.py +++ b/wsme/restjson.py @@ -15,7 +15,7 @@ def prepare_encode(value, datatype): return value if datatype in wsme.types.structured_types: d = dict() - for name, datatype, mandatory in wsme.types.list_attributes(value): + for name, datatype, mandatory in wsme.types.list_attributes(datatype): d[name] = prepare_encode(getattr(value, name), datatype) return d if datatype in wsme.types.dt_types: diff --git a/wsme/types.py b/wsme/types.py index d9444ea..c356b8f 100644 --- a/wsme/types.py +++ b/wsme/types.py @@ -1,5 +1,7 @@ import datetime import decimal +import weakref +import inspect binary = object() @@ -10,6 +12,45 @@ native_types = pod_types + dt_types + extra_types structured_types = [] -def register_type(class_): - structured_types.append(class_) +def mandatory(datatype): + if isinstance(datatype, AttrDef): + datatype.mandatory = True + return datatype + return AttrDef(datatype, True) + + +class AttrDef(object): + def __init__(self, datatype, mandatory=False, default=None): + self.datatype = datatype + self.mandatory = mandatory + self.default = None + +def inspect_class(class_): + attributes = [] + for name in dir(class_): + if name.startswith('_'): + continue + + attr = getattr(class_, name) + if inspect.isfunction(attr): + continue + if inspect.ismethod(attr): + continue + if not isinstance(attr, AttrDef): + attrdef = AttrDef(attr) + else: + attrdef = attr + + attributes.append((name, AttrDef)) + return attributes + +def register_type(class_): + if hasattr(class_, '_wsme_attributes'): + return + + class_._wsme_attributes = inspect_class(class_) + structured_types.append(weakref.ref(class_)) + +def list_attributes(class_): + return class_._wsme_attributes