summaryrefslogtreecommitdiff
path: root/gi
diff options
context:
space:
mode:
Diffstat (limited to 'gi')
-rw-r--r--gi/overrides/GLib.py56
-rw-r--r--gi/overrides/GObject.py94
-rw-r--r--gi/overrides/__init__.py74
-rw-r--r--gi/pygi-basictype.c12
-rw-r--r--gi/pygi-cache.c39
-rw-r--r--gi/pygi-cache.h5
-rw-r--r--gi/pygi-closure.c4
-rw-r--r--gi/pygi-invoke.c41
8 files changed, 243 insertions, 82 deletions
diff --git a/gi/overrides/GLib.py b/gi/overrides/GLib.py
index ce15da1..455ea84 100644
--- a/gi/overrides/GLib.py
+++ b/gi/overrides/GLib.py
@@ -26,7 +26,7 @@ import sys
from ..module import get_introspection_module
from .._gi import (variant_type_from_string, source_new,
source_set_callback, io_channel_read)
-from ..overrides import override, deprecated
+from ..overrides import override, deprecated, deprecated_attr
from gi import PyGIDeprecationWarning, version_info
GLib = get_introspection_module('GLib')
@@ -40,6 +40,7 @@ __all__.append('option')
# Types and functions still needed from static bindings
from gi._gi import _glib
+from gi._gi import _gobject
from gi._error import GError
Error = GError
@@ -481,8 +482,10 @@ __all__.append('markup_escape_text')
# backwards compatible names from old static bindings
for n in ['DESKTOP', 'DOCUMENTS', 'DOWNLOAD', 'MUSIC', 'PICTURES',
'PUBLIC_SHARE', 'TEMPLATES', 'VIDEOS']:
- globals()['USER_DIRECTORY_' + n] = getattr(GLib.UserDirectory, 'DIRECTORY_' + n)
- __all__.append('USER_DIRECTORY_' + n)
+ attr = 'USER_DIRECTORY_' + n
+ deprecated_attr("GLib", attr, "GLib.UserDirectory.DIRECTORY_" + n)
+ globals()[attr] = getattr(GLib.UserDirectory, 'DIRECTORY_' + n)
+ __all__.append(attr)
for n in ['ERR', 'HUP', 'IN', 'NVAL', 'OUT', 'PRI']:
globals()['IO_' + n] = getattr(GLib.IOCondition, n)
@@ -490,30 +493,53 @@ for n in ['ERR', 'HUP', 'IN', 'NVAL', 'OUT', 'PRI']:
for n in ['APPEND', 'GET_MASK', 'IS_READABLE', 'IS_SEEKABLE',
'MASK', 'NONBLOCK', 'SET_MASK']:
- globals()['IO_FLAG_' + n] = getattr(GLib.IOFlags, n)
- __all__.append('IO_FLAG_' + n)
+ attr = 'IO_FLAG_' + n
+ deprecated_attr("GLib", attr, "GLib.IOFlags." + n)
+ globals()[attr] = getattr(GLib.IOFlags, n)
+ __all__.append(attr)
+
# spelling for the win
IO_FLAG_IS_WRITEABLE = GLib.IOFlags.IS_WRITABLE
+deprecated_attr("GLib", "IO_FLAG_IS_WRITEABLE", "GLib.IOFlags.IS_WRITABLE")
__all__.append('IO_FLAG_IS_WRITEABLE')
for n in ['AGAIN', 'EOF', 'ERROR', 'NORMAL']:
- globals()['IO_STATUS_' + n] = getattr(GLib.IOStatus, n)
- __all__.append('IO_STATUS_' + n)
+ attr = 'IO_STATUS_' + n
+ globals()[attr] = getattr(GLib.IOStatus, n)
+ deprecated_attr("GLib", attr, "GLib.IOStatus." + n)
+ __all__.append(attr)
for n in ['CHILD_INHERITS_STDIN', 'DO_NOT_REAP_CHILD', 'FILE_AND_ARGV_ZERO',
'LEAVE_DESCRIPTORS_OPEN', 'SEARCH_PATH', 'STDERR_TO_DEV_NULL',
'STDOUT_TO_DEV_NULL']:
- globals()['SPAWN_' + n] = getattr(GLib.SpawnFlags, n)
- __all__.append('SPAWN_' + n)
+ attr = 'SPAWN_' + n
+ globals()[attr] = getattr(GLib.SpawnFlags, n)
+ deprecated_attr("GLib", attr, "GLib.SpawnFlags." + n)
+ __all__.append(attr)
for n in ['HIDDEN', 'IN_MAIN', 'REVERSE', 'NO_ARG', 'FILENAME', 'OPTIONAL_ARG',
'NOALIAS']:
- globals()['OPTION_FLAG_' + n] = getattr(GLib.OptionFlags, n)
- __all__.append('OPTION_FLAG_' + n)
+ attr = 'OPTION_FLAG_' + n
+ globals()[attr] = getattr(GLib.OptionFlags, n)
+ deprecated_attr("GLib", attr, "GLib.OptionFlags." + n)
+ __all__.append(attr)
for n in ['UNKNOWN_OPTION', 'BAD_VALUE', 'FAILED']:
- globals()['OPTION_ERROR_' + n] = getattr(GLib.OptionError, n)
- __all__.append('OPTION_ERROR_' + n)
+ attr = 'OPTION_ERROR_' + n
+ deprecated_attr("GLib", attr, "GLib.OptionError." + n)
+ globals()[attr] = getattr(GLib.OptionError, n)
+ __all__.append(attr)
+
+
+# these are not currently exported in GLib gir, presumably because they are
+# platform dependent; so get them from our static bindings
+for name in ['G_MINFLOAT', 'G_MAXFLOAT', 'G_MINDOUBLE', 'G_MAXDOUBLE',
+ 'G_MINSHORT', 'G_MAXSHORT', 'G_MAXUSHORT', 'G_MININT', 'G_MAXINT',
+ 'G_MAXUINT', 'G_MINLONG', 'G_MAXLONG', 'G_MAXULONG', 'G_MAXSIZE',
+ 'G_MINSSIZE', 'G_MAXSSIZE', 'G_MINOFFSET', 'G_MAXOFFSET']:
+ attr = name.split("_", 1)[-1]
+ globals()[attr] = getattr(_gobject, name)
+ __all__.append(attr)
class MainLoop(GLib.MainLoop):
@@ -901,5 +927,9 @@ if not hasattr(GLib, 'unix_signal_add_full'):
# obsolete constants for backwards compatibility
glib_version = (GLib.MAJOR_VERSION, GLib.MINOR_VERSION, GLib.MICRO_VERSION)
__all__.append('glib_version')
+deprecated_attr("GLib", "glib_version",
+ "(GLib.MAJOR_VERSION, GLib.MINOR_VERSION, GLib.MICRO_VERSION)")
+
pyglib_version = version_info
__all__.append('pyglib_version')
+deprecated_attr("GLib", "pyglib_version", "gi.version_info")
diff --git a/gi/overrides/GObject.py b/gi/overrides/GObject.py
index e922ac0..28408b2 100644
--- a/gi/overrides/GObject.py
+++ b/gi/overrides/GObject.py
@@ -27,7 +27,7 @@ from collections import namedtuple
import gi.overrides
import gi.module
-from gi.overrides import override
+from gi.overrides import override, deprecated_attr
from gi.repository import GLib
from gi import PyGIDeprecationWarning
@@ -56,10 +56,11 @@ for name in ['markup_escape_text', 'get_application_name',
'idle_add', 'timeout_add', 'timeout_add_seconds',
'io_add_watch', 'child_watch_add', 'get_current_time',
'spawn_async']:
- globals()[name] = gi.overrides.deprecated(getattr(GLib, name), 'GLib.' + name)
+ globals()[name] = getattr(GLib, name)
+ deprecated_attr("GObject", name, "GLib." + name)
__all__.append(name)
-# constants are also deprecated, but cannot mark them as such
+# deprecated constants
for name in ['PRIORITY_DEFAULT', 'PRIORITY_DEFAULT_IDLE', 'PRIORITY_HIGH',
'PRIORITY_HIGH_IDLE', 'PRIORITY_LOW',
'IO_IN', 'IO_OUT', 'IO_PRI', 'IO_ERR', 'IO_HUP', 'IO_NVAL',
@@ -77,25 +78,21 @@ for name in ['PRIORITY_DEFAULT', 'PRIORITY_DEFAULT_IDLE', 'PRIORITY_HIGH',
'OPTION_FLAG_NOALIAS', 'OPTION_ERROR_UNKNOWN_OPTION',
'OPTION_ERROR_BAD_VALUE', 'OPTION_ERROR_FAILED', 'OPTION_REMAINING',
'glib_version']:
- globals()[name] = getattr(GLib, name)
+ with warnings.catch_warnings():
+ # TODO: this uses deprecated Glib attributes, silence for now
+ warnings.simplefilter('ignore', PyGIDeprecationWarning)
+ globals()[name] = getattr(GLib, name)
+ deprecated_attr("GObject", name, "GLib." + name)
__all__.append(name)
-G_MININT8 = GLib.MININT8
-G_MAXINT8 = GLib.MAXINT8
-G_MAXUINT8 = GLib.MAXUINT8
-G_MININT16 = GLib.MININT16
-G_MAXINT16 = GLib.MAXINT16
-G_MAXUINT16 = GLib.MAXUINT16
-G_MININT32 = GLib.MININT32
-G_MAXINT32 = GLib.MAXINT32
-G_MAXUINT32 = GLib.MAXUINT32
-G_MININT64 = GLib.MININT64
-G_MAXINT64 = GLib.MAXINT64
-G_MAXUINT64 = GLib.MAXUINT64
-__all__ += ['G_MININT8', 'G_MAXINT8', 'G_MAXUINT8', 'G_MININT16',
- 'G_MAXINT16', 'G_MAXUINT16', 'G_MININT32', 'G_MAXINT32',
- 'G_MAXUINT32', 'G_MININT64', 'G_MAXINT64', 'G_MAXUINT64']
+for name in ['G_MININT8', 'G_MAXINT8', 'G_MAXUINT8', 'G_MININT16',
+ 'G_MAXINT16', 'G_MAXUINT16', 'G_MININT32', 'G_MAXINT32',
+ 'G_MAXUINT32', 'G_MININT64', 'G_MAXINT64', 'G_MAXUINT64']:
+ new_name = name.split("_", 1)[-1]
+ globals()[name] = getattr(GLib, new_name)
+ deprecated_attr("GObject", name, "GLib." + new_name)
+ __all__.append(name)
# these are not currently exported in GLib gir, presumably because they are
# platform dependent; so get them from our static bindings
@@ -103,7 +100,9 @@ for name in ['G_MINFLOAT', 'G_MAXFLOAT', 'G_MINDOUBLE', 'G_MAXDOUBLE',
'G_MINSHORT', 'G_MAXSHORT', 'G_MAXUSHORT', 'G_MININT', 'G_MAXINT',
'G_MAXUINT', 'G_MINLONG', 'G_MAXLONG', 'G_MAXULONG', 'G_MAXSIZE',
'G_MINSSIZE', 'G_MAXSSIZE', 'G_MINOFFSET', 'G_MAXOFFSET']:
- globals()[name] = getattr(_gobject, name)
+ new_name = name.split("_", 1)[-1]
+ globals()[name] = getattr(GLib, new_name)
+ deprecated_attr("GObject", name, "GLib." + new_name)
__all__.append(name)
@@ -145,38 +144,44 @@ __all__ += ['TYPE_INVALID', 'TYPE_NONE', 'TYPE_INTERFACE', 'TYPE_CHAR',
# Deprecated, use GLib directly
-Pid = GLib.Pid
-GError = GLib.GError
-OptionGroup = GLib.OptionGroup
-OptionContext = GLib.OptionContext
-__all__ += ['Pid', 'GError', 'OptionGroup', 'OptionContext']
+for name in ['Pid', 'GError', 'OptionGroup', 'OptionContext']:
+ globals()[name] = getattr(GLib, name)
+ deprecated_attr("GObject", name, "GLib." + name)
+ __all__.append(name)
# Deprecated, use: GObject.ParamFlags.* directly
-PARAM_CONSTRUCT = GObjectModule.ParamFlags.CONSTRUCT
-PARAM_CONSTRUCT_ONLY = GObjectModule.ParamFlags.CONSTRUCT_ONLY
-PARAM_LAX_VALIDATION = GObjectModule.ParamFlags.LAX_VALIDATION
-PARAM_READABLE = GObjectModule.ParamFlags.READABLE
-PARAM_WRITABLE = GObjectModule.ParamFlags.WRITABLE
+for name in ['PARAM_CONSTRUCT', 'PARAM_CONSTRUCT_ONLY', 'PARAM_LAX_VALIDATION',
+ 'PARAM_READABLE', 'PARAM_WRITABLE']:
+ new_name = name.split("_", 1)[-1]
+ globals()[name] = getattr(GObjectModule.ParamFlags, new_name)
+ deprecated_attr("GObject", name, "GObject.ParamFlags." + new_name)
+ __all__.append(name)
+
# PARAM_READWRITE should come from the gi module but cannot due to:
# https://bugzilla.gnome.org/show_bug.cgi?id=687615
-PARAM_READWRITE = PARAM_READABLE | PARAM_WRITABLE
-__all__ += ['PARAM_CONSTRUCT', 'PARAM_CONSTRUCT_ONLY', 'PARAM_LAX_VALIDATION',
- 'PARAM_READABLE', 'PARAM_WRITABLE', 'PARAM_READWRITE']
+PARAM_READWRITE = GObjectModule.ParamFlags.READABLE | \
+ GObjectModule.ParamFlags.WRITABLE
+__all__.append("PARAM_READWRITE")
+# READWRITE is part of ParamFlags since glib 2.42. Only mark PARAM_READWRITE as
+# deprecated in case ParamFlags.READWRITE is available. Also include the glib
+# version in the warning so it's clear that this needs a newer glib, unlike
+# the other ParamFlags related deprecations.
+# https://bugzilla.gnome.org/show_bug.cgi?id=726037
+if hasattr(GObjectModule.ParamFlags, "READWRITE"):
+ deprecated_attr("GObject", "PARAM_READWRITE",
+ "GObject.ParamFlags.READWRITE (glib 2.42+)")
-# Deprecated, use: GObject.SignalFlags.* directly
-SIGNAL_ACTION = GObjectModule.SignalFlags.ACTION
-SIGNAL_DETAILED = GObjectModule.SignalFlags.DETAILED
-SIGNAL_NO_HOOKS = GObjectModule.SignalFlags.NO_HOOKS
-SIGNAL_NO_RECURSE = GObjectModule.SignalFlags.NO_RECURSE
-SIGNAL_RUN_CLEANUP = GObjectModule.SignalFlags.RUN_CLEANUP
-SIGNAL_RUN_FIRST = GObjectModule.SignalFlags.RUN_FIRST
-SIGNAL_RUN_LAST = GObjectModule.SignalFlags.RUN_LAST
-__all__ += ['SIGNAL_ACTION', 'SIGNAL_DETAILED', 'SIGNAL_NO_HOOKS',
- 'SIGNAL_NO_RECURSE', 'SIGNAL_RUN_CLEANUP', 'SIGNAL_RUN_FIRST',
- 'SIGNAL_RUN_LAST']
+# Deprecated, use: GObject.SignalFlags.* directly
+for name in ['SIGNAL_ACTION', 'SIGNAL_DETAILED', 'SIGNAL_NO_HOOKS',
+ 'SIGNAL_NO_RECURSE', 'SIGNAL_RUN_CLEANUP', 'SIGNAL_RUN_FIRST',
+ 'SIGNAL_RUN_LAST']:
+ new_name = name.split("_", 1)[-1]
+ globals()[name] = getattr(GObjectModule.SignalFlags, new_name)
+ deprecated_attr("GObject", name, "GObject.SignalFlags." + new_name)
+ __all__.append(name)
# Static types
GBoxed = _gobject.GBoxed
@@ -705,4 +710,5 @@ SignalOverride = signalhelper.SignalOverride
# Deprecated naming "property" available for backwards compatibility.
# Keep this at the end of the file to avoid clobbering the builtin.
property = Property
+deprecated_attr("GObject", "property", "GObject.Property")
__all__ += ['Property', 'Signal', 'SignalOverride', 'property']
diff --git a/gi/overrides/__init__.py b/gi/overrides/__init__.py
index b337b35..62cfd30 100644
--- a/gi/overrides/__init__.py
+++ b/gi/overrides/__init__.py
@@ -14,6 +14,10 @@ from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
+# namespace -> (attr, replacement)
+_deprecated_attrs = {}
+
+
def wraps(wrapped):
def assign(wrapper):
wrapper.__name__ = wrapped.__name__
@@ -43,6 +47,37 @@ class OverridesProxyModule(types.ModuleType):
return "<%s %r>" % (type(self).__name__, self._introspection_module)
+class _DeprecatedAttribute(object):
+ """A deprecation descriptor for OverridesProxyModule subclasses.
+
+ Emits a PyGIDeprecationWarning on every access and tries to act as a
+ normal instance attribute (can be replaced and deleted).
+ """
+
+ def __init__(self, namespace, attr, value, replacement):
+ self._attr = attr
+ self._value = value
+ self._warning = PyGIDeprecationWarning(
+ '%s.%s is deprecated; use %s instead' % (
+ namespace, attr, replacement))
+
+ def __get__(self, instance, owner):
+ if instance is None:
+ raise AttributeError(self._attr)
+ warnings.warn(self._warning, stacklevel=2)
+ return self._value
+
+ def __set__(self, instance, value):
+ attr = self._attr
+ # delete the descriptor, then set the instance value
+ delattr(type(instance), attr)
+ setattr(instance, attr, value)
+
+ def __delete__(self, instance):
+ # delete the descriptor
+ delattr(type(instance), self._attr)
+
+
def load_overrides(introspection_module):
"""Loads overrides for an introspection module.
@@ -58,7 +93,11 @@ def load_overrides(introspection_module):
has_old = module_key in sys.modules
old_module = sys.modules.get(module_key)
- proxy = OverridesProxyModule(introspection_module)
+ # Create a new sub type, so we can separate descriptors like
+ # _DeprecatedAttribute for each namespace.
+ proxy_type = type(namespace + "ProxyModule", (OverridesProxyModule, ), {})
+
+ proxy = proxy_type(introspection_module)
sys.modules[module_key] = proxy
# backwards compat:
@@ -90,6 +129,19 @@ def load_overrides(introspection_module):
continue
setattr(proxy, var, item)
+ # Replace deprecated module level attributes with a descriptor
+ # which emits a warning when accessed.
+ for attr, replacement in _deprecated_attrs.pop(namespace, []):
+ try:
+ value = getattr(proxy, attr)
+ except AttributeError:
+ raise AssertionError(
+ "%s was set deprecated but wasn't added to __all__" % attr)
+ delattr(proxy, attr)
+ deprecated_attr = _DeprecatedAttribute(
+ namespace, attr, value, replacement)
+ setattr(proxy_type, attr, deprecated_attr)
+
return proxy
@@ -152,6 +204,26 @@ def deprecated(fn, replacement):
return wrapped
+def deprecated_attr(namespace, attr, replacement):
+ """Marks a module level attribute as deprecated. Accessing it will emit
+ a PyGIDeprecationWarning warning.
+
+ e.g. for ``deprecated_attr("GObject", "STATUS_FOO", "GLib.Status.FOO")``
+ accessing GObject.STATUS_FOO will emit:
+
+ "GObject.STATUS_FOO is deprecated; use GLib.Status.FOO instead"
+
+ :param str namespace:
+ The namespace of the override this is called in.
+ :param str namespace:
+ The attribute name (which gets added to __all__).
+ :param str replacement:
+ The replacement text which will be included in the warning.
+ """
+
+ _deprecated_attrs.setdefault(namespace, []).append((attr, replacement))
+
+
def deprecated_init(super_init_func, arg_names, ignore=tuple(),
deprecated_aliases={}, deprecated_defaults={},
category=PyGIDeprecationWarning,
diff --git a/gi/pygi-basictype.c b/gi/pygi-basictype.c
index e199741..432559d 100644
--- a/gi/pygi-basictype.c
+++ b/gi/pygi-basictype.c
@@ -253,18 +253,18 @@ _pygi_marshal_from_py_filename (PyObject *py_arg,
{
gchar *string_;
GError *error = NULL;
+ PyObject *tmp = NULL;
if (PyUnicode_Check (py_arg)) {
- PyObject *pystr_obj = PyUnicode_AsUTF8String (py_arg);
- if (!pystr_obj)
+ tmp = PyUnicode_AsUTF8String (py_arg);
+ if (!tmp)
return FALSE;
- string_ = g_strdup (PYGLIB_PyBytes_AsString (pystr_obj));
- Py_DECREF (pystr_obj);
+ string_ = PYGLIB_PyBytes_AsString (tmp);
}
#if PY_VERSION_HEX < 0x03000000
else if (PyString_Check (py_arg)) {
- string_ = g_strdup (PyString_AsString (py_arg));
+ string_ = PyString_AsString (py_arg);
}
#endif
else {
@@ -274,7 +274,7 @@ _pygi_marshal_from_py_filename (PyObject *py_arg,
}
arg->v_string = g_filename_from_utf8 (string_, -1, NULL, NULL, &error);
- g_free (string_);
+ Py_XDECREF (tmp);
if (arg->v_string == NULL) {
PyErr_SetString (PyExc_Exception, error->message);
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
index a572929..ca24517 100644
--- a/gi/pygi-cache.c
+++ b/gi/pygi-cache.c
@@ -657,6 +657,7 @@ _callable_cache_init (PyGICallableCache *cache,
GICallableInfo *callable_info)
{
gint n_args;
+ GIBaseInfo *container;
if (cache->deinit == NULL)
cache->deinit = _callable_cache_deinit_real;
@@ -665,18 +666,27 @@ _callable_cache_init (PyGICallableCache *cache,
cache->generate_args_cache = _callable_cache_generate_args_cache_real;
cache->name = g_base_info_get_name ((GIBaseInfo *) callable_info);
+ cache->namespace = g_base_info_get_namespace ((GIBaseInfo *) callable_info);
+ container = g_base_info_get_container ((GIBaseInfo *) callable_info);
+ cache->container_name = NULL;
+ /* https://bugzilla.gnome.org/show_bug.cgi?id=709456 */
+ if (container != NULL && g_base_info_get_type (container) != GI_INFO_TYPE_TYPE) {
+ cache->container_name = g_base_info_get_name (container);
+ }
cache->throws = g_callable_info_can_throw_gerror ((GIBaseInfo *) callable_info);
if (g_base_info_is_deprecated (callable_info)) {
const gchar *deprecated = g_base_info_get_attribute (callable_info, "deprecated");
gchar *warning;
+ gchar *full_name = pygi_callable_cache_get_full_name (cache);
if (deprecated != NULL)
- warning = g_strdup_printf ("%s.%s is deprecated: %s",
- g_base_info_get_namespace (callable_info), cache->name,
+ warning = g_strdup_printf ("%s is deprecated: %s",
+ full_name,
deprecated);
else
- warning = g_strdup_printf ("%s.%s is deprecated",
- g_base_info_get_namespace (callable_info), cache->name);
+ warning = g_strdup_printf ("%s is deprecated",
+ full_name);
+ g_free (full_name);
PyErr_WarnEx (PyExc_DeprecationWarning, warning, 0);
g_free (warning);
}
@@ -696,6 +706,23 @@ _callable_cache_init (PyGICallableCache *cache,
return TRUE;
}
+gchar *
+pygi_callable_cache_get_full_name (PyGICallableCache *cache)
+{
+ if (cache->container_name != NULL) {
+ return g_strjoin (".",
+ cache->namespace,
+ cache->container_name,
+ cache->name,
+ NULL);
+ } else {
+ return g_strjoin (".",
+ cache->namespace,
+ cache->name,
+ NULL);
+ }
+}
+
void
pygi_callable_cache_free (PyGICallableCache *cache)
{
@@ -845,11 +872,13 @@ _constructor_cache_invoke_real (PyGIFunctionCache *function_cache,
constructor_class = PyTuple_GetItem (py_args, 0);
if (constructor_class == NULL) {
+ gchar *full_name = pygi_callable_cache_get_full_name (cache);
PyErr_Clear ();
PyErr_Format (PyExc_TypeError,
"Constructors require the class to be passed in as an argument, "
"No arguments passed to the %s constructor.",
- ((PyGICallableCache *) function_cache)->name);
+ full_name);
+ g_free (full_name);
return FALSE;
}
diff --git a/gi/pygi-cache.h b/gi/pygi-cache.h
index 0361f00..098f3f1 100644
--- a/gi/pygi-cache.h
+++ b/gi/pygi-cache.h
@@ -158,6 +158,8 @@ typedef struct _PyGIInterfaceCache
struct _PyGICallableCache
{
const gchar *name;
+ const gchar *container_name;
+ const gchar *namespace;
PyGICallingContext calling_context;
@@ -265,6 +267,9 @@ pygi_arg_cache_free (PyGIArgCache *cache);
void
pygi_callable_cache_free (PyGICallableCache *cache);
+gchar *
+pygi_callable_cache_get_full_name (PyGICallableCache *cache);
+
PyGIFunctionCache *
pygi_function_cache_new (GICallableInfo *info);
diff --git a/gi/pygi-closure.c b/gi/pygi-closure.c
index 2a5a120..65f7e55 100644
--- a/gi/pygi-closure.c
+++ b/gi/pygi-closure.c
@@ -777,10 +777,12 @@ _pygi_marshal_from_py_interface_callback (PyGIInvokeState *state,
if (user_data_cache != NULL) {
state->arg_values[destroy_cache->c_arg_index].v_pointer = _pygi_invoke_closure_free;
} else {
+ char *full_name = pygi_callable_cache_get_full_name (callable_cache);
gchar *msg = g_strdup_printf("Callables passed to %s will leak references because "
"the method does not support a user_data argument. "
"See: https://bugzilla.gnome.org/show_bug.cgi?id=685598",
- callable_cache->name);
+ full_name);
+ g_free (full_name);
if (PyErr_WarnEx(PyExc_RuntimeWarning, msg, 2)) {
g_free(msg);
_pygi_invoke_closure_free(closure);
diff --git a/gi/pygi-invoke.c b/gi/pygi-invoke.c
index a65274a..0151650 100644
--- a/gi/pygi-invoke.c
+++ b/gi/pygi-invoke.c
@@ -26,7 +26,7 @@
#include "pygi-error.h"
static gboolean
-_check_for_unexpected_kwargs (const gchar *function_name,
+_check_for_unexpected_kwargs (PyGICallableCache *cache,
GHashTable *arg_name_hash,
PyObject *py_kwargs)
{
@@ -54,11 +54,13 @@ _check_for_unexpected_kwargs (const gchar *function_name,
* found which maps to index 0 for our hash lookup.
*/
if (!g_hash_table_lookup_extended (arg_name_hash, PyBytes_AsString(key), NULL, NULL)) {
+ char *full_name = pygi_callable_cache_get_full_name (cache);
PyErr_Format (PyExc_TypeError,
"%.200s() got an unexpected keyword argument '%.400s'",
- function_name,
+ full_name,
PyBytes_AsString (key));
Py_DECREF (key);
+ g_free (full_name);
return FALSE;
}
@@ -84,7 +86,6 @@ _py_args_combine_and_check_length (PyGICallableCache *cache,
Py_ssize_t n_py_args, n_py_kwargs, i;
guint n_expected_args;
GSList *l;
- const gchar *function_name = cache->name;
n_py_args = PyTuple_GET_SIZE (py_args);
if (py_kwargs == NULL)
@@ -100,24 +101,28 @@ _py_args_combine_and_check_length (PyGICallableCache *cache,
}
if (cache->user_data_varargs_index < 0 && n_expected_args < n_py_args) {
+ char *full_name = pygi_callable_cache_get_full_name (cache);
PyErr_Format (PyExc_TypeError,
"%.200s() takes exactly %d %sargument%s (%zd given)",
- function_name,
+ full_name,
n_expected_args,
n_py_kwargs > 0 ? "non-keyword " : "",
n_expected_args == 1 ? "" : "s",
n_py_args);
+ g_free (full_name);
return NULL;
}
if (cache->user_data_varargs_index >= 0 && n_py_kwargs > 0 && n_expected_args < n_py_args) {
+ char *full_name = pygi_callable_cache_get_full_name (cache);
PyErr_Format (PyExc_TypeError,
"%.200s() cannot use variable user data arguments with keyword arguments",
- function_name);
+ full_name);
+ g_free (full_name);
return NULL;
}
- if (n_py_kwargs > 0 && !_check_for_unexpected_kwargs (function_name,
+ if (n_py_kwargs > 0 && !_check_for_unexpected_kwargs (cache,
cache->arg_name_hash,
py_kwargs)) {
return NULL;
@@ -183,24 +188,28 @@ _py_args_combine_and_check_length (PyGICallableCache *cache,
Py_INCREF (_PyGIDefaultArgPlaceholder);
PyTuple_SET_ITEM (combined_py_args, i, _PyGIDefaultArgPlaceholder);
} else {
+ char *full_name = pygi_callable_cache_get_full_name (cache);
PyErr_Format (PyExc_TypeError,
"%.200s() takes exactly %d %sargument%s (%zd given)",
- function_name,
+ full_name,
n_expected_args,
n_py_kwargs > 0 ? "non-keyword " : "",
n_expected_args == 1 ? "" : "s",
n_py_args);
+ g_free (full_name);
Py_DECREF (combined_py_args);
return NULL;
}
} else if (kw_arg_item != NULL && py_arg_item != NULL) {
+ char *full_name = pygi_callable_cache_get_full_name (cache);
PyErr_Format (PyExc_TypeError,
"%.200s() got multiple values for keyword argument '%.200s'",
- function_name,
+ full_name,
arg_name);
Py_DECREF (combined_py_args);
+ g_free (full_name);
return NULL;
}
}
@@ -362,11 +371,13 @@ _invoke_marshal_in_args (PyGIInvokeState *state, PyGIFunctionCache *function_cac
gssize i;
if (state->n_py_in_args > cache->n_py_args) {
+ char *full_name = pygi_callable_cache_get_full_name (cache);
PyErr_Format (PyExc_TypeError,
"%s() takes exactly %zd argument(s) (%zd given)",
- cache->name,
+ full_name,
cache->n_py_args,
state->n_py_in_args);
+ g_free (full_name);
return FALSE;
}
@@ -387,11 +398,13 @@ _invoke_marshal_in_args (PyGIInvokeState *state, PyGIFunctionCache *function_cac
continue;
if (arg_cache->py_arg_index >= state->n_py_in_args) {
+ char *full_name = pygi_callable_cache_get_full_name (cache);
PyErr_Format (PyExc_TypeError,
"%s() takes exactly %zd argument(s) (%zd given)",
- cache->name,
+ full_name,
cache->n_py_args,
state->n_py_in_args);
+ g_free (full_name);
/* clean up all of the args we have already marshalled,
* since invoke will not be called
@@ -410,11 +423,13 @@ _invoke_marshal_in_args (PyGIInvokeState *state, PyGIFunctionCache *function_cac
case PYGI_DIRECTION_BIDIRECTIONAL:
if (arg_cache->meta_type != PYGI_META_ARG_TYPE_CHILD) {
if (arg_cache->py_arg_index >= state->n_py_in_args) {
+ char *full_name = pygi_callable_cache_get_full_name (cache);
PyErr_Format (PyExc_TypeError,
"%s() takes exactly %zd argument(s) (%zd given)",
- cache->name,
+ full_name,
cache->n_py_args,
state->n_py_in_args);
+ g_free (full_name);
pygi_marshal_cleanup_args_from_py_parameter_fail (state,
cache,
i);
@@ -446,9 +461,11 @@ _invoke_marshal_in_args (PyGIInvokeState *state, PyGIFunctionCache *function_cac
state->args[i] = c_arg;
if (!_caller_alloc (arg_cache, c_arg)) {
+ char *full_name = pygi_callable_cache_get_full_name (cache);
PyErr_Format (PyExc_TypeError,
"Could not caller allocate argument %zd of callable %s",
- i, cache->name);
+ i, full_name);
+ g_free (full_name);
pygi_marshal_cleanup_args_from_py_parameter_fail (state,
cache,
i);