From: Philip J. <pj...@un...> - 2010-01-18 22:21:59
|
On Jan 18, 2010, at 1:52 PM, Sharon Lucas wrote: > > Hi, > > We have a Java application that uses Jython and works fine with Jython 2.1. I'm now porting it to use Jython 2.5.1. However, I'm getting the following error using Jython 2.5.1 > > "TypeError: function() argument 1 must be code, not stringmap" > > in our Jython function that does our version of a "deep copy" of a PyFunction definition where we create an identical PyFunction, except for the reference to the global variable pool (which is redirected to look at a new global variable pool). Here is a simple Jython program I wrote that recreates this problem. It defines a function named cloneGlobals and a main function that calls this function passing it globals() as the argument. When run via Jython 2.1, it works fine. However, when run via Jython 2.5.1, it fails when calling org.python.core.PyFunction (the line in blue). > > def cloneGlobals(theGlobals): > import copy > import types > import org.python.core.PyFunction > > clone = copy.copy(theGlobals) > skipTypes = [types.ModuleType, types.FunctionType, > types.ClassType, > type(clone) # StringMapType > ] > > for key in clone.keys(): > if (type(clone[key]) not in skipTypes): > try: > clone[key] = copy.deepcopy(clone[key]) > except: > pass # ignore types that cannot be deep copied > elif ((type(clone[key]) is types.FunctionType) and > (clone[key].func_globals is theGlobals)): > > # Checks to see if the variable is a function definition that was > # defined at the "global" scope, i.e., not within some other > # Python module. If so, then it replaces the function definition > # with one that is identical except for the reference to the global > # variable pool, which is redirected to look at the new global > # variable pool being created. > > print '\nFunction name: %s' % (key) > print ' globals : %s' % (type(clone)) > print ' defaults: %s' % (type(clone[key].func_defaults)) > print ' code : %s' % (type(clone[key].func_code)) > print ' doc : %s' % (type(clone[key].func_doc)) > print ' closure : %s' % (type(clone[key].func_closure)) > clone[key] = org.python.core.PyFunction( > clone, # globals > clone[key].func_defaults, > clone[key].func_code, > clone[key].func_doc, > clone[key].func_closure) And to fix the mismatch in your arguments, FunctionType's name argument would just be clone[key].func_name (or whatever you want it to be), and func_defaults is obviously the argdefs argument. To clone the docstring assign func_doc (or __doc__) to the new object after creating it. -- Philip Jenvey |