diff --git a/thriftpy/_compat.py b/thriftpy/_compat.py index 9c15e1f..eabf603 100644 --- a/thriftpy/_compat.py +++ b/thriftpy/_compat.py @@ -11,7 +11,6 @@ import platform import sys -import types PY3 = sys.version_info[0] == 3 PYPY = "__pypy__" in sys.modules @@ -58,69 +57,3 @@ def __new__(cls, name, this_bases, d): return type.__new__(cls, name, (), d) return meta(name, bases, d) return metaclass('temporary_class', None, {}) - - -def init_func_generator(spec): - """Generate `__init__` function based on TPayload.default_spec - - For example:: - - spec = [('name', 'Alice'), ('number', None)] - - will generate:: - - def __init__(self, name='Alice', number=None): - kwargs = locals() - kwargs.pop('self') - self.__dict__.update(kwargs) - - TODO: The `locals()` part may need refine. - """ - if not spec: - def __init__(self): - pass - return __init__ - - varnames, defaults = zip(*spec) - varnames = ('self', ) + varnames - - def init(self): - self.__dict__ = locals().copy() - del self.__dict__['self'] - - code = init.__code__ - if PY3: - new_code = types.CodeType(len(varnames), - 0, - len(varnames), - code.co_stacksize, - code.co_flags, - code.co_code, - code.co_consts, - code.co_names, - varnames, - code.co_filename, - "__init__", - code.co_firstlineno, - code.co_lnotab, - code.co_freevars, - code.co_cellvars) - else: - new_code = types.CodeType(len(varnames), - len(varnames), - code.co_stacksize, - code.co_flags, - code.co_code, - code.co_consts, - code.co_names, - varnames, - code.co_filename, - "__init__", - code.co_firstlineno, - code.co_lnotab, - code.co_freevars, - code.co_cellvars) - - return types.FunctionType(new_code, - {"__builtins__": __builtins__}, - argdefs=defaults) diff --git a/thriftpy/thrift.py b/thriftpy/thrift.py index 0cf0877..64b492d 100644 --- a/thriftpy/thrift.py +++ b/thriftpy/thrift.py @@ -10,8 +10,9 @@ from __future__ import absolute_import import functools +import types -from ._compat import init_func_generator, with_metaclass +from ._compat import with_metaclass def args2kwargs(thrift_spec, *args): @@ -38,6 +39,36 @@ def _type(s): return "MAP<%s, %s>" % (_type(spec[0]), _type(spec[1])) +def init_func_generator(spec): + """Generate `__init__` function based on TPayload.default_spec + + For example:: + + spec = [('name', 'Alice'), ('number', None)] + + will generate a types.FunctionType object representing:: + + def __init__(self, name='Alice', number=None): + self.name = name + self.number = number + """ + if not spec: + def __init__(self): + pass + return __init__ + + varnames, defaults = zip(*spec) + + args = ', '.join(map('{0[0]}={0[1]!r}'.format, spec)) + init = "def __init__(self, {0}):\n".format(args) + init += "\n".join(map(' self.{0} = {0}'.format, varnames)) + + code = compile(init, '', 'exec') + func = next(c for c in code.co_consts if isinstance(c, types.CodeType)) + + return types.FunctionType(func, {}, argdefs=defaults) + + class TType(object): STOP = 0 VOID = 1