[libpeas] Move internal Python code to another file



commit ae7c80d25a425420604929c6ce9c263eaa853ef0
Author: Garrett Regier <garrettregier gmail com>
Date:   Sun Jan 4 21:26:47 2015 -0800

    Move internal Python code to another file
    
    All code that deals with internal.py is now in
    peas-python-internal.c instead of cluttering
    the plugin loader code.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=742349

 loaders/python/Makefile.am                 |    2 +
 loaders/python/peas-plugin-loader-python.c |  120 ++------------------
 loaders/python/peas-python-internal.c      |  169 ++++++++++++++++++++++++++++
 loaders/python/peas-python-internal.h      |   40 +++++++
 loaders/python3/Makefile.am                |    2 +
 5 files changed, 222 insertions(+), 111 deletions(-)
---
diff --git a/loaders/python/Makefile.am b/loaders/python/Makefile.am
index c69ef3f..3ec9aef 100644
--- a/loaders/python/Makefile.am
+++ b/loaders/python/Makefile.am
@@ -18,6 +18,8 @@ loader_LTLIBRARIES = libpythonloader.la
 libpythonloader_la_SOURCES = \
        peas-plugin-loader-python.c     \
        peas-plugin-loader-python.h     \
+       peas-python-internal.c          \
+       peas-python-internal.h          \
        peas-python-resources.c
 
 libpythonloader_la_LDFLAGS = \
diff --git a/loaders/python/peas-plugin-loader-python.c b/loaders/python/peas-plugin-loader-python.c
index 36f6172..ce77ed6 100644
--- a/loaders/python/peas-plugin-loader-python.c
+++ b/loaders/python/peas-plugin-loader-python.c
@@ -25,6 +25,7 @@
 #endif
 
 #include "peas-plugin-loader-python.h"
+#include "peas-python-internal.h"
 #include "libpeas/peas-plugin-info-priv.h"
 
 /* _POSIX_C_SOURCE is defined in Python.h and in limits.h included by
@@ -48,7 +49,7 @@ typedef struct {
   guint init_failed : 1;
   guint must_finalize_python : 1;
   PyThreadState *py_thread_state;
-  PyObject *hooks;
+  PeasPythonInternal *internal;
 } PeasPluginLoaderPythonPrivate;
 
 G_DEFINE_TYPE_WITH_PRIVATE (PeasPluginLoaderPython,
@@ -70,21 +71,6 @@ peas_register_types (PeasObjectModule *module)
 }
 
 /* NOTE: This must be called with the GIL held */
-static void
-internal_python_hook (PeasPluginLoaderPython *pyloader,
-                      const gchar            *name)
-{
-  PeasPluginLoaderPythonPrivate *priv = GET_PRIV (pyloader);
-  PyObject *result;
-
-  result = PyObject_CallMethod (priv->hooks, (gchar *) name, NULL);
-  Py_XDECREF (result);
-
-  if (PyErr_Occurred ())
-    PyErr_Print ();
-}
-
-/* NOTE: This must be called with the GIL held */
 static PyTypeObject *
 find_python_extension_type (GType     exten_type,
                             PyObject *pymodule)
@@ -341,7 +327,7 @@ peas_plugin_loader_python_unload (PeasPluginLoader *loader,
    * loader will not be finalized by applications
    */
   if (--priv->n_loaded_plugins == 0)
-    internal_python_hook (pyloader, "all_plugins_unloaded");
+    peas_python_internal_call (priv->internal, "all_plugins_unloaded");
 
   info->loader_data = NULL;
   PyGILState_Release (state);
@@ -434,8 +420,7 @@ peas_plugin_loader_python_initialize (PeasPluginLoader *loader)
   PeasPluginLoaderPythonPrivate *priv = GET_PRIV (pyloader);
   PyGILState_STATE state = 0;
   long hexversion;
-  GBytes *internal_python;
-  PyObject *gettext, *result, *builtins_module, *code, *globals;
+  PyObject *gettext, *result;
   const gchar *prgname;
 #if PY_VERSION_HEX < 0x03000000
   const char *argv[] = { NULL, NULL };
@@ -572,94 +557,10 @@ peas_plugin_loader_python_initialize (PeasPluginLoader *loader)
       goto python_init_error;
     }
 
