<commit_before>/*
 * peas-plugin-loader-python.c
 * This file is part of libpeas
 *
 * Copyright (C) 2008 - <NAME>
 * Copyright (C) 2009 - <NAME>
 *
 * libpeas is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * libpeas 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#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
 * glib-object.h, so we unset it here to avoid a warning. Yep, that's bad.
 */
#undef _POSIX_C_SOURCE
#include <pygobject.h>

typedef struct {
  PyThreadState *py_thread_state;

  guint n_loaded_plugins;

  guint init_failed : 1;
  guint must_finalize_python : 1;
} PeasPluginLoaderPythonPrivate;

G_DEFINE_TYPE_WITH_PRIVATE (PeasPluginLoaderPython,
                            peas_plugin_loader_python,
                            PEAS_TYPE_PLUGIN_LOADER)

#define GET_PRIV(o) \
  (peas_plugin_loader_python_get_instance_private (o))

static GQuark quark_extension_type = 0;

G_MODULE_EXPORT void
peas_register_types (PeasObjectModule *module)
{
  peas_object_module_register_extension_type (module,
                                              PEAS_TYPE_PLUGIN_LOADER,
                                              PEAS_TYPE_PLUGIN_LOADER_PYTHON);
}

static GType
find_python_extension_type (GType     exten_type,
                            PyObject *pymodule)
{
  PyObject *pyexten_type, *pytype;
  GType the_type = G_TYPE_INVALID;

  pyexten_type = pyg_type_wrapper_new (exten_type);

  pytype = peas_python_internal_call ("find_extension_type",
                                      &PyType_Type, "(OO)",
                                      pyexten_type, pymodule);
  Py_DECREF (pyexten_type);

  if (pytype != NULL)
    {
      the_type = pyg_type_from_object (pytype);
      Py_DECREF (pytype);

      g_return_val_if_fail (g_type_is_a (the_type, exten_type),
                            G_TYPE_INVALID);
    }

  return the_type;
}

static gboolean
peas_plugin_loader_python_provides_extension (PeasPluginLoader *loader,
                                              PeasPluginInfo   *info,
                                              GType             exten_type)
{
  PyObject *pymodule = info->loader_data;
  GType the_type;
  PyGILState_STATE state = PyGILState_Ensure ();

  the_type = find_python_extension_type (exten_type, pymodule);

  PyGILState_Release (state);
  return the_type != G_TYPE_INVALID;
}

