[elinks-dev] Re: Replace Py_XDECREF with Py_CLEAR in cleanup_python?

M. Levinson levinsm at users.sourceforge.net
Sun Dec 10 11:02:34 MST 2006


On Dec 09, 2006, at 1:22am, Kalle Olavi Niemitalo writes:
>Now if the Python scripting module is initialized once and
>cleaned up, and then initialized again but the second
>initialization fails e.g. because of invalid syntax in hooks.py,
>I believe python_hooks will retain the value from the first
>successful initialization.  And if the module is then again
>cleaned up, Py_XDECREF gets called on an object that has already
>been deleted.  A similar problem seems possible in
>python_done_keybinding_interface.

You're right, I hadn't anticipated reinitialization after cleanup.

>Should the Py_XDECREF calls be changed to Py_CLEAR, or did I
>misunderstand something?

Yes, Py_CLEAR is the clean solution for Python 2.4 and later; but relying
on it would mean that the Python backend could no longer be compiled with
Python 2.3 (which I believe happens to be the version you've been linking
with?).

Assuming compatibility with older Python versions is still desired, the
safe approach would be to explicitly imitate what Py_CLEAR does:


 src/scripting/python/core.c       |   10 +++++++++-
 src/scripting/python/keybinding.c |    8 +++++++-
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/src/scripting/python/core.c b/src/scripting/python/core.c
index 3ce2d43..33bb5c8 100644
--- a/src/scripting/python/core.c
+++ b/src/scripting/python/core.c
@@ -209,8 +209,16 @@ void
 cleanup_python(struct module *module)
 {
 	if (Py_IsInitialized()) {
+		PyObject *temp;
+
 		python_done_keybinding_interface();
-		Py_XDECREF(python_hooks);
+
+		/* This is equivalent to Py_CLEAR(), but it works with older
+		 * versions of Python predating that macro: */
+		temp = python_hooks;
+		python_hooks = NULL;
+		Py_XDECREF(temp);
+
 		Py_Finalize();
 	}
 }
diff --git a/src/scripting/python/keybinding.c b/src/scripting/python/keybinding.c
index 2d6668c..983c184 100644
--- a/src/scripting/python/keybinding.c
+++ b/src/scripting/python/keybinding.c
@@ -194,5 +194,11 @@ python_init_keybinding_interface(PyObject *dict, PyObject *name)
 void
 python_done_keybinding_interface(void)
 {
-	Py_XDECREF(keybindings);
+	PyObject *temp;
+
+	/* This is equivalent to Py_CLEAR(), but it works with older
+	 * versions of Python predating that macro: */
+	temp = keybindings;
+	keybindings = NULL;
+	Py_XDECREF(temp);
 }



More information about the elinks-dev mailing list