[Zope-Checkins] CVS: Zope3/lib/python/Persistence - Function.py:1.8
Jeremy Hylton
jeremy@zope.com
Wed, 10 Jul 2002 19:11:00 -0400
Update of /cvs-repository/Zope3/lib/python/Persistence
In directory cvs.zope.org:/tmp/cvs-serv28387
Modified Files:
Function.py
Log Message:
Extend CodeWrapper to make functions with nested functions picklable.
This allows code with nested functions to be written, although the
nested functions will not be persistent.
=== Zope3/lib/python/Persistence/Function.py 1.7 => 1.8 ===
import dis
import new
import sys
-# in 2.3, this will be spelled new.function
-from types import FunctionType as function
+# in 2.3, this will be spelled new.function and new.code
+from types import FunctionType as function, CodeType as code
from Persistence import Persistent
@@ -16,13 +16,26 @@
class CodeWrapper:
"""Package a code object so that it can be pickled."""
+ nested = 0
+
def __init__(self, co):
- self.args = (co.co_argcount,
+ consts = co.co_consts
+ nested = [(i, c) for i, c in zip(range(len(consts)), consts)
+ if isinstance(c, code)]
+ if nested:
+ self.nested = 1
+ L = list(consts)
+ for i, c in nested:
+ L[i] = CodeWrapper(c)
+ consts = tuple(L)
+
+ # args stores the arguments to new.code in order
+ self.args = [co.co_argcount,
co.co_nlocals,
co.co_stacksize,
co.co_flags,
co.co_code,
- co.co_consts,
+ consts,
co.co_names,
co.co_varnames,
co.co_filename,
@@ -30,9 +43,15 @@
co.co_firstlineno,
co.co_lnotab,
co.co_freevars,
- co.co_cellvars)
+ co.co_cellvars]
def ascode(self):
+ if self.nested:
+ L = list(self.args[5])
+ for i, elt in zip(range(len(L)), L):
+ if isinstance(elt, CodeWrapper):
+ L[i] = elt.ascode()
+ self.args[5] = tuple(L)
return new.code(*self.args)
def get_code_args(co):