[Pyrex] Weakrefs patch

Peter Johnson peter at tortall.net
Thu Dec 7 06:08:05 UTC 2006


I recently ran into this problem myself (as the current code causes Python 
to crash), so I whipped up a quick patch that fixes it for me.  I think it 
follows all of the weakref guidelines now.

The patch is against the LXML svn pyrex 
(http://codespeak.net/svn/lxml/pyrex/).  Is there a different SVN I should 
be pointing to?  It patches functions generate_new_function, 
generate_dealloc_function, generate_traverse_function, and 
generate_clear_function.

The patch just compares the entry.name against "__weakref__"; this could 
probably be centralized in the Entry object if so desired.

Cheers,
Peter Johnson
-------------- next part --------------
Index: Nodes.py
===================================================================
--- Nodes.py	(revision 35411)
+++ Nodes.py	(working copy)
@@ -539,7 +539,10 @@
                 type.vtabptr_cname))
         for entry in scope.var_entries:
             if entry.type.is_pyobject:
-                code.put_init_var_to_py_none(entry, "p->%s")
+                if entry.name == "__weakref__":
+                    code.putln("p->%s = NULL;" % entry.cname)
+                else:
+                    code.put_init_var_to_py_none(entry, "p->%s")
         entry = scope.lookup_here("__new__")
         if entry:
             code.putln(
@@ -563,7 +566,12 @@
         self.generate_usr_dealloc_call(scope, code)
         for entry in scope.var_entries:
             if entry.type.is_pyobject:
-                code.put_xdecref("p->%s" % entry.cname, entry.type)
+                if entry.name == "__weakref__":
+                    code.putln(
+                        "if (p->%s) PyObject_ClearWeakRefs(o);" %
+                            entry.cname)
+                else:
+                    code.put_xdecref("p->%s" % entry.cname, entry.type)
         if base_type:
             code.putln(
                 "%s->tp_dealloc(o);" %
@@ -611,7 +619,7 @@
                     "e = %s->tp_traverse(o, v, a); if (e) return e;" %
                         base_type.typeptr_cname)
         for entry in scope.var_entries:
-            if entry.type.is_pyobject:
+            if entry.type.is_pyobject and entry.name != "__weakref__":
                 var_code = "p->%s" % entry.cname
                 code.putln(
                         "if (%s) {"
@@ -640,7 +648,7 @@
                 "%s->tp_clear(o);" %
                     base_type.typeptr_cname)
         for entry in scope.var_entries:
-            if entry.type.is_pyobject:
+            if entry.type.is_pyobject and entry.name != "__weakref__":
                 name = "p->%s" % entry.cname
                 code.put_xdecref(name, entry.type)
                 #code.put_init_to_py_none(name)


More information about the Pyrex mailing list