-commit ecb2e6c64cbc420ed8f0d8dc8d1c3f6c516d6f63
+commit 2048dc8d1d708abce7037f96483c6d776567d6b5
+Author: Christoph Reiter <creiter@src.gnome.org>
+Date: Mon Mar 2 20:58:04 2015 +0100
+
+ Add gi.PyGIWarning and use it instead of PyGIDeprecationWarning in
+ case the version to import wasn't specified.
+
+ This makes the warning visible by default.
+ See commit ef3bff4e570363e4f383d4cdae9cecd4073b03d8 for more info
+ on the warning.
+
+ https://bugzilla.gnome.org/show_bug.cgi?id=727379
+
+ gi/__init__.py | 2 ++
+ gi/gimodule.c | 6 ++++++
+ gi/importer.py | 3 ++-
+ tests/test_gi.py | 15 +++++++++++++++
+ 4 files changed, 25 insertions(+), 1 deletion(-)
+
+commit 7a3bb6971f22accd25e987496d377e1879f6e1ba
+Author: Christoph Reiter <creiter@src.gnome.org>
+Date: Sat May 30 17:46:54 2015 +0200
+
+ Remove Gdk.Rectangle alias with newer gobject-introspection and GTK+
+
+ The new GdkRectangle in the typelib confuses the marshalling code
+ as PyGObject uses the Python class from the overrides for marshalling
+ to Python but uses the gtype from the typelib to do
+ type checking when marshalling from Python.
+
+ https://bugzilla.gnome.org/show_bug.cgi?id=749625
+
+ gi/overrides/Gdk.py | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+commit 64be2069d39b4d2767eb1efd47bb3f268ad7fb0d
Author: Christoph Reiter <creiter@src.gnome.org>
Date: Thu Apr 23 22:03:54 2015 +0200
gi/overrides/__init__.py | 7 +++++++
1 file changed, 7 insertions(+)
-commit eddc46202fc813f03137fcaba80090d19cc8f200
-Author: Simon Feltman <sfeltman@src.gnome.org>
-Date: Mon Apr 13 19:48:24 2015 -0700
-
- configure.ac: post release version bump to 3.16.2
-
- configure.ac | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-commit 763510d091bcb9833a3de7f9646d9a06282135da
-Author: Simon Feltman <sfeltman@src.gnome.org>
-Date: Mon Apr 13 19:46:48 2015 -0700
-
- release 3.16.1
-
- NEWS | 4 ++++
- 1 file changed, 4 insertions(+)
-
-commit 7291cb1f841c384f1a18cc744c8d9c6be20c48e2
+commit 6772e990ad889af817b9224e88ea9d79a04caef7
Author: Simon Feltman <sfeltman@src.gnome.org>
Date: Mon Apr 13 19:33:40 2015 -0700
gi/overrides/Gdk.py | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
-commit c5952495351b551b5295afc36643e3d10004225e
+commit 26c015b177ddcc0f35c97bcd7a4f2114fb2e8e2a
+Author: Christoph Reiter <reiter.christoph@gmail.com>
+Date: Sun Mar 29 23:23:09 2015 +0200
+
+ Field setters: Remove unneeded type/range checks and resulting
+ unused code.
+
+ These checks are performed in the actual marshalling code
+ paths as well, no need to do them twice.
+
+ Also move _pygi_g_registered_type_info_check_object() to pygi-info.c
+ as it's the only place where it is still used.
+
+ https://bugzilla.gnome.org/show_bug.cgi?id=746985
+
+ gi/pygi-argument.c | 626
+ ---------------------------------------------------
+ gi/pygi-argument.h | 12 -
+ gi/pygi-info.c | 90 ++++++--
+ tests/test_fields.py | 14 +-
+ 4 files changed, 83 insertions(+), 659 deletions(-)
+
+commit dbb0b199268ece884e19eb99093fc26bd7bf92af
+Author: Christoph Reiter <reiter.christoph@gmail.com>
+Date: Sun Mar 29 21:51:42 2015 +0200
+
+ pygi-argument: Remove unused imports/includes
+
+ https://bugzilla.gnome.org/show_bug.cgi?id=746985
+
+ gi/gimodule.c | 1 -
+ gi/pygi-argument.c | 7 -------
+ gi/pygi-argument.h | 2 --
+ 3 files changed, 10 deletions(-)
+
+commit 7dee04efff418677eead36ee9ed497cc3eadf8f7
+Author: Christoph Reiter <reiter.christoph@gmail.com>
+Date: Sun Mar 29 21:47:47 2015 +0200
+
+ Improve test coverage for field setters/getters.
+
+ Field setters are the sole users of the GIArgument value validation
+ code and the error handling is hardly tested. This tries to improve
+ the coverage for the field types available in
+ GLib/Regress/GIMarshallingTests.
+
+ https://bugzilla.gnome.org/show_bug.cgi?id=746985
+
+ tests/Makefile.am | 1 +
+ tests/test_fields.py | 186
+ +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 187 insertions(+)
+
+commit b0170220fabbf878a36e0c14b0a3024973b7355f
Author: Simon Feltman <sfeltman@src.gnome.org>
-Date: Sun Mar 29 16:29:35 2015 -0700
+Date: Sun Mar 29 16:35:47 2015 -0700
- configure.ac: post release version bump to 3.16.1
+ configure.ac: post release version bump to 3.17.1
- configure.ac | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
+ configure.ac | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
commit 46f463a3a3ff45eb8eba67fbb59ecc861b1e1d73
Author: Simon Feltman <sfeltman@src.gnome.org>
-3.16.2 15-Jun-2015
+3.17.1 15-Jun-2015
+ - Add gi.PyGIWarning used when import version is not specified
+ (Christoph Reiter) (#727379)
+ - Remove Gdk.Rectangle alias with newer gobject-introspection and GTK+
+ (Christoph Reiter) (#749625)
- overrides: Provide _overrides_module attribute
(Christoph Reiter) (#736678)
-
-3.16.1 13-Apr-2015
- overrides: Conditionalize touch override support in Gdk
(Simon Feltman) (#747717)
+ - Field setters: Remove unneeded type/range checks and unused code
+ (Christoph Reiter) (#746985)
+ - pygi-argument: Remove unused imports/includes
+ (Christoph Reiter) (#746985)
+ - Improve test coverage for field setters/getters
+ (Christoph Reiter) (#746985)
3.16.0 24-Mar-2015
Metadata-Version: 1.0
Name: PyGObject
-Version: 3.16.2
+Version: 3.17.1
Summary: Python bindings for GObject
Home-page: http://www.pygtk.org/
Author: James Henstridge
Maintainer: Simon Feltman
Maintainer-email: sfeltman@src.gnome.org
License: GNU LGPL
-Download-url: ftp://ftp.gnome.org/pub/GNOME/sources/pygobject/3.16/pygobject-3.16.2.tar.gz
+Download-url: ftp://ftp.gnome.org/pub/GNOME/sources/pygobject/3.17/pygobject-3.17.1.tar.gz
Description: Python bindings for GLib and GObject
Platform: POSIX, Windows
Classifier: Development Status :: 5 - Production/Stable
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for pygobject 3.16.2.
+# Generated by GNU Autoconf 2.69 for pygobject 3.17.1.
#
# Report bugs to <http://bugzilla.gnome.org/enter_bug.cgi?product=pygobject>.
#
# Identity of this package.
PACKAGE_NAME='pygobject'
PACKAGE_TARNAME='pygobject'
-PACKAGE_VERSION='3.16.2'
-PACKAGE_STRING='pygobject 3.16.2'
+PACKAGE_VERSION='3.17.1'
+PACKAGE_STRING='pygobject 3.17.1'
PACKAGE_BUGREPORT='http://bugzilla.gnome.org/enter_bug.cgi?product=pygobject'
PACKAGE_URL='https://wiki.gnome.org/Projects/PyGObject/'
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures pygobject 3.16.2 to adapt to many kinds of systems.
+\`configure' configures pygobject 3.17.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of pygobject 3.16.2:";;
+ short | recursive ) echo "Configuration of pygobject 3.17.1:";;
esac
cat <<\_ACEOF
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-pygobject configure 3.16.2
+pygobject configure 3.17.1
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by pygobject $as_me 3.16.2, which was
+It was created by pygobject $as_me 3.17.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
PYGOBJECT_MAJOR_VERSION=3
-$as_echo "#define PYGOBJECT_MINOR_VERSION 16" >>confdefs.h
+$as_echo "#define PYGOBJECT_MINOR_VERSION 17" >>confdefs.h
-PYGOBJECT_MINOR_VERSION=16
+PYGOBJECT_MINOR_VERSION=17
-$as_echo "#define PYGOBJECT_MICRO_VERSION 2" >>confdefs.h
+$as_echo "#define PYGOBJECT_MICRO_VERSION 1" >>confdefs.h
-PYGOBJECT_MICRO_VERSION=2
+PYGOBJECT_MICRO_VERSION=1
ac_config_headers="$ac_config_headers config.h"
# Define the identity of the package.
PACKAGE='pygobject'
- VERSION='3.16.2'
+ VERSION='3.17.1'
cat >>confdefs.h <<_ACEOF
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by pygobject $as_me 3.16.2, which was
+This file was extended by pygobject $as_me 3.17.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-pygobject config.status 3.16.2
+pygobject config.status 3.17.1
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
dnl the pygobject version number
m4_define(pygobject_major_version, 3)
-m4_define(pygobject_minor_version, 16)
-m4_define(pygobject_micro_version, 2)
+m4_define(pygobject_minor_version, 17)
+m4_define(pygobject_micro_version, 1)
m4_define(pygobject_version, pygobject_major_version.pygobject_minor_version.pygobject_micro_version)
dnl versions of packages we require ...
from ._gi import _API
from ._gi import Repository
from ._gi import PyGIDeprecationWarning
+from ._gi import PyGIWarning
_API = _API # pyflakes
PyGIDeprecationWarning = PyGIDeprecationWarning
+PyGIWarning = PyGIWarning
_versions = {}
_overridesdir = os.path.join(os.path.dirname(__file__), 'overrides')
#include <pyglib-python-compat.h>
+PyObject *PyGIWarning;
PyObject *PyGIDeprecationWarning;
PyObject *_PyGIDefaultArgPlaceholder;
_pygi_struct_register_types (module);
_pygi_boxed_register_types (module);
_pygi_ccallback_register_types (module);
- _pygi_argument_init ();
+
+ PyGIWarning = PyErr_NewException ("gi.PyGIWarning", PyExc_Warning, NULL);
/* Use RuntimeWarning as the base class of PyGIDeprecationWarning
* for unstable (odd minor version) and use DeprecationWarning for
*/
_PyGIDefaultArgPlaceholder = PyObject_New(PyObject, &PyType_Type);
+ Py_INCREF (PyGIWarning);
+ PyModule_AddObject (module, "PyGIWarning", PyGIWarning);
+
Py_INCREF(PyGIDeprecationWarning);
PyModule_AddObject(module, "PyGIDeprecationWarning", PyGIDeprecationWarning);
import gi
from ._gi import Repository
+from ._gi import PyGIWarning
from .module import get_introspection_module
from .overrides import load_overrides
"Use gi.require_version('%(namespace)s', '%(version)s') before "
"import to ensure that the right version gets loaded."
% {"namespace": namespace, "version": version},
- ImportWarning, stacklevel=stacklevel)
+ PyGIWarning, stacklevel=stacklevel)
class DynamicImporter(object):
Rectangle = override(Rectangle)
__all__.append('Rectangle')
else:
- from gi.repository import cairo as _cairo
- Rectangle = _cairo.RectangleInt
-
- __all__.append('Rectangle')
+ # Newer GTK+/gobject-introspection (3.17.x) include GdkRectangle in the
+ # typelib. See https://bugzilla.gnome.org/show_bug.cgi?id=748832 and
+ # https://bugzilla.gnome.org/show_bug.cgi?id=748833
+ if not hasattr(Gdk, 'Rectangle'):
+ from gi.repository import cairo as _cairo
+ Rectangle = _cairo.RectangleInt
+
+ __all__.append('Rectangle')
if Gdk._version == '2.0':
class Drawable(Gdk.Drawable):
#include <string.h>
#include <time.h>
-#include <datetime.h>
#include <pyglib-python-compat.h>
#include <pyglib.h>
}
}
-static void
-_pygi_g_type_tag_py_bounds (GITypeTag type_tag,
- PyObject **lower,
- PyObject **upper)
-{
- switch (type_tag) {
- case GI_TYPE_TAG_INT8:
- *lower = PYGLIB_PyLong_FromLong (-128);
- *upper = PYGLIB_PyLong_FromLong (127);
- break;
- case GI_TYPE_TAG_UINT8:
- *upper = PYGLIB_PyLong_FromLong (255);
- *lower = PYGLIB_PyLong_FromLong (0);
- break;
- case GI_TYPE_TAG_INT16:
- *lower = PYGLIB_PyLong_FromLong (-32768);
- *upper = PYGLIB_PyLong_FromLong (32767);
- break;
- case GI_TYPE_TAG_UINT16:
- *upper = PYGLIB_PyLong_FromLong (65535);
- *lower = PYGLIB_PyLong_FromLong (0);
- break;
- case GI_TYPE_TAG_INT32:
- *lower = PYGLIB_PyLong_FromLong (G_MININT32);
- *upper = PYGLIB_PyLong_FromLong (G_MAXINT32);
- break;
- case GI_TYPE_TAG_UINT32:
- /* Note: On 32-bit archs, this number doesn't fit in a long. */
- *upper = PyLong_FromLongLong (G_MAXUINT32);
- *lower = PYGLIB_PyLong_FromLong (0);
- break;
- case GI_TYPE_TAG_INT64:
- /* Note: On 32-bit archs, these numbers don't fit in a long. */
- *lower = PyLong_FromLongLong (G_MININT64);
- *upper = PyLong_FromLongLong (G_MAXINT64);
- break;
- case GI_TYPE_TAG_UINT64:
- *upper = PyLong_FromUnsignedLongLong (G_MAXUINT64);
- *lower = PYGLIB_PyLong_FromLong (0);
- break;
- case GI_TYPE_TAG_FLOAT:
- *upper = PyFloat_FromDouble (G_MAXFLOAT);
- *lower = PyFloat_FromDouble (-G_MAXFLOAT);
- break;
- case GI_TYPE_TAG_DOUBLE:
- *upper = PyFloat_FromDouble (G_MAXDOUBLE);
- *lower = PyFloat_FromDouble (-G_MAXDOUBLE);
- break;
- default:
- PyErr_SetString (PyExc_TypeError, "Non-numeric type tag");
- *lower = *upper = NULL;
- return;
- }
-}
-
-gint
-_pygi_g_registered_type_info_check_object (GIRegisteredTypeInfo *info,
- gboolean is_instance,
- PyObject *object)
-{
- gint retval;
-
- GType g_type;
- PyObject *py_type;
- gchar *type_name_expected = NULL;
- GIInfoType interface_type;
-
- interface_type = g_base_info_get_type (info);
- if ( (interface_type == GI_INFO_TYPE_STRUCT) &&
- (g_struct_info_is_foreign ( (GIStructInfo*) info))) {
- /* TODO: Could we check is the correct foreign type? */
- return 1;
- }
-
- g_type = g_registered_type_info_get_g_type (info);
- if (g_type != G_TYPE_NONE) {
- py_type = _pygi_type_get_from_g_type (g_type);
- } else {
- py_type = _pygi_type_import_by_gi_info ( (GIBaseInfo *) info);
- }
-
- if (py_type == NULL) {
- return 0;
- }
-
- g_assert (PyType_Check (py_type));
-
- if (is_instance) {
- retval = PyObject_IsInstance (object, py_type);
- if (!retval) {
- type_name_expected = _pygi_g_base_info_get_fullname (
- (GIBaseInfo *) info);
- }
- } else {
- if (!PyObject_Type (py_type)) {
- type_name_expected = "type";
- retval = 0;
- } else if (!PyType_IsSubtype ( (PyTypeObject *) object,
- (PyTypeObject *) py_type)) {
- type_name_expected = _pygi_g_base_info_get_fullname (
- (GIBaseInfo *) info);
- retval = 0;
- } else {
- retval = 1;
- }
- }
-
- Py_DECREF (py_type);
-
- if (!retval) {
- PyTypeObject *object_type;
-
- if (type_name_expected == NULL) {
- return -1;
- }
-
- object_type = (PyTypeObject *) PyObject_Type (object);
- if (object_type == NULL) {
- return -1;
- }
-
- PyErr_Format (PyExc_TypeError, "Must be %s, not %s",
- type_name_expected, object_type->tp_name);
-
- g_free (type_name_expected);
- }
-
- return retval;
-}
-
-gint
-_pygi_g_type_interface_check_object (GIBaseInfo *info,
- PyObject *object)
-{
- gint retval = 1;
- GIInfoType info_type;
-
- info_type = g_base_info_get_type (info);
- switch (info_type) {
- case GI_INFO_TYPE_CALLBACK:
- if (!PyCallable_Check (object)) {
- PyErr_Format (PyExc_TypeError, "Must be callable, not %s",
- object->ob_type->tp_name);
- retval = 0;
- }
- break;
- case GI_INFO_TYPE_ENUM:
- retval = 0;
- if (PyNumber_Check (object)) {
- PyObject *number = PYGLIB_PyNumber_Long (object);
- if (number == NULL)
- PyErr_Clear();
- else {
- glong value = PYGLIB_PyLong_AsLong (number);
- int i;
- for (i = 0; i < g_enum_info_get_n_values (info); i++) {
- GIValueInfo *value_info = g_enum_info_get_value (info, i);
- glong enum_value = g_value_info_get_value (value_info);
- g_base_info_unref (value_info);
- if (value == enum_value) {
- retval = 1;
- break;
- }
- }
- }
- }
- if (retval < 1)
- retval = _pygi_g_registered_type_info_check_object (
- (GIRegisteredTypeInfo *) info, TRUE, object);
- break;
- case GI_INFO_TYPE_FLAGS:
- if (PyNumber_Check (object)) {
- /* Accept 0 as a valid flag value */
- PyObject *number = PYGLIB_PyNumber_Long (object);
- if (number == NULL)
- PyErr_Clear();
- else {
- long value = PYGLIB_PyLong_AsLong (number);
- if (value == 0)
- break;
- else if (value == -1)
- PyErr_Clear();
- }
- }
- retval = _pygi_g_registered_type_info_check_object (
- (GIRegisteredTypeInfo *) info, TRUE, object);
- break;
- case GI_INFO_TYPE_STRUCT:
- {
- GType type;
-
- /* Handle special cases. */
- type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *) info);
- if (g_type_is_a (type, G_TYPE_CLOSURE)) {
- if (!(PyCallable_Check (object) ||
- pyg_type_from_object_strict (object, FALSE) == G_TYPE_CLOSURE)) {
- PyErr_Format (PyExc_TypeError, "Must be callable, not %s",
- object->ob_type->tp_name);
- retval = 0;
- }
- break;
- } else if (g_type_is_a (type, G_TYPE_VALUE)) {
- /* we can't check g_values because we don't have
- * enough context so just pass them through */
- break;
- }
-
- /* Fallback. */
- }
- case GI_INFO_TYPE_BOXED:
- case GI_INFO_TYPE_INTERFACE:
- case GI_INFO_TYPE_OBJECT:
- retval = _pygi_g_registered_type_info_check_object ( (GIRegisteredTypeInfo *) info, TRUE, object);
- break;
- case GI_INFO_TYPE_UNION:
-
-
- retval = _pygi_g_registered_type_info_check_object ( (GIRegisteredTypeInfo *) info, TRUE, object);
-
- /* If not the same type then check to see if the object's type
- * is the same as one of the union's members
- */
- if (retval == 0) {
- gint i;
- gint n_fields;
-
- n_fields = g_union_info_get_n_fields ( (GIUnionInfo *) info);
-
- for (i = 0; i < n_fields; i++) {
- gint member_retval;
- GIFieldInfo *field_info;
- GITypeInfo *field_type_info;
-
- field_info =
- g_union_info_get_field ( (GIUnionInfo *) info, i);
- field_type_info = g_field_info_get_type (field_info);
-
- member_retval = _pygi_g_type_info_check_object(
- field_type_info,
- object,
- TRUE);
-
- g_base_info_unref ( ( GIBaseInfo *) field_type_info);
- g_base_info_unref ( ( GIBaseInfo *) field_info);
-
- if (member_retval == 1) {
- retval = member_retval;
- break;
- }
- }
- }
-
- break;
- default:
- g_assert_not_reached();
- }
-
- return retval;
-}
-
-gint
-_pygi_g_type_info_check_object (GITypeInfo *type_info,
- PyObject *object,
- gboolean allow_none)
-{
- GITypeTag type_tag;
- gint retval = 1;
-
- if (allow_none && object == Py_None) {
- return retval;
- }
-
- type_tag = g_type_info_get_tag (type_info);
-
- switch (type_tag) {
- case GI_TYPE_TAG_VOID:
- /* No check; VOID means undefined type */
- break;
- case GI_TYPE_TAG_BOOLEAN:
- /* No check; every Python object has a truth value. */
- break;
- case GI_TYPE_TAG_UINT8:
- case GI_TYPE_TAG_INT8:
- /* (U)INT8 types can be characters */
- if (PYGLIB_PyBytes_Check(object)) {
- if (PYGLIB_PyBytes_Size(object) != 1) {
- PyErr_Format (PyExc_TypeError, "Must be a single character");
- retval = 0;
- break;
- }
-
- break;
- }
- case GI_TYPE_TAG_INT16:
- case GI_TYPE_TAG_UINT16:
- case GI_TYPE_TAG_INT32:
- case GI_TYPE_TAG_UINT32:
- case GI_TYPE_TAG_INT64:
- case GI_TYPE_TAG_UINT64:
- case GI_TYPE_TAG_FLOAT:
- case GI_TYPE_TAG_DOUBLE:
- {
- PyObject *number, *lower, *upper;
-
- if (!PyNumber_Check (object)) {
- PyErr_Format (PyExc_TypeError, "Must be number, not %s",
- object->ob_type->tp_name);
- retval = 0;
- break;
- }
-
- if (type_tag == GI_TYPE_TAG_FLOAT || type_tag == GI_TYPE_TAG_DOUBLE) {
- number = PyNumber_Float (object);
- } else {
- number = PYGLIB_PyNumber_Long (object);
- }
-
- _pygi_g_type_tag_py_bounds (type_tag, &lower, &upper);
-
- if (lower == NULL || upper == NULL || number == NULL) {
- retval = -1;
- goto check_number_release;
- }
-
- /* Check bounds */
- if (PyObject_RichCompareBool (lower, number, Py_GT)
- || PyObject_RichCompareBool (upper, number, Py_LT)) {
- PyObject *lower_str;
- PyObject *upper_str;
-
- if (PyErr_Occurred()) {
- retval = -1;
- goto check_number_release;
- }
-
- lower_str = PyObject_Str (lower);
- upper_str = PyObject_Str (upper);
- if (lower_str == NULL || upper_str == NULL) {
- retval = -1;
- goto check_number_error_release;
- }
-
-#if PY_VERSION_HEX < 0x03000000
- PyErr_Format (PyExc_ValueError, "Must range from %s to %s",
- PyString_AS_STRING (lower_str),
- PyString_AS_STRING (upper_str));
-#else
- {
- PyObject *lower_pybytes_obj;
- PyObject *upper_pybytes_obj;
-
- lower_pybytes_obj = PyUnicode_AsUTF8String (lower_str);
- if (!lower_pybytes_obj) {
- goto utf8_fail;
- }
-
- upper_pybytes_obj = PyUnicode_AsUTF8String (upper_str);
- if (!upper_pybytes_obj) {
- Py_DECREF(lower_pybytes_obj);
- goto utf8_fail;
- }
-
- PyErr_Format (PyExc_ValueError, "Must range from %s to %s",
- PyBytes_AsString (lower_pybytes_obj),
- PyBytes_AsString (upper_pybytes_obj));
- Py_DECREF (lower_pybytes_obj);
- Py_DECREF (upper_pybytes_obj);
- }
-utf8_fail:
-#endif
- retval = 0;
-
-check_number_error_release:
- Py_XDECREF (lower_str);
- Py_XDECREF (upper_str);
- }
-
-check_number_release:
- Py_XDECREF (number);
- Py_XDECREF (lower);
- Py_XDECREF (upper);
- break;
- }
- case GI_TYPE_TAG_GTYPE:
- {
- if (pyg_type_from_object (object) == 0) {
- PyErr_Format (PyExc_TypeError, "Must be gobject.GType, not %s",
- object->ob_type->tp_name);
- retval = 0;
- }
- break;
- }
- case GI_TYPE_TAG_UNICHAR:
- {
- Py_ssize_t size;
- if (PyUnicode_Check (object)) {
- size = PyUnicode_GET_SIZE (object);
-#if PY_VERSION_HEX < 0x03000000
- } else if (PyString_Check (object)) {
- PyObject *pyuni = PyUnicode_FromEncodedObject (object, "UTF-8", "strict");
- size = PyUnicode_GET_SIZE (pyuni);
- Py_DECREF(pyuni);
-#endif
- } else {
- PyErr_Format (PyExc_TypeError, "Must be string, not %s",
- object->ob_type->tp_name);
- retval = 0;
- break;
- }
-
- if (size != 1) {
- PyErr_Format (PyExc_TypeError, "Must be a one character string, not %" G_GINT64_FORMAT " characters",
- (gint64)size);
- retval = 0;
- break;
- }
-
- break;
- }
- case GI_TYPE_TAG_UTF8:
- case GI_TYPE_TAG_FILENAME:
- if (!PYGLIB_PyBaseString_Check (object) ) {
- PyErr_Format (PyExc_TypeError, "Must be string, not %s",
- object->ob_type->tp_name);
- retval = 0;
- }
- break;
- case GI_TYPE_TAG_ARRAY:
- {
- gssize fixed_size;
- Py_ssize_t length;
- GITypeInfo *item_type_info;
- Py_ssize_t i;
-
- if (!PySequence_Check (object)) {
- PyErr_Format (PyExc_TypeError, "Must be sequence, not %s",
- object->ob_type->tp_name);
- retval = 0;
- break;
- }
-
- length = PySequence_Length (object);
- if (length < 0) {
- retval = -1;
- break;
- }
-
- fixed_size = g_type_info_get_array_fixed_size (type_info);
- if (fixed_size >= 0 && length != fixed_size) {
- PyErr_Format (PyExc_ValueError, "Must contain %zd items, not %zd",
- fixed_size, length);
- retval = 0;
- break;
- }
-
- item_type_info = g_type_info_get_param_type (type_info, 0);
- g_assert (item_type_info != NULL);
-
- /* FIXME: This is insain. We really should only check the first
- * object and perhaps have a debugging mode. Large arrays
- * will cause apps to slow to a crawl.
- */
- for (i = 0; i < length; i++) {
- PyObject *item;
-
- item = PySequence_GetItem (object, i);
- if (item == NULL) {
- retval = -1;
- break;
- }
-
- retval = _pygi_g_type_info_check_object (item_type_info, item, TRUE);
-
- Py_DECREF (item);
-
- if (retval < 0) {
- break;
- }
- if (!retval) {
- _PyGI_ERROR_PREFIX ("Item %zd: ", i);
- break;
- }
- }
-
- g_base_info_unref ( (GIBaseInfo *) item_type_info);
-
- break;
- }
- case GI_TYPE_TAG_INTERFACE:
- {
- GIBaseInfo *info;
-
- info = g_type_info_get_interface (type_info);
- g_assert (info != NULL);
-
- retval = _pygi_g_type_interface_check_object(info, object);
-
- g_base_info_unref (info);
- break;
- }
- case GI_TYPE_TAG_GLIST:
- case GI_TYPE_TAG_GSLIST:
- {
- Py_ssize_t length;
- GITypeInfo *item_type_info;
- Py_ssize_t i;
-
- if (!PySequence_Check (object)) {
- PyErr_Format (PyExc_TypeError, "Must be sequence, not %s",
- object->ob_type->tp_name);
- retval = 0;
- break;
- }
-
- length = PySequence_Length (object);
- if (length < 0) {
- retval = -1;
- break;
- }
-
- item_type_info = g_type_info_get_param_type (type_info, 0);
- g_assert (item_type_info != NULL);
-
- for (i = 0; i < length; i++) {
- PyObject *item;
-
- item = PySequence_GetItem (object, i);
- if (item == NULL) {
- retval = -1;
- break;
- }
-
- retval = _pygi_g_type_info_check_object (item_type_info, item, TRUE);
-
- Py_DECREF (item);
-
- if (retval < 0) {
- break;
- }
- if (!retval) {
- _PyGI_ERROR_PREFIX ("Item %zd: ", i);
- break;
- }
- }
-
- g_base_info_unref ( (GIBaseInfo *) item_type_info);
- break;
- }
- case GI_TYPE_TAG_GHASH:
- {
- Py_ssize_t length;
- PyObject *keys;
- PyObject *values;
- GITypeInfo *key_type_info;
- GITypeInfo *value_type_info;
- Py_ssize_t i;
-
- keys = PyMapping_Keys (object);
- if (keys == NULL) {
- PyErr_Format (PyExc_TypeError, "Must be mapping, not %s",
- object->ob_type->tp_name);
- retval = 0;
- break;
- }
-
- length = PyMapping_Length (object);
- if (length < 0) {
- Py_DECREF (keys);
- retval = -1;
- break;
- }
-
- values = PyMapping_Values (object);
- if (values == NULL) {
- retval = -1;
- Py_DECREF (keys);
- break;
- }
-
- key_type_info = g_type_info_get_param_type (type_info, 0);
- g_assert (key_type_info != NULL);
-
- value_type_info = g_type_info_get_param_type (type_info, 1);
- g_assert (value_type_info != NULL);
-
- for (i = 0; i < length; i++) {
- PyObject *key;
- PyObject *value;
-
- key = PyList_GET_ITEM (keys, i);
- value = PyList_GET_ITEM (values, i);
-
- retval = _pygi_g_type_info_check_object (key_type_info, key, TRUE);
- if (retval < 0) {
- break;
- }
- if (!retval) {
- _PyGI_ERROR_PREFIX ("Key %zd :", i);
- break;
- }
-
- retval = _pygi_g_type_info_check_object (value_type_info, value, TRUE);
- if (retval < 0) {
- break;
- }
- if (!retval) {
- _PyGI_ERROR_PREFIX ("Value %zd :", i);
- break;
- }
- }
-
- g_base_info_unref ( (GIBaseInfo *) key_type_info);
- g_base_info_unref ( (GIBaseInfo *) value_type_info);
- Py_DECREF (values);
- Py_DECREF (keys);
- break;
- }
- case GI_TYPE_TAG_ERROR:
- PyErr_SetString (PyExc_NotImplementedError, "Error marshalling is not supported yet");
- /* TODO */
- break;
- }
-
- return retval;
-}
-
/**
* _pygi_argument_array_length_marshal:
}
}
-void
-_pygi_argument_init (void)
-{
- PyDateTime_IMPORT;
-}
-
void _pygi_hash_pointer_to_arg (GIArgument *arg,
GITypeTag type_tag);
-gint _pygi_g_type_interface_check_object (GIBaseInfo *info,
- PyObject *object);
-
-gint _pygi_g_type_info_check_object (GITypeInfo *type_info,
- PyObject *object,
- gboolean allow_none);
-
-gint _pygi_g_registered_type_info_check_object (GIRegisteredTypeInfo *info,
- gboolean is_instance,
- PyObject *object);
-
-
GArray* _pygi_argument_to_array (GIArgument *arg,
PyGIArgArrayLengthPolicy array_length_policy,
void *user_data1,
GITransfer transfer,
GIDirection direction);
-void _pygi_argument_init (void);
-
gboolean pygi_argument_to_gssize (GIArgument *arg_in,
GITypeTag type_tag,
gssize *gssize_out);
return array_len;
}
+static gint
+_pygi_g_registered_type_info_check_object (GIRegisteredTypeInfo *info,
+ gboolean is_instance,
+ PyObject *object)
+{
+ gint retval;
+
+ GType g_type;
+ PyObject *py_type;
+ gchar *type_name_expected = NULL;
+ GIInfoType interface_type;
+
+ interface_type = g_base_info_get_type (info);
+ if ( (interface_type == GI_INFO_TYPE_STRUCT) &&
+ (g_struct_info_is_foreign ( (GIStructInfo*) info))) {
+ /* TODO: Could we check is the correct foreign type? */
+ return 1;
+ }
+
+ g_type = g_registered_type_info_get_g_type (info);
+ if (g_type != G_TYPE_NONE) {
+ py_type = _pygi_type_get_from_g_type (g_type);
+ } else {
+ py_type = _pygi_type_import_by_gi_info ( (GIBaseInfo *) info);
+ }
+
+ if (py_type == NULL) {
+ return 0;
+ }
+
+ g_assert (PyType_Check (py_type));
+
+ if (is_instance) {
+ retval = PyObject_IsInstance (object, py_type);
+ if (!retval) {
+ type_name_expected = _pygi_g_base_info_get_fullname (
+ (GIBaseInfo *) info);
+ }
+ } else {
+ if (!PyObject_Type (py_type)) {
+ type_name_expected = "type";
+ retval = 0;
+ } else if (!PyType_IsSubtype ( (PyTypeObject *) object,
+ (PyTypeObject *) py_type)) {
+ type_name_expected = _pygi_g_base_info_get_fullname (
+ (GIBaseInfo *) info);
+ retval = 0;
+ } else {
+ retval = 1;
+ }
+ }
+
+ Py_DECREF (py_type);
+
+ if (!retval) {
+ PyTypeObject *object_type;
+
+ if (type_name_expected == NULL) {
+ return -1;
+ }
+
+ object_type = (PyTypeObject *) PyObject_Type (object);
+ if (object_type == NULL) {
+ return -1;
+ }
+
+ PyErr_Format (PyExc_TypeError, "Must be %s, not %s",
+ type_name_expected, object_type->tp_name);
+
+ g_free (type_name_expected);
+ }
+
+ return retval;
+}
+
static PyObject *
_wrap_g_field_info_get_value (PyGIBaseInfo *self,
PyObject *args)
field_type_info = g_field_info_get_type ( (GIFieldInfo *) self->info);
- /* Check the value. */
- {
- gboolean retval;
-
- retval = _pygi_g_type_info_check_object (field_type_info, py_value, TRUE);
- if (retval < 0) {
- goto out;
- }
-
- if (!retval) {
- _PyGI_ERROR_PREFIX ("argument 2: ");
- goto out;
- }
- }
-
/* Set the field's value. */
/* A few types are not handled by g_field_info_set_field, so do it here. */
if (!g_type_info_is_pointer (field_type_info)
org.gnome.test.gschema.xml \
test_cairo.py \
test_error.py \
+ test_fields.py \
test_gio.py \
test_glib.py \
test_gobject.py \
org.gnome.test.gschema.xml \
test_cairo.py \
test_error.py \
+ test_fields.py \
test_gio.py \
test_glib.py \
test_gobject.py \
--- /dev/null
+# -*- Mode: Python; py-indent-offset: 4 -*-
+# coding=utf-8
+
+import math
+import unittest
+
+from gi.repository import GLib
+from gi.repository import Regress
+from gi.repository import GIMarshallingTests
+
+from compathelper import _unicode
+
+
+class Number(object):
+
+ def __init__(self, value):
+ self.value = value
+
+ def __int__(self):
+ return int(self.value)
+
+ def __float__(self):
+ return float(self.value)
+
+
+class TestFields(unittest.TestCase):
+
+ def test_int8(self):
+ s = Regress.TestStructA()
+ s.some_int8 = 21
+ self.assertEqual(s.some_int8, 21)
+
+ s.some_int8 = b"\x42"
+ self.assertEqual(s.some_int8, 0x42)
+
+ self.assertRaises(TypeError, setattr, s, "some_int8", b"ab")
+ self.assertRaises(TypeError, setattr, s, "some_int8", None)
+ self.assertRaises(OverflowError, setattr, s, "some_int8", 128)
+ self.assertRaises(OverflowError, setattr, s, "some_int8", -129)
+
+ s.some_int8 = 3.6
+ self.assertEqual(s.some_int8, 3)
+
+ s.some_int8 = Number(55)
+ self.assertEqual(s.some_int8, 55)
+
+ def test_int(self):
+ s = Regress.TestStructA()
+ s.some_int = GLib.MAXINT
+ self.assertEqual(s.some_int, GLib.MAXINT)
+
+ self.assertRaises(TypeError, setattr, s, "some_int", b"a")
+ self.assertRaises(TypeError, setattr, s, "some_int", None)
+ self.assertRaises(
+ OverflowError, setattr, s, "some_int", GLib.MAXINT + 1)
+ self.assertRaises(
+ OverflowError, setattr, s, "some_int", GLib.MININT - 1)
+
+ s.some_int = 3.6
+ self.assertEqual(s.some_int, 3)
+
+ s.some_int = Number(GLib.MININT)
+ self.assertEqual(s.some_int, GLib.MININT)
+
+ def test_long(self):
+ s = GIMarshallingTests.SimpleStruct()
+ s.long_ = GLib.MAXLONG
+ self.assertEqual(s.long_, GLib.MAXLONG)
+
+ self.assertRaises(TypeError, setattr, s, "long_", b"a")
+ self.assertRaises(TypeError, setattr, s, "long_", None)
+ self.assertRaises(OverflowError, setattr, s, "long_", GLib.MAXLONG + 1)
+ self.assertRaises(OverflowError, setattr, s, "long_", GLib.MINLONG - 1)
+
+ s.long_ = 3.6
+ self.assertEqual(s.long_, 3)
+
+ s.long_ = Number(GLib.MINLONG)
+ self.assertEqual(s.long_, GLib.MINLONG)
+
+ def test_double(self):
+ s = Regress.TestStructA()
+ s.some_double = GLib.MAXDOUBLE
+ self.assertEqual(s.some_double, GLib.MAXDOUBLE)
+ s.some_double = GLib.MINDOUBLE
+ self.assertEqual(s.some_double, GLib.MINDOUBLE)
+
+ s.some_double = float("nan")
+ self.assertTrue(math.isnan(s.some_double))
+
+ self.assertRaises(TypeError, setattr, s, "some_double", b"a")
+ self.assertRaises(TypeError, setattr, s, "some_double", None)
+
+ def test_gtype(self):
+ s = Regress.TestStructE()
+
+ s.some_type = Regress.TestObj
+ self.assertEqual(s.some_type, Regress.TestObj.__gtype__)
+
+ self.assertRaises(TypeError, setattr, s, "some_type", 42)
+
+ def test_unichar(self):
+ # I can't find a unichar field..
+ pass
+
+ def test_utf8(self):
+ s = GIMarshallingTests.BoxedStruct()
+ s.string_ = "hello"
+ self.assertEqual(s.string_, "hello")
+
+ s.string_ = _unicode("hello")
+ self.assertEqual(s.string_, _unicode("hello"))
+
+ s.string_ = None
+ self.assertEqual(s.string_, None)
+
+ self.assertRaises(TypeError, setattr, s, "string_", 42)
+
+ def test_array_of_structs(self):
+ s = Regress.TestStructD()
+ self.assertEqual(s.array1, [])
+ self.assertEqual(s.array2, [])
+
+ def test_interface(self):
+ s = Regress.TestStructC()
+
+ obj = Regress.TestObj()
+ s.obj = obj
+ self.assertTrue(s.obj is obj)
+
+ s.obj = None
+ self.assertTrue(s.obj is None)
+
+ self.assertRaises(TypeError, setattr, s, "obj", object())
+
+ def test_glist(self):
+ s = Regress.TestStructD()
+ self.assertEqual(s.list, [])
+
+ self.assertRaises(TypeError, setattr, s, "list", [object()])
+
+ def test_gpointer(self):
+ glist = GLib.List()
+
+ glist.data = 123
+ self.assertEqual(glist.data, 123)
+
+ glist.data = None
+ self.assertEqual(glist.data, 0)
+
+ def test_gptrarray(self):
+ s = Regress.TestStructD()
+ self.assertEqual(s.garray, [])
+
+ self.assertRaises(TypeError, setattr, s, "garray", [object()])
+
+ def test_enum(self):
+ s = Regress.TestStructA()
+
+ s.some_enum = Regress.TestEnum.VALUE3
+ self.assertEqual(s.some_enum, Regress.TestEnum.VALUE3)
+
+ self.assertRaises(TypeError, setattr, s, "some_enum", object())
+
+ s.some_enum = 0
+ self.assertEqual(s.some_enum, Regress.TestEnum.VALUE1)
+
+ def test_union(self):
+ s = Regress.TestStructE()
+ self.assertEqual(s.some_union, [None, None])
+
+ def test_struct(self):
+ s = GIMarshallingTests.NestedStruct()
+
+ # FIXME: segfaults
+ # https://bugzilla.gnome.org/show_bug.cgi?id=747002
+ # s.simple_struct = None
+
+ self.assertRaises(TypeError, setattr, s, "simple_struct", object())
+
+ sub = GIMarshallingTests.SimpleStruct()
+ sub.long_ = 42
+ s.simple_struct = sub
+ self.assertEqual(s.simple_struct.long_, 42)
+
+ def test_ghashtable(self):
+ obj = Regress.TestObj()
+ self.assertTrue(obj.hash_table is None)
import gi
import gi.overrides
+from gi import PyGIWarning
from gi import PyGIDeprecationWarning
from gi.repository import GObject, GLib, Gio
gi.check_version("3.3.5")
+class TestGIWarning(unittest.TestCase):
+
+ def test_warning(self):
+ ignored_by_default = (DeprecationWarning, PendingDeprecationWarning,
+ ImportWarning)
+
+ with warnings.catch_warnings(record=True) as warn:
+ warnings.simplefilter('always')
+ warnings.warn("test", PyGIWarning)
+ self.assertTrue(issubclass(warn[0].category, Warning))
+ # We don't want PyGIWarning get ignored by default
+ self.assertFalse(issubclass(warn[0].category, ignored_by_default))
+
+
class TestDeprecation(unittest.TestCase):
def test_method(self):
d = GLib.Date.new()