static PeasExtension *
peas_plugin_loader_python_create_extension (PeasPluginLoader *loader,
                                            PeasPluginInfo   *info,
                                            GType             exten_type,
                                            guint             n_parameters,
                                            GParameter       *parameters)
{
  PyObject *pymodule = info->loader_data;
  GType the_type;
  GObject *object = NULL;
  PyObject *pyobject;
  PyObject *pyplinfo;
  PyGILState_STATE state = PyGILState_Ensure ();

  the_type = find_python_extension_type (exten_type, pymodule);
  if (the_type == G_TYPE_INVALID)
    goto out;

  object = g_object_newv (the_type, n_parameters, parameters);
  if (object == NULL)
    goto out;

  /* We have to remember which interface we are instantiating
   * for the deprecated peas_extension_get_extension_type().
   */
  g_object_set_qdata (object, quark_extension_type,
                      GSIZE_TO_POINTER (exten_type));

  pyobject = pygobject_new (object);
  pyplinfo = pyg_boxed_new (PEAS_TYPE_PLUGIN_INFO, info, TRUE, TRUE);

  /* Set the plugin info as an attribute of the instance */
  if (PyObject_SetAttrString (pyobject, "plugin_info", pyplinfo) != 0)
    {
      g_warning ("Failed to set 'plugin_info' for '%s'",<commit_msg>python: fix use of PeasExtension with GInitiallyUnowned<commit_after>/*
 * peas-plugin-loader-python.c
 * This file is part of libpeas
 *
 * Copyright (C) 2008 - <NAME>
 * Copyright (C) 2009 - <NAME>
 *
 * libpeas is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * libpeas 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#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
 * glib-object.h, so we unset it here to avoid a warning. Yep, that's bad.
 */
#undef _POSIX_C_SOURCE
#include <pygobject.h>

typedef struct {
  PyThreadState *py_thread_state;

  guint n_loaded_plugins;

  guint init_failed : 1;
  guint must_finalize_python : 1;
} PeasPluginLoaderPythonPrivate;

G_DEFINE_TYPE_WITH_PRIVATE (PeasPluginLoaderPython,
                            peas_plugin_loader_python,
                            PEAS_TYPE_PLUGIN_LOADER)

#define GET_PRIV(o) \
  (peas_plugin_loader_python_get_instance_private (o))

static GQuark quark_extension_type = 0;

G_MODULE_EXPORT void
peas_register_types (PeasObjectModule *module)
{
  peas_object_module_register_extension_type (module,
                                              PEAS_TYPE_PLUGIN_LOADER,
                                              PEAS_TYPE_PLUGIN_LOADER_PYTHON);
}

static GType
find_python_extension_type (GType     exten_type,
                            PyObject *pymodule)
{
  PyObject *pyexten_type, *pytype;
  GType the_type = G_TYPE_INVALID;

  pyexten_type = pyg_type_wrapper_new (exten_type);

  pytype = peas_python_internal_call ("find_extension_type",
                                      &PyType_Type, "(OO)",
                                      pyexten_type, pymodule);
  Py_DECREF (pyexten_type);

  if (pytype != NULL)
    {
      the_type = pyg_type_from_object (pytype);
      Py_DECREF (pytype);

      g_return_val_if_fail (g_type_is_a (the_type, exten_type),
                            G_TYPE_INVALID);
    }

  return the_type;
}

static gboolean
peas_plugin_loader_python_provides_extension (PeasPluginLoader *loader,
                                              PeasPluginInfo   *info,
                                              GType             exten_type)
{
  PyObject *pymodule = info->loader_data;
  GType the_type;
  PyGILState_STATE state = PyGILState_Ensure ();

  the_type = find_python_extension_type (exten_type, pymodule);

  PyGILState_Release (state);
  return the_type != G_TYPE_INVALID;
}

static PeasExtension *
peas_plugin_loader_python_create_extension (PeasPluginLoader *loader,
                                            PeasPluginInfo   *info,
                                            GType             exten_type,
                                            guint             n_parameters,
                                            GParameter       *parameters)
{
  PyObject *pymodule = info->loader_data;
  GType the_type;
  GObject *object = NULL;
  PyObject *pyobject;
  PyObject *pyplinfo;
  PyGILState_STATE state = PyGILState_Ensure ();

  the_type = find_python_extension_type (exten_type, pymodule);
  if (the_type == G_TYPE_INVALID)
    goto out;

  object = g_object_newv (the_type, n_parameters, parameters);
  if (object == NULL)
    goto out;

  /* Sink floating references if necessary */
  if (g_object_is_floating (object))
    g_object_ref_sink (object);

  /* We have to remember which interface we are instantiating
   * for the deprecated peas_extension_get_extension_type().
   */
  g_object_set_qdata (object, quark_extension_type,
                      GSIZE_TO_POINTER (exten_type));

  pyobject = pygobject_new (object);
  pyplinfo = pyg_boxed_new (PEAS_TYPE_PLUGIN_INFO, info, TRUE, TRUE);

  /* Set the plugin info as an attribute of the instance */
  if (PyObject_SetAttrString (pyobject, "plugin_info", pyplinfo) != 0)
    {
      g_warning ("Failed to set 'plugin_info' for '%s'",
{'fraction_non_alphanumeric': 0.0726993191302438, 'fraction_numerical': 0.005490885130683066, 'mean_word_length': 2.549103663289166, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 36, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4658063', 'n_tokens_mistral': 2828, 'n_tokens_neox': 2755, 'n_words': 745}