From 7e8d81a0a1863460620f6f88aa1d31c1acb73c2f Mon Sep 17 00:00:00 2001 From: hit9 Date: Thu, 27 Aug 2015 16:47:14 +0800 Subject: [PATCH] Allow self-referencing recursive struct definition --- thriftpy/parser/parser.py | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/thriftpy/parser/parser.py b/thriftpy/parser/parser.py index 5a992e3..e930fae 100644 --- a/thriftpy/parser/parser.py +++ b/thriftpy/parser/parser.py @@ -203,12 +203,18 @@ def p_enum_item(p): def p_struct(p): - '''struct : STRUCT IDENTIFIER '{' field_seq '}' ''' - val = _make_struct(p[2], p[4]) - setattr(thrift_stack[-1], p[2], val) + '''struct : seen_struct '{' field_seq '}' ''' + val = _fill_in_struct(p[1], p[3]) _add_thrift_meta('structs', val) +def p_seen_struct(p): + '''seen_struct : STRUCT IDENTIFIER ''' + val = _make_empty_struct(p[2]) + setattr(thrift_stack[-1], p[2], val) + p[0] = val + + def p_union(p): '''union : UNION IDENTIFIER '{' field_seq '}' ''' val = _make_struct(p[2], p[4]) @@ -652,10 +658,12 @@ def _make_enum(name, kvs): return cls -def _make_struct(name, fields, ttype=TType.STRUCT, base_cls=TPayload, - _gen_init=True): +def _make_empty_struct(name, ttype=TType.STRUCT, base_cls=TPayload): attrs = {'__module__': thrift_stack[-1].__name__, '_ttype': ttype} - cls = type(name, (base_cls, ), attrs) + return type(name, (base_cls, ), attrs) + + +def _fill_in_struct(cls, fields, _gen_init=True): thrift_spec = {} default_spec = [] _tspec = {} @@ -677,6 +685,12 @@ def _make_struct(name, fields, ttype=TType.STRUCT, base_cls=TPayload, return cls +def _make_struct(name, fields, ttype=TType.STRUCT, base_cls=TPayload, + _gen_init=True): + cls = _make_empty_struct(name, ttype=ttype, base_cls=base_cls) + return _fill_in_struct(cls, fields, _gen_init=_gen_init) + + def _make_service(name, funcs, extends): if extends is None: extends = object