summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Reiter <reiter.christoph@gmail.com>2015-01-27 19:13:54 +0100
committerChristoph Reiter <creiter@src.gnome.org>2015-03-03 13:01:23 +0100
commita10df7d28c01d70ee33d8e4e9ddaa23f1990ca60 (patch)
treeacff691a02a188e314469793f0aa87e6da8ab4c5
parent747fc3754c296ad5481d354bbf35521f886c5c61 (diff)
downloadpygobject-a10df7d28c01d70ee33d8e4e9ddaa23f1990ca60.tar.gz
Add namespace and container name to callable cache and include them in all warnings/error messages.
https://bugzilla.gnome.org/show_bug.cgi?id=743468
-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
-rw-r--r--tests/test_everything.py2
-rw-r--r--tests/test_gi.py28
6 files changed, 90 insertions, 29 deletions
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
index a5729299..ca245173 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 0361f001..098f3f18 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 2a5a120d..65f7e553 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 a65274a0..01516500 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);
diff --git a/tests/test_everything.py b/tests/test_everything.py
index 88b6da14..b8a37f1f 100644
--- a/tests/test_everything.py
+++ b/tests/test_everything.py
@@ -322,7 +322,7 @@ class TestEverything(unittest.TestCase):
Everything.test_int8()
except TypeError:
(e_type, e) = sys.exc_info()[:2]
- self.assertEqual(e.args, ("test_int8() takes exactly 1 argument (0 given)",))
+ self.assertEqual(e.args, ("Regress.test_int8() takes exactly 1 argument (0 given)",))
def test_gtypes(self):
gchararray_gtype = GObject.type_from_name('gchararray')
diff --git a/tests/test_gi.py b/tests/test_gi.py
index 9633f57a..dc40f3c5 100644
--- a/tests/test_gi.py
+++ b/tests/test_gi.py
@@ -2636,29 +2636,29 @@ class TestKeywordArgs(unittest.TestCase):
def test_type_errors(self):
# test too few args
- self.assertRaisesMessage(TypeError, "int_three_in_three_out() takes exactly 3 arguments (0 given)",
+ self.assertRaisesMessage(TypeError, "GIMarshallingTests.int_three_in_three_out() takes exactly 3 arguments (0 given)",
GIMarshallingTests.int_three_in_three_out)
- self.assertRaisesMessage(TypeError, "int_three_in_three_out() takes exactly 3 arguments (1 given)",
+ self.assertRaisesMessage(TypeError, "GIMarshallingTests.int_three_in_three_out() takes exactly 3 arguments (1 given)",
GIMarshallingTests.int_three_in_three_out, 1)
- self.assertRaisesMessage(TypeError, "int_three_in_three_out() takes exactly 3 arguments (0 given)",
+ self.assertRaisesMessage(TypeError, "GIMarshallingTests.int_three_in_three_out() takes exactly 3 arguments (0 given)",
GIMarshallingTests.int_three_in_three_out, *())
- self.assertRaisesMessage(TypeError, "int_three_in_three_out() takes exactly 3 arguments (0 given)",
+ self.assertRaisesMessage(TypeError, "GIMarshallingTests.int_three_in_three_out() takes exactly 3 arguments (0 given)",
GIMarshallingTests.int_three_in_three_out, *(), **{})
- self.assertRaisesMessage(TypeError, "int_three_in_three_out() takes exactly 3 non-keyword arguments (0 given)",
+ self.assertRaisesMessage(TypeError, "GIMarshallingTests.int_three_in_three_out() takes exactly 3 non-keyword arguments (0 given)",
GIMarshallingTests.int_three_in_three_out, *(), **{'c': 4})
# test too many args
- self.assertRaisesMessage(TypeError, "int_three_in_three_out() takes exactly 3 arguments (4 given)",
+ self.assertRaisesMessage(TypeError, "GIMarshallingTests.int_three_in_three_out() takes exactly 3 arguments (4 given)",
GIMarshallingTests.int_three_in_three_out, *(1, 2, 3, 4))
- self.assertRaisesMessage(TypeError, "int_three_in_three_out() takes exactly 3 non-keyword arguments (4 given)",
+ self.assertRaisesMessage(TypeError, "GIMarshallingTests.int_three_in_three_out() takes exactly 3 non-keyword arguments (4 given)",
GIMarshallingTests.int_three_in_three_out, *(1, 2, 3, 4), c=6)
# test too many keyword args
- self.assertRaisesMessage(TypeError, "int_three_in_three_out() got multiple values for keyword argument 'a'",
+ self.assertRaisesMessage(TypeError, "GIMarshallingTests.int_three_in_three_out() got multiple values for keyword argument 'a'",
GIMarshallingTests.int_three_in_three_out, 1, 2, 3, **{'a': 4, 'b': 5})
- self.assertRaisesMessage(TypeError, "int_three_in_three_out() got an unexpected keyword argument 'd'",
+ self.assertRaisesMessage(TypeError, "GIMarshallingTests.int_three_in_three_out() got an unexpected keyword argument 'd'",
GIMarshallingTests.int_three_in_three_out, d=4)
- self.assertRaisesMessage(TypeError, "int_three_in_three_out() got an unexpected keyword argument 'e'",
+ self.assertRaisesMessage(TypeError, "GIMarshallingTests.int_three_in_three_out() got an unexpected keyword argument 'e'",
GIMarshallingTests.int_three_in_three_out, **{'e': 2})
def test_kwargs_are_not_modified(self):
@@ -2780,6 +2780,14 @@ class TestDeprecation(unittest.TestCase):
warnings.simplefilter('always')
d.set_time(1)
self.assertTrue(issubclass(warn[0].category, DeprecationWarning))
+ self.assertEqual(str(warn[0].message), "GLib.Date.set_time is deprecated")
+
+ def test_function(self):
+ with warnings.catch_warnings(record=True) as warn:
+ warnings.simplefilter('always')
+ GLib.strcasecmp("foo", "bar")
+ self.assertTrue(issubclass(warn[0].category, DeprecationWarning))
+ self.assertEqual(str(warn[0].message), "GLib.strcasecmp is deprecated")
def test_deprecated_init_no_keywords(self):
def init(self, **kwargs):