-#if PY_VERSION_HEX < 0x03000000
-  builtins_module = PyImport_ImportModule ("__builtin__");
-#else
-  builtins_module = PyImport_ImportModule ("builtins");
-#endif
-
-  if (builtins_module == NULL)
-    goto python_init_error;
-
-  /* We don't use the byte-compiled Python source
-   * because glib-compile-resources cannot output
-   * depends for generated files.
-   *
-   * https://bugzilla.gnome.org/show_bug.cgi?id=673101
-   */
-
-  internal_python = g_resources_lookup_data ("/org/gnome/libpeas/loaders/"
-#if PY_VERSION_HEX < 0x03000000
-                                             "python/"
-#else
-                                             "python3/"
-#endif
-                                             "internal.py",
-                                             G_RESOURCE_LOOKUP_FLAGS_NONE,
-                                             NULL);
-
-  if (internal_python == NULL)
+  priv->internal = peas_python_internal_new ();
+  if (priv->internal == NULL)
     {
-      g_warning ("Error initializing Python Plugin Loader: "
-                 "failed to locate internal python code");
-
-      goto python_init_error;
-    }
-
-  /* Compile it manually so the filename is available */
-  code = Py_CompileString (g_bytes_get_data (internal_python, NULL),
-                           "peas-python-internal.py",
-                           Py_file_input);
-
-  g_bytes_unref (internal_python);
-
-  if (code == NULL)
-    {
-      g_warning ("Error initializing Python Plugin Loader: "
-                 "failed to compile internal python code");
-
-      goto python_init_error;
-    }
-
-  globals = PyDict_New ();
-  if (globals == NULL)
-    {
-      Py_DECREF (code);
-      goto python_init_error;
-    }
-
-  if (PyDict_SetItemString (globals, "__builtins__",
-                            PyModule_GetDict (builtins_module)) != 0)
-    {
-      Py_DECREF (globals);
-      Py_DECREF (code);
-      goto python_init_error;
-    }
-
-  result = PyEval_EvalCode ((gpointer) code, globals, globals);
-  Py_XDECREF (result);
-
-  Py_DECREF (code);
-
-  if (PyErr_Occurred ())
-    {
-      g_warning ("Error initializing Python Plugin Loader: "
-                 "failed to run internal python code");
-
-      Py_DECREF (globals);
-      goto python_init_error;
-    }
-
-  priv->hooks = PyDict_GetItemString (globals, "hooks");
-  Py_XINCREF (priv->hooks);
-
-  Py_DECREF (globals);
-
-  if (priv->hooks == NULL)
-    {
-      g_warning ("Error initializing Python Plugin Loader: "
-                 "failed to find internal python hooks");
-
+      /* Already warned */
       goto python_init_error;
     }
 
@@ -715,14 +616,11 @@ peas_plugin_loader_python_finalize (GObject *object)
       PyGILState_Release (state);
     }
 
-  if (priv->hooks != NULL && !priv->init_failed)
+  if (priv->internal != NULL && !priv->init_failed)
     {
       state = PyGILState_Ensure ();
-      internal_python_hook (pyloader, "exit");
+      peas_python_internal_free (priv->internal);
       PyGILState_Release (state);
-
-      /* Borrowed Reference */
-      priv->hooks = NULL;
     }
 
   if (priv->py_thread_state)
