Skip to content
This repository has been archived by the owner on Dec 10, 2018. It is now read-only.

Assign generated init funcs unique names #227

Merged
merged 1 commit into from
Aug 18, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions tests/test_base.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# -*- coding: utf-8 -*-

import linecache

import pytest

import thriftpy
Expand Down Expand Up @@ -68,3 +70,8 @@ def test_parse_spec():

for spec, res in cases:
assert parse_spec(*spec) == res


def test_init_func():
thriftpy.load("addressbook.thrift")
assert linecache.getline('<generated PhoneNumber.__init__>', 1) != ''
15 changes: 11 additions & 4 deletions thriftpy/thrift.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from __future__ import absolute_import

import functools
import linecache
import types

from ._compat import with_metaclass
Expand Down Expand Up @@ -39,7 +40,7 @@ def _type(s):
return "MAP<%s, %s>" % (_type(spec[0]), _type(spec[1]))


def init_func_generator(spec):
def init_func_generator(cls, spec):
"""Generate `__init__` function based on TPayload.default_spec

For example::
Expand All @@ -63,9 +64,14 @@ def __init__(self):
init = "def __init__(self, {0}):\n".format(args)
init += "\n".join(map(' self.{0} = {0}'.format, varnames))

code = compile(init, '<init_func_generator>', 'exec')
name = '<generated {0}.__init__>'.format(cls.__name__)
code = compile(init, name, 'exec')
func = next(c for c in code.co_consts if isinstance(c, types.CodeType))

# Add a fake linecache entry so debuggers and the traceback module can
# better understand our generated code.
linecache.cache[name] = (len(init), None, init.splitlines(True), name)

return types.FunctionType(func, {}, argdefs=defaults)


Expand Down Expand Up @@ -122,7 +128,8 @@ class TPayloadMeta(type):

def __new__(cls, name, bases, attrs):
if "default_spec" in attrs:
attrs["__init__"] = init_func_generator(attrs.pop("default_spec"))
spec = attrs.pop("default_spec")
attrs["__init__"] = init_func_generator(cls, spec)
return super(TPayloadMeta, cls).__new__(cls, name, bases, attrs)


Expand All @@ -131,7 +138,7 @@ def gen_init(cls, thrift_spec=None, default_spec=None):
cls.thrift_spec = thrift_spec

if default_spec is not None:
cls.__init__ = init_func_generator(default_spec)
cls.__init__ = init_func_generator(cls, default_spec)
return cls


Expand Down