diff options
author | Christoph Reiter <reiter.christoph@gmail.com> | 2015-01-27 19:13:54 +0100 |
---|---|---|
committer | Christoph Reiter <creiter@src.gnome.org> | 2015-03-03 13:01:23 +0100 |
commit | a10df7d28c01d70ee33d8e4e9ddaa23f1990ca60 (patch) | |
tree | acff691a02a188e314469793f0aa87e6da8ab4c5 | |
parent | 747fc3754c296ad5481d354bbf35521f886c5c61 (diff) | |
download | pygobject-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.c | 39 | ||||
-rw-r--r-- | gi/pygi-cache.h | 5 | ||||
-rw-r--r-- | gi/pygi-closure.c | 4 | ||||
-rw-r--r-- | gi/pygi-invoke.c | 41 | ||||
-rw-r--r-- | tests/test_everything.py | 2 | ||||
-rw-r--r-- | tests/test_gi.py | 28 |
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): |