diff --git a/loaders/python/peas-python-internal.c b/loaders/python/peas-python-internal.c
new file mode 100644
index 0000000..c7d175b
--- /dev/null
+++ b/loaders/python/peas-python-internal.c
@@ -0,0 +1,169 @@
+/*
+ * peas-python-internal.c
+ * This file is part of libpeas
+ *
+ * Copyright (C) 2014-2015 - Garrett Regier
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Library General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "peas-python-internal.h"
+
+#include <gio/gio.h>
+
+/* _POSIX_C_SOURCE is defined in Python.h and in limits.h included by
+ * glib-object.h, so we unset it here to avoid a warning. Yep, that's bad.
+ */
+#undef _POSIX_C_SOURCE
+#include <Python.h>
+
+
+typedef PyObject _PeasPythonInternal;
+
+
+PeasPythonInternal *
+peas_python_internal_new (void)
+{
+  GBytes *internal_python;
+  PyObject *builtins_module, *code, *globals, *result, *internal;
+
+#if PY_MAJOR_VERSION < 3
+  builtins_module = PyImport_ImportModule ("__builtin__");
+#else
+  builtins_module = PyImport_ImportModule ("builtins");
+#endif
+
+  if (builtins_module == NULL)
+    {
+      g_warning ("Error initializing Python Plugin Loader: "
+                 "failed to get builtins module");
+
+      return NULL;
+    }
+
+  /* We don't use the byte-compiled Python source
+   * because glib-compile-resources cannot output
+   * depends for generated files.
+   *
+   * https://bugzilla.gnome.org/show_bug.cgi?id=673101
+   */
+
+  internal_python = g_resources_lookup_data ("/org/gnome/libpeas/loaders/"
+#if PY_MAJOR_VERSION < 3
+                                             "python/"
+#else
+                                             "python3/"
+#endif
+                                             "internal.py",
+                                             G_RESOURCE_LOOKUP_FLAGS_NONE,
+                                             NULL);
+
+  if (internal_python == NULL)
+    {
+      g_warning ("Error initializing Python Plugin Loader: "
+                 "failed to locate internal Python code");
+
+      return NULL;
+    }
+
+  /* Compile it manually so the filename is available */
+  code = Py_CompileString (g_bytes_get_data (internal_python, NULL),
+                           "peas-python-internal.py",
+                           Py_file_input);
+
+  g_bytes_unref (internal_python);
+
+  if (code == NULL)
+    {
+      g_warning ("Error initializing Python Plugin Loader: "
+                 "failed to compile internal Python code");
+
+      return NULL;
+    }
+
+  globals = PyDict_New ();
+  if (globals == NULL)
+    {
+      Py_DECREF (code);
+      return NULL;
+    }
+
+  if (PyDict_SetItemString (globals, "__builtins__",
+                            PyModule_GetDict (builtins_module)) != 0)
+    {
+      Py_DECREF (globals);
+      Py_DECREF (code);
+      return NULL;
+    }
+
+  result = PyEval_EvalCode ((gpointer) code, globals, globals);
+  Py_XDECREF (result);
+
+  Py_DECREF (code);
+
+  if (PyErr_Occurred ())
+    {
+      g_warning ("Error initializing Python Plugin Loader: "
+                 "failed to run internal Python code");
+
+      Py_DECREF (globals);
+      return NULL;
+    }
+
+  internal = PyDict_GetItemString (globals, "hooks");
+  Py_XINCREF (internal);
+
+  Py_DECREF (globals);
+
+  if (internal == NULL)
+    {
+      g_warning ("Error initializing Python Plugin Loader: "
+                 "failed to find internal Python hooks");
+
+      return NULL;
+    }
+
+  return (PeasPythonInternal *) internal;
+}
+
+/* NOTE: This must be called with the GIL held */
+void
+peas_python_internal_free (PeasPythonInternal *internal)
+{
+  PyObject *internal_ = (PyObject *) internal;
+
+  peas_python_internal_call (internal, "exit");
+  Py_DECREF (internal_);
+}
+
+/* NOTE: This must be called with the GIL held */
+void
+peas_python_internal_call (PeasPythonInternal *internal,
+                           const gchar        *name)
+{
+  PyObject *internal_ = (PyObject *) internal;
+  PyObject *result;
+
+  result = PyObject_CallMethod (internal_, (gchar *) name, NULL);
+  Py_XDECREF (result);
+
+  if (PyErr_Occurred ())
+    PyErr_Print ();
+}
+
diff --git a/loaders/python/peas-python-internal.h b/loaders/python/peas-python-internal.h
new file mode 100644
index 0000000..e2c3124
--- /dev/null
+++ b/loaders/python/peas-python-internal.h
@@ -0,0 +1,40 @@
+/*
+ * peas-python-internal.h
+ * This file is part of libpeas
+ *
+ * Copyright (C) 2015 - Garrett Regier
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Library General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __PEAS_PYTHON_INTERNAL_H__
+#define __PEAS_PYTHON_INTERNAL_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct _PeasPythonInternal PeasPythonInternal;
+
+PeasPythonInternal *
+        peas_python_internal_new  (void);
+void    peas_python_internal_free (PeasPythonInternal *internal);
+
+void    peas_python_internal_call (PeasPythonInternal *internal,
+                                   const gchar        *name);
+
+G_END_DECLS
+
+#endif /* __PEAS_PYTHON_INTERNAL_H__ */
diff --git a/loaders/python3/Makefile.am b/loaders/python3/Makefile.am
index fb3ee29..f304e8f 100644
--- a/loaders/python3/Makefile.am
+++ b/loaders/python3/Makefile.am
@@ -18,6 +18,8 @@ loader_LTLIBRARIES = libpython3loader.la
 libpython3loader_la_SOURCES = \
        $(top_srcdir)/loaders/python/peas-plugin-loader-python.c        \
        $(top_srcdir)/loaders/python/peas-plugin-loader-python.h        \
+       $(top_srcdir)/loaders/python/peas-python-internal.c             \
+       $(top_srcdir)/loaders/python/peas-python-internal.h             \
        peas-python3-resources.c
 
 libpython3loader_la_LDFLAGS = \


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]