[Stackless] An unpickled lambda loses its __module__ + patch

Alain Poirier alain.poirier at net-ng.com
Thu Oct 18 23:00:02 CEST 2007


Hi,

When a lambda expression is pickled then unpickled, its `__module__` attribut
is reseted to `None`:

Python 2.5.1 Stackless 3.1b3 060516 (release25-maint, Oct 18 2007, 22:24:34)
[GCC 3.4.6 (Gentoo 3.4.6-r2, ssp-3.4.6-1.0, pie-8.7.10)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import cPickle
>>> f = lambda: 0
>>> print 'Before :', f.__module__
Before : __main__
>>> f = cPickle.loads(cPickle.dumps(f))
>>> print 'After :', f.__module__
After : None


I created the following patch to solve the problem. Can you check it ?

Note: I think there is the same problem with the attributs of lambda 
expressions.


--- stackless-251-export/Stackless/pickling/prickelpit.c        2007-05-01 
12:25:50.000000000 +0200
+++ stackless-251-export.new/Stackless/pickling/prickelpit.c    2007-10-18 
18:14:20.000000000 +0200
@@ -633,7 +633,7 @@

  ******************************************************/

-#define functuplefmt "OOOOO"
+#define functuplefmt "OOOOOO"

 static PyTypeObject wrap_PyFunction_Type;

@@ -647,8 +647,9 @@
            func->func_globals != NULL ? func->func_globals : Py_None,
            func->func_name != NULL ? func->func_name : Py_None,
            func->func_defaults != NULL ? func->func_defaults : Py_None,
-           func->func_closure != NULL ? func->func_closure : Py_None
-       );
+           func->func_closure != NULL ? func->func_closure : Py_None,
+           func->func_module != NULL ? func->func_module : Py_None
+           );
         return tup;
 }

@@ -679,7 +680,7 @@
        if (is_wrong_type(self->ob_type)) return NULL;
        self->ob_type = self->ob_type->tp_base;
        fu = (PyFunctionObject *)
-            self->ob_type->tp_new(self->ob_type, args, NULL);
+            self->ob_type->tp_new(self->ob_type, PyTuple_GetSlice(args, 0, 
5), NULL);
        if (fu != NULL) {
                PyFunctionObject *target = (PyFunctionObject *) self;
                COPY(fu, target, func_code);
@@ -687,6 +688,10 @@
                COPY(fu, target, func_name);
                COPY(fu, target, func_defaults);
                COPY(fu, target, func_closure);
+
+               Py_XINCREF(PyTuple_GetItem(args, 5));
+               target->func_module = PyTuple_GetItem(args, 5);
+
                Py_DECREF(fu);
                Py_INCREF(self);
                return self;




More information about the Stackless mailing list