@@ -209,21 +209,17 @@ def p_enum_item(p):
209209
210210def p_struct (p ):
211211 '''struct : seen_struct '{' field_seq '}' '''
212- name , pos = p [1 ]
213- use_slots = p .parser .__use_slots__
214- val = _make_empty_struct (
215- name ,
216- base_cls = TSPayload if use_slots else TPayload ,
217- slots = _field_names (p [3 ]) if use_slots else [],
218- )
219- val = _fill_in_struct (val , p [3 ])
220- setattr (thrift_stack [pos ], name , val )
212+ val = _fill_in_struct (p [1 ], p [3 ])
221213 _add_thrift_meta ('structs' , val )
222214
223215
224216def p_seen_struct (p ):
225217 '''seen_struct : STRUCT IDENTIFIER '''
226- p [0 ] = (p [2 ], len (thrift_stack )- 1 )
218+ use_slots = p .parser .__use_slots__
219+ base_cls = TSPayload if use_slots else TPayload
220+ val = _make_empty_struct (p [2 ], base_cls = base_cls )
221+ setattr (thrift_stack [- 1 ], p [2 ], val )
222+ p [0 ] = val
227223
228224
229225def p_union (p ):
@@ -234,7 +230,9 @@ def p_union(p):
234230
235231def p_seen_union (p ):
236232 '''seen_union : UNION IDENTIFIER '''
237- val = _make_empty_struct (p [2 ])
233+ use_slots = p .parser .__use_slots__
234+ base_cls = TSPayload if use_slots else TPayload
235+ val = _make_empty_struct (p [2 ], base_cls = base_cls )
238236 setattr (thrift_stack [- 1 ], p [2 ], val )
239237 p [0 ] = val
240238
@@ -268,7 +266,8 @@ def p_service(p):
268266 else :
269267 extends = None
270268
271- val = _make_service (p [2 ], p [len (p ) - 2 ], extends )
269+ use_slots = p .parser .__use_slots__
270+ val = _make_service (p [2 ], p [len (p ) - 2 ], extends , use_slots = use_slots )
272271 setattr (thrift , p [2 ], val )
273272 _add_thrift_meta ('services' , val )
274273
@@ -766,20 +765,11 @@ def _make_enum(name, kvs):
766765 return cls
767766
768767
769- def _make_empty_struct (name , ttype = TType .STRUCT , base_cls = TPayload , slots = [] ):
768+ def _make_empty_struct (name , ttype = TType .STRUCT , base_cls = TPayload ):
770769 attrs = {'__module__' : thrift_stack [- 1 ].__name__ , '_ttype' : ttype }
771- if issubclass (base_cls , TSPayload ):
772- attrs ['__slots__' ] = slots
773770 return type (name , (base_cls , ), attrs )
774771
775772
776- def _field_names (fields ):
777- fnames = []
778- for _ , _ , _ , name , _ in fields :
779- fnames .append (name )
780- return fnames
781-
782-
783773def _fill_in_struct (cls , fields , _gen_init = True ):
784774 thrift_spec = {}
785775 default_spec = []
@@ -797,6 +787,10 @@ def _fill_in_struct(cls, fields, _gen_init=True):
797787 setattr (cls , 'thrift_spec' , thrift_spec )
798788 setattr (cls , 'default_spec' , default_spec )
799789 setattr (cls , '_tspec' , _tspec )
790+ # add __slots__ so we can check way before the class is created, even though
791+ # it really does nothing here, the real work is done during instantiation
792+ if issubclass (cls , TSPayload ):
793+ cls .__slots__ = tuple (field for field , _ in default_spec )
800794 if _gen_init :
801795 gen_init (cls , thrift_spec , default_spec )
802796 return cls
@@ -808,11 +802,14 @@ def _make_struct(name, fields, ttype=TType.STRUCT, base_cls=TPayload,
808802 return _fill_in_struct (cls , fields , _gen_init = _gen_init )
809803
810804
811- def _make_service (name , funcs , extends ):
805+ def _make_service (name , funcs , extends , use_slots = False ):
812806 if extends is None :
813807 extends = object
814808
815809 attrs = {'__module__' : thrift_stack [- 1 ].__name__ }
810+ base_cls = TSPayload if use_slots else TPayload
811+ if use_slots :
812+ attrs ['__slots__' ] = tuple ()
816813 cls = type (name , (extends , ), attrs )
817814 thrift_services = []
818815
@@ -821,15 +818,15 @@ def _make_service(name, funcs, extends):
821818 # args payload cls
822819 args_name = '%s_args' % func_name
823820 args_fields = func [3 ]
824- args_cls = _make_struct (args_name , args_fields )
821+ args_cls = _make_struct (args_name , args_fields , base_cls = base_cls )
825822 setattr (cls , args_name , args_cls )
826823 # result payload cls
827824 result_name = '%s_result' % func_name
828825 result_type = func [1 ]
829826 result_throws = func [4 ]
830827 result_oneway = func [0 ]
831828 result_cls = _make_struct (result_name , result_throws ,
832- _gen_init = False )
829+ _gen_init = False , base_cls = base_cls )
833830 setattr (result_cls , 'oneway' , result_oneway )
834831 if result_type != TType .VOID :
835832 result_cls .thrift_spec [0 ] = _ttype_spec (result_type , 'success' )
0 commit comments