[libpeas] Stop pretending that the Python internals are non-global



commit 7c6699c6fef4c51e22585dab1f09f4cc608652ac
Author: Garrett Regier <garrettregier gmail com>
Date:   Tue Jan 20 18:33:14 2015 -0800

    Stop pretending that the Python internals are non-global
    
    Python uses many globals, we might as well do the same.

 loaders/python/peas-plugin-loader-python.c |   36 +++++++-------------
 loaders/python/peas-python-internal.c      |   50 +++++++++++++---------------
 loaders/python/peas-python-internal.h      |   19 ++++-------
 3 files changed, 42 insertions(+), 63 deletions(-)
---
diff --git a/loaders/python/peas-plugin-loader-python.c b/loaders/python/peas-plugin-loader-python.c
index 7b6d1e9..e85a73f 100644
--- a/loaders/python/peas-plugin-loader-python.c
+++ b/loaders/python/peas-plugin-loader-python.c
@@ -35,7 +35,6 @@
 #include <pygobject.h>
 
 typedef struct {
-  PeasPythonInternal *internal;
   PyThreadState *py_thread_state;
 
   guint n_loaded_plugins;
@@ -63,18 +62,15 @@ peas_register_types (PeasObjectModule *module)
 }
 
 static GType
-find_python_extension_type (PeasPluginLoaderPython *pyloader,
-                            GType                   exten_type,
-                            PyObject               *pymodule)
+find_python_extension_type (GType     exten_type,
+                            PyObject *pymodule)
 {
-  PeasPluginLoaderPythonPrivate *priv = GET_PRIV (pyloader);
   PyObject *pyexten_type, *pytype;
   GType the_type = G_TYPE_INVALID;
 
   pyexten_type = pyg_type_wrapper_new (exten_type);
 
-  pytype = peas_python_internal_call (priv->internal,
-                                      "find_extension_type",
+  pytype = peas_python_internal_call ("find_extension_type",
                                       &PyType_Type, "(OO)",
                                       pyexten_type, pymodule);
   Py_DECREF (pyexten_type);
@@ -96,12 +92,11 @@ peas_plugin_loader_python_provides_extension (PeasPluginLoader *loader,
                                               PeasPluginInfo   *info,
                                               GType             exten_type)
 {
-  PeasPluginLoaderPython *pyloader = PEAS_PLUGIN_LOADER_PYTHON (loader);
   PyObject *pymodule = info->loader_data;
   GType the_type;
   PyGILState_STATE state = PyGILState_Ensure ();
 
-  the_type = find_python_extension_type (pyloader, exten_type, pymodule);
+  the_type = find_python_extension_type (exten_type, pymodule);
 
   PyGILState_Release (state);
   return the_type != G_TYPE_INVALID;
@@ -114,7 +109,6 @@ peas_plugin_loader_python_create_extension (PeasPluginLoader *loader,
                                             guint             n_parameters,
                                             GParameter       *parameters)
 {
-  PeasPluginLoaderPython *pyloader = PEAS_PLUGIN_LOADER_PYTHON (loader);
   PyObject *pymodule = info->loader_data;
   GType the_type;
   GObject *object = NULL;
@@ -122,7 +116,7 @@ peas_plugin_loader_python_create_extension (PeasPluginLoader *loader,
   PyObject *pyplinfo;
   PyGILState_STATE state = PyGILState_Ensure ();
 
-  the_type = find_python_extension_type (pyloader, exten_type, pymodule);
+  the_type = find_python_extension_type (exten_type, pymodule);
   if (the_type == G_TYPE_INVALID)
     goto out;
 
@@ -173,8 +167,7 @@ peas_plugin_loader_python_load (PeasPluginLoader *loader,
   module_dir = peas_plugin_info_get_module_dir (info);
   module_name = peas_plugin_info_get_module_name (info);
 
-  pymodule = peas_python_internal_call (priv->internal, "load",
-                                        &PyModule_Type, "(sss)",
+  pymodule = peas_python_internal_call ("load", &PyModule_Type, "(sss)",
                                         info->filename,
                                         module_dir, module_name);
 
@@ -200,10 +193,7 @@ peas_plugin_loader_python_unload (PeasPluginLoader *loader,
    * loader will not be finalized by applications
    */
   if (--priv->n_loaded_plugins == 0)
-    {
-      peas_python_internal_call (priv->internal, "all_plugins_unloaded",
-                                 NULL, NULL);
-    }
+    peas_python_internal_call ("all_plugins_unloaded", NULL, NULL);
 
   Py_CLEAR (info->loader_data);
   PyGILState_Release (state);
@@ -212,11 +202,9 @@ peas_plugin_loader_python_unload (PeasPluginLoader *loader,
 static void
 peas_plugin_loader_python_garbage_collect (PeasPluginLoader *loader)
 {
-  PeasPluginLoaderPython *pyloader = PEAS_PLUGIN_LOADER_PYTHON (loader);
-  PeasPluginLoaderPythonPrivate *priv = GET_PRIV (pyloader);
   PyGILState_STATE state = PyGILState_Ensure ();
 
-  peas_python_internal_call (priv->internal, "garbage_collect", NULL, NULL);
+  peas_python_internal_call ("garbage_collect", NULL, NULL);
 
   PyGILState_Release (state);
 }
@@ -278,8 +266,8 @@ peas_plugin_loader_python_initialize (PeasPluginLoader *loader)
   if (!priv->must_finalize_python)
     pyg_disable_warning_redirections ();
 
-  priv->internal = peas_python_internal_new (!priv->must_finalize_python);
-  if (priv->internal == NULL)
+  /* Must be done last, finalize() depends on init_failed */
+  if (!peas_python_internal_setup (!priv->must_finalize_python))
     {
       /* Already warned */
       goto python_init_error;
@@ -324,10 +312,10 @@ peas_plugin_loader_python_finalize (GObject *object)
 
   g_warn_if_fail (priv->n_loaded_plugins == 0);
 
-  if (priv->internal != NULL)
+  if (!priv->init_failed)
     {
       state = PyGILState_Ensure ();
-      peas_python_internal_free (priv->internal);
+      peas_python_internal_shutdown ();
       PyGILState_Release (state);
     }
 
diff --git a/loaders/python/peas-python-internal.c b/loaders/python/peas-python-internal.c
index dca8e61..e7c2b56 100644
--- a/loaders/python/peas-python-internal.c
+++ b/loaders/python/peas-python-internal.c
@@ -28,8 +28,7 @@
 #include <gio/gio.h>
 
 
-typedef PyObject _PeasPythonInternal;
-
+static PyObject *internal_hooks = NULL;
 static PyObject *FailedError = NULL;
 
 
@@ -60,15 +59,15 @@ static PyMethodDef failed_method_def = {
   "Prints warning and raises an Exception"
 };
 
-PeasPythonInternal *
-peas_python_internal_new (gboolean already_initialized)
+gboolean
+peas_python_internal_setup (gboolean already_initialized)
 {
-  GBytes *internal_python;
   const gchar *prgname;
-  PeasPythonInternal *internal = NULL;
-  PyObject *builtins_module, *globals;
+  GBytes *internal_python = NULL;
+  PyObject *builtins_module, *globals, *result;
   PyObject *code = NULL, *module = NULL;
-  PyObject *result = NULL, *failed_method = NULL;
+  PyObject *failed_method = NULL;
+  gboolean success = FALSE;
 
 #define goto_error_if_failed(cond) \
   G_STMT_START { \
@@ -142,10 +141,11 @@ peas_python_internal_new (gboolean already_initialized)
       goto error;
     }
 
-  result = PyDict_GetItemString (globals, "hooks");
-  goto_error_if_failed (result != NULL);
+  internal_hooks = PyDict_GetItemString (globals, "hooks");
+  goto_error_if_failed (internal_hooks != NULL);
+  Py_INCREF (internal_hooks);
 
-  goto_error_if_failed (PyObject_SetAttrString (result,
+  goto_error_if_failed (PyObject_SetAttrString (internal_hooks,
                                                 "__internal_module__",
                                                 module) == 0);
 
@@ -154,43 +154,39 @@ peas_python_internal_new (gboolean already_initialized)
 
   failed_method = PyCFunction_NewEx (&failed_method_def, NULL, module);
   goto_error_if_failed (failed_method != NULL);
-  goto_error_if_failed (PyObject_SetAttrString (result, "failed",
+  goto_error_if_failed (PyObject_SetAttrString (internal_hooks, "failed",
                                                 failed_method) == 0);
 
-  internal = (PeasPythonInternal *) result;
+  success = TRUE;
 
 #undef goto_error_if_failed
 
 error:
 
-  if (internal == NULL)
-    Py_XDECREF (result);
+  if (!success)
+    Py_CLEAR (internal_hooks);
 
   Py_XDECREF (failed_method);
   Py_XDECREF (module);
   Py_XDECREF (code);
   g_clear_pointer (&internal_python, g_bytes_unref);
 
-  return internal;
+  return success;
 }
 
 void
-peas_python_internal_free (PeasPythonInternal *internal)
+peas_python_internal_shutdown (void)
 {
-  PyObject *internal_ = (PyObject *) internal;
-
-  peas_python_internal_call (internal, "exit", NULL, NULL);
-  Py_DECREF (internal_);
+  peas_python_internal_call ("exit", NULL, NULL);
+  Py_CLEAR (internal_hooks);
 }
 
 PyObject *
-peas_python_internal_call (PeasPythonInternal *internal,
-                           const gchar        *name,
-                           PyTypeObject       *return_type,
-                           const gchar        *format,
+peas_python_internal_call (const gchar  *name,
+                           PyTypeObject *return_type,
+                           const gchar  *format,
                            ...)
 {
-  PyObject *internal_ = (PyObject *) internal;
   PyObject *args;
   PyObject *result = NULL;
   va_list var_args;
@@ -205,7 +201,7 @@ peas_python_internal_call (PeasPythonInternal *internal,
 
   if (args != NULL)
     {
-      result = PyObject_CallMethod (internal_, "call", "(sOO)",
+      result = PyObject_CallMethod (internal_hooks, "call", "(sOO)",
                                     name, args, return_type);
       Py_DECREF (args);
     }
diff --git a/loaders/python/peas-python-internal.h b/loaders/python/peas-python-internal.h
index df8735d..6c147a5 100644
--- a/loaders/python/peas-python-internal.h
+++ b/loaders/python/peas-python-internal.h
@@ -32,18 +32,13 @@
 
 G_BEGIN_DECLS
 
-typedef struct _PeasPythonInternal PeasPythonInternal;
-
-PeasPythonInternal *
-        peas_python_internal_new  (gboolean            already_initialized);
-void    peas_python_internal_free (PeasPythonInternal *internal);
-
-PyObject *
-        peas_python_internal_call (PeasPythonInternal *internal,
-                                   const gchar        *name,
-                                   PyTypeObject       *return_type,
-                                   const gchar        *format,
-                                   ...);
+gboolean  peas_python_internal_setup    (gboolean     already_initialized);
+void      peas_python_internal_shutdown (void);
+
+PyObject *peas_python_internal_call     (const gchar  *name,
+                                         PyTypeObject *return_type,
+                                         const gchar  *format,
+                                         ...);
 
 G_END_DECLS
 


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