"""This module defines the abstract base classes that support execution:Code and Frame."""frompypy.interpreter.errorimportOperationErrorfrompypy.interpreter.baseobjspaceimportWrappableclassCode(Wrappable):"""A code is a compiled version of some source code. Abstract base class."""_immutable_=Truehidden_applevel=False# n >= 0 : arity# FLATPYCALL = 0x100# n|FLATPYCALL: pycode flat case# FLATPYCALL<<x (x>=1): special cases# HOPELESS: hopelessFLATPYCALL=0x100PASSTHROUGHARGS1=0x200HOPELESS=0x400fast_natural_arity=HOPELESSdef__init__(self,co_name):self.co_name=co_namedefexec_code(self,space,w_globals,w_locals):"Implements the 'exec' statement."# this should be on PyCode?frame=space.createframe(self,w_globals,None)frame.setdictscope(w_locals)returnframe.run()defsignature(self):raiseNotImplementedErrordefgetvarnames(self):"""List of names including the arguments, vararg and kwarg, and possibly more locals."""returnself.signature().getallvarnames()defgetformalargcount(self):returnself.signature().scope_length()defgetdocstring(self,space):returnspace.w_Nonedeffuncrun(self,func,args):raiseNotImplementedError("purely abstract")deffuncrun_obj(self,func,w_obj,args):returnself.funcrun(func,args.prepend(w_obj))classFrame(Wrappable):"""A frame is an environment supporting the execution of a code object. Abstract base class."""def__init__(self,space,w_globals=None):self.space=spaceself.w_globals=w_globals# wrapped dict of globalsself.w_locals=None# wrapped dict of localsdefrun(self):"Abstract method to override. Runs the frame"raiseTypeError,"abstract"defgetdictscope(self):"Get the locals as a dictionary."self.fast2locals()returnself.w_localsdefgetcode(self):returnNonedeffget_code(self,space):returnspace.wrap(self.getcode())deffget_getdictscope(self,space):returnself.getdictscope()defsetdictscope(self,w_locals):"Initialize the locals from a dictionary."self.w_locals=w_localsself.locals2fast()defgetfastscope(self):"Abstract. Get the fast locals as a list."raiseTypeError,"abstract"defsetfastscope(self,scope_w):"""Abstract. Initialize the fast locals from a list of values, where the order is according to self.getcode().signature()."""raiseTypeError,"abstract"defgetfastscopelength(self):"Abstract. Get the expected number of locals."raiseTypeError,"abstract"deffast2locals(self):# Copy values from the fastlocals to self.w_localsifself.w_localsisNone:self.w_locals=self.space.newdict()varnames=self.getcode().getvarnames()fastscope_w=self.getfastscope()foriinrange(min(len(varnames),self.getfastscopelength())):name=varnames[i]w_value=fastscope_w[i]ifw_valueisnotNone:w_name=self.space.wrap(name)self.space.setitem(self.w_locals,w_name,w_value)deflocals2fast(self):# Copy values from self.w_locals to the fastlocalsassertself.w_localsisnotNonevarnames=self.getcode().getvarnames()numlocals=self.getfastscopelength()new_fastlocals_w=[None]*numlocalsforiinrange(min(len(varnames),numlocals)):w_name=self.space.wrap(varnames[i])try:w_value=self.space.getitem(self.w_locals,w_name)exceptOperationError,e:ifnote.match(self.space,self.space.w_KeyError):raiseelse:new_fastlocals_w[i]=w_valueself.setfastscope(new_fastlocals_w)