diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2017-07-12 08:42:37 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2017-07-12 08:42:41 +0900 |
commit | 87757999f26315ef84be29236bef8a1ba4e4af76 (patch) | |
tree | 716215f025890e99a84fe46b5431ee0399313ee5 | |
parent | c20b00fa62305380031ec383e1d7f7c548cdfe44 (diff) | |
download | pygobject2-87757999f26315ef84be29236bef8a1ba4e4af76.tar.gz pygobject2-87757999f26315ef84be29236bef8a1ba4e4af76.tar.bz2 pygobject2-87757999f26315ef84be29236bef8a1ba4e4af76.zip |
Imported Upstream version 3.13.92
Change-Id: Ic195bab5260fd866ffc9d377f9efdcba5bffe014
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
-rw-r--r-- | ChangeLog | 145 | ||||
-rw-r--r-- | NEWS | 7 | ||||
-rw-r--r-- | PKG-INFO | 4 | ||||
-rw-r--r-- | aclocal.m4 | 318 | ||||
-rwxr-xr-x | configure | 45 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | gi/pygi-argument.c | 11 | ||||
-rw-r--r-- | gi/pygi-array.c | 1 | ||||
-rw-r--r-- | gi/pygi-boxed.c | 20 | ||||
-rw-r--r-- | gi/pygi-boxed.h | 2 | ||||
-rw-r--r-- | gi/pygi-marshal-cleanup.c | 13 | ||||
-rw-r--r-- | gi/pygi-signal-closure.c | 43 | ||||
-rw-r--r-- | gi/pygi-struct-marshal.c | 7 | ||||
-rw-r--r-- | tests/Makefile.am | 23 | ||||
-rw-r--r-- | tests/Makefile.in | 23 | ||||
-rw-r--r-- | tests/test_everything.py | 72 | ||||
-rw-r--r-- | tests/test_gio.py | 29 | ||||
-rw-r--r-- | tests/test_overrides_gtk.py | 18 | ||||
-rw-r--r-- | tests/test_signal.py | 27 |
19 files changed, 624 insertions, 186 deletions
@@ -1,3 +1,148 @@ +commit 79bad703a089a4b0c31fcdb143b889667f5fa197 +Author: Simon Feltman <sfeltman@src.gnome.org> +Date: Fri Sep 12 17:10:04 2014 -0700 + + tests: Add test for Gio.Application.add_main_option() + + tests/test_gio.py | 29 +++++++++++++++++++++++++++++ + 1 file changed, 29 insertions(+) + +commit a2f98a9ba0b0dda0d3cf59651327e5c93d5479d6 +Author: Simon Feltman <sfeltman@src.gnome.org> +Date: Thu Sep 11 19:32:53 2014 -0700 + + Split test_everything.TestEverything.test_string() into multiple tests + + https://bugzilla.gnome.org/show_bug.cgi?id=735193 + + tests/test_everything.py | 25 +++++++++++++++++++------ + 1 file changed, 19 insertions(+), 6 deletions(-) + +commit 6674701b6de02353738b9dc04ab88de23996704e +Author: Simon Feltman <sfeltman@src.gnome.org> +Date: Thu Sep 11 19:08:53 2014 -0700 + + tests: Split array tests up + + Split test_everything.TestEverything.test_array(), + test_array_fixed_size(), + and test_ptrarray() into functions of a finer granularity. This + allows for + easier diagnosis of problems and leaks when they occur. + + https://bugzilla.gnome.org/show_bug.cgi?id=735193 + + tests/test_everything.py | 37 ++++++++++++++++++++++++++++++++----- + 1 file changed, 32 insertions(+), 5 deletions(-) + +commit d1bae18ba0514864a37bf5d182605e2100c28d7e +Author: Simon Feltman <sfeltman@src.gnome.org> +Date: Thu Sep 11 16:17:13 2014 -0700 + + tests: Split test_strv() into multiple tests + + https://bugzilla.gnome.org/show_bug.cgi?id=735193 + + tests/test_everything.py | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +commit 6181f724bc2c6ea30194c961cb15b2c543a48f95 +Author: Simon Feltman <sfeltman@src.gnome.org> +Date: Wed Sep 10 19:06:35 2014 -0700 + + Fix invalid read error in argument cleanup code + + Always set initial length argument index for arrays to -1. Ensure + we don't + attempt retrieving Python cleanup arguments until we know it is valid. + This was causing an invalid read in test_gi.TestArray.test_array_out() + + gi/pygi-array.c | 1 + + gi/pygi-marshal-cleanup.c | 13 ++++++++----- + 2 files changed, 9 insertions(+), 5 deletions(-) + +commit 972e944ad4b2aac03c61633b8c277e35395c114c +Author: Simon Feltman <sfeltman@src.gnome.org> +Date: Wed Sep 10 18:55:45 2014 -0700 + + tests: Increase num-callers for valgrind runs + + Additionally split valgrind check variations over multiple lines + for readability. + + tests/Makefile.am | 23 ++++++++++++++++++++--- + 1 file changed, 20 insertions(+), 3 deletions(-) + +commit d70b300c7415dd7b20ff88b09fe835690da19831 +Author: Simon Feltman <sfeltman@src.gnome.org> +Date: Sat Sep 6 23:58:25 2014 -0700 + + Fix memory management problems with struct arguments to signals + + Replicate struct marshaling logic for determining if struct arguments + to signals should be passed by reference to callbacks. + Maintain a list of these structs and apply an in-place copy of + the struct + pointer if the struct wrapper is held longer than the duration of the + Python callback. This allows for both mutation of struct arguments + from + callbacks as well as memory safety incase a callbacks holds onto + the struct. + + https://bugzilla.gnome.org/show_bug.cgi?id=736175 + + gi/pygi-boxed.c | 20 ++++++++++++++++++++ + gi/pygi-boxed.h | 2 ++ + gi/pygi-signal-closure.c | 43 + +++++++++++++++++++++++++++++++++++++------ + tests/test_overrides_gtk.py | 1 - + tests/test_signal.py | 27 +++++++++++++++++++++++++++ + 5 files changed, 86 insertions(+), 7 deletions(-) + +commit 09161ff690ad37c94668d5d65191f4d84829d41f +Author: Simon Feltman <sfeltman@src.gnome.org> +Date: Sun Sep 7 15:53:35 2014 -0700 + + Limit foreign struct checks to GI_INFO_TYPE_STRUCT + + Add struct type check before calling g_struct_info_is_foreign(). + + https://bugzilla.gnome.org/show_bug.cgi?id=736175 + + gi/pygi-argument.c | 11 ++++++++--- + gi/pygi-struct-marshal.c | 7 +++++-- + 2 files changed, 13 insertions(+), 5 deletions(-) + +commit 4ebb1f5a4750712bd919a31103ed8c8d6af483b3 +Author: Simon Feltman <sfeltman@src.gnome.org> +Date: Sat Sep 6 15:16:06 2014 -0700 + + tests: Add failing regression test for Gtk.TextBuffer.insert-text + signal + + https://bugzilla.gnome.org/show_bug.cgi?id=736175 + + tests/test_overrides_gtk.py | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +commit 2f355dc4e9724f25c200d30db1c8fbc4695f9ab7 +Author: Simon Feltman <sfeltman@src.gnome.org> +Date: Mon Sep 1 17:36:46 2014 -0700 + + configure.ac: post release version bump to 3.13.92 + + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 68d34721a21bfac1a43252bd92612c2460ea60dd +Author: Simon Feltman <sfeltman@src.gnome.org> +Date: Mon Sep 1 17:31:39 2014 -0700 + + release 3.13.91 + + NEWS | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + commit 8c6cf22d74075b7169512b9e7773a511abb9b759 Author: Simon Feltman <sfeltman@src.gnome.org> Date: Mon Sep 1 16:48:15 2014 -0700 @@ -1,3 +1,10 @@ +3.13.92 15-Sep-2014 + - tests: Add test for Gio.Application.add_main_option() (Simon Feltman) + - tests: Split up various test cases (Simon Feltman) (#735193) + - Fix invalid read error in argument cleanup code (Simon Feltman) + - Fix memory management problems with struct arguments to signals + (Simon Feltman) (#736175) + 3.13.91 01-Sep-2014 - docs: Fix return types in auto-generated doc strings (Simon Feltman) - Special case signal output arguments which are structs as @@ -1,6 +1,6 @@ Metadata-Version: 1.0 Name: PyGObject -Version: 3.13.91 +Version: 3.13.92 Summary: Python bindings for GObject Home-page: http://www.pygtk.org/ Author: James Henstridge @@ -8,7 +8,7 @@ Author-email: james@daa.com.au Maintainer: Simon Feltman Maintainer-email: sfeltman@src.gnome.org License: GNU LGPL -Download-url: ftp://ftp.gnome.org/pub/GNOME/sources/pygobject/3.13/pygobject-3.13.91.tar.gz +Download-url: ftp://ftp.gnome.org/pub/GNOME/sources/pygobject/3.13/pygobject-3.13.92.tar.gz Description: Python bindings for GLib and GObject Platform: POSIX, Windows Classifier: Development Status :: 5 - Production/Stable @@ -235,6 +235,187 @@ AS_VAR_COPY([$1], [pkg_cv_][$1]) AS_VAR_IF([$1], [""], [$5], [$4])dnl ])# PKG_CHECK_VAR +# SYNOPSIS +# +# AX_CODE_COVERAGE() +# +# DESCRIPTION +# +# Defines CODE_COVERAGE_CFLAGS and CODE_COVERAGE_LDFLAGS which should be +# included in the CFLAGS and LIBS/LDFLAGS variables of every build target +# (program or library) which should be built with code coverage support. +# Also defines CODE_COVERAGE_RULES which should be substituted in your +# Makefile; and $enable_code_coverage which can be used in subsequent +# configure output. CODE_COVERAGE_ENABLED is defined and substituted, and +# corresponds to the value of the --enable-code-coverage option, which +# defaults to being disabled. +# +# Note that all optimisation flags in CFLAGS must be disabled when code +# coverage is enabled. +# +# Usage example: +# configure.ac: +# AX_CODE_COVERAGE +# +# Makefile.am: +# @CODE_COVERAGE_RULES@ +# my_program_LIBS = … $(CODE_COVERAGE_LDFLAGS) … +# my_program_CFLAGS = … $(CODE_COVERAGE_CFLAGS) … +# +# This results in a “check-code-coverage” rule being added to any Makefile.am +# which includes “@CODE_COVERAGE_RULES@” (assuming the module has been +# configured with --enable-code-coverage). Running `make check-code-coverage` +# in that directory will run the module’s test suite (`make check`) and build +# a code coverage report detailing the code which was touched, then print the +# URI for the report. +# +# LICENSE +# +# Copyright © 2012, 2014 Philip Withnall +# Copyright © 2012 Xan Lopez +# Copyright © 2012 Christian Persch +# Copyright © 2012 Paolo Borelli +# Copyright © 2012 Dan Winship +# +# Derived from Makefile.decl in GLib, originally licenced under LGPLv2.1+. +# This file is licenced under LGPLv2.1+. + +#serial 1 + +AC_DEFUN([AX_CODE_COVERAGE],[ + dnl Check for --enable-code-coverage + AC_MSG_CHECKING([whether to build with code coverage support]) + AC_ARG_ENABLE([code-coverage], AS_HELP_STRING([--enable-code-coverage], [Whether to enable code coverage support]),, enable_code_coverage=no) + AM_CONDITIONAL([CODE_COVERAGE_ENABLED], [test x$enable_code_coverage = xyes]) + AC_SUBST([CODE_COVERAGE_ENABLED], [$enable_code_coverage]) + AC_MSG_RESULT($enable_code_coverage) + + AS_IF([ test "$enable_code_coverage" = "yes" ], [ + dnl Check if gcc is being used + AS_IF([ test "$GCC" = "no" ], [ + AC_MSG_ERROR([not compiling with gcc, which is required for gcov code coverage]) + ]) + + # List of supported lcov versions. + lcov_version_list="1.6 1.7 1.8 1.9 1.10 1.11" + + AC_CHECK_PROG([LCOV], [lcov], [lcov]) + AC_CHECK_PROG([GENHTML], [genhtml], [genhtml]) + + AS_IF([ test "$LCOV" ], [ + AC_CACHE_CHECK([for lcov version], ax_cv_lcov_version, [ + ax_cv_lcov_version=invalid + lcov_version=`$LCOV -v 2>/dev/null | $SED -e 's/^.* //'` + for lcov_check_version in $lcov_version_list; do + if test "$lcov_version" = "$lcov_check_version"; then + ax_cv_lcov_version="$lcov_check_version (ok)" + fi + done + ]) + ], [ + lcov_msg="To enable code coverage reporting you must have one of the following lcov versions installed: $lcov_version_list" + AC_MSG_ERROR([$lcov_msg]) + ]) + + case $ax_cv_lcov_version in + ""|invalid[)] + lcov_msg="You must have one of the following versions of lcov: $lcov_version_list (found: $lcov_version)." + AC_MSG_ERROR([$lcov_msg]) + LCOV="exit 0;" + ;; + esac + + AS_IF([ test -z "$GENHTML" ], [ + AC_MSG_ERROR([Could not find genhtml from the lcov package]) + ]) + + dnl Build the code coverage flags + CODE_COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" + CODE_COVERAGE_LDFLAGS="-lgcov" + + AC_SUBST([CODE_COVERAGE_CFLAGS]) + AC_SUBST([CODE_COVERAGE_LDFLAGS]) + ]) + +CODE_COVERAGE_RULES=' +# Code coverage +# +# Optional: +# - CODE_COVERAGE_DIRECTORY: Top-level directory for code coverage reporting. +# (Default: $(top_builddir)) +# - CODE_COVERAGE_OUTPUT_FILE: Filename and path for the .info file generated +# by lcov for code coverage. (Default: +# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info) +# - CODE_COVERAGE_OUTPUT_DIRECTORY: Directory for generated code coverage +# reports to be created. (Default: +# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage) +# - CODE_COVERAGE_LCOV_OPTIONS: Extra options to pass to the lcov instance. +# (Default: empty) +# - CODE_COVERAGE_GENHTML_OPTIONS: Extra options to pass to the genhtml +# instance. (Default: empty) +# - CODE_COVERAGE_IGNORE_PATTERN: Extra glob pattern of files to ignore +# +# The generated report will be titled using the $(PACKAGE_NAME) and +# $(PACKAGE_VERSION). In order to add the current git hash to the title, +# use the git-version-gen script, available online. + +# Optional variables +CODE_COVERAGE_DIRECTORY ?= $(top_builddir) +CODE_COVERAGE_OUTPUT_FILE ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info +CODE_COVERAGE_OUTPUT_DIRECTORY ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage +CODE_COVERAGE_LCOV_OPTIONS ?= +CODE_COVERAGE_GENHTML_OPTIONS ?= +CODE_COVERAGE_IGNORE_PATTERN ?= + +code_coverage_quiet = $(code_coverage_quiet_$(V)) +code_coverage_quiet_ = $(code_coverage_quiet_$(AM_DEFAULT_VERBOSITY)) +code_coverage_quiet_0 = --quiet + +# Use recursive makes in order to ignore errors during check +check-code-coverage: +ifeq ($(CODE_COVERAGE_ENABLED),yes) + -$(MAKE) $(AM_MAKEFLAGS) -k check + $(MAKE) $(AM_MAKEFLAGS) code-coverage-capture +else + @echo "Need to reconfigure with --enable-code-coverage" +endif + +# Capture code coverage data +code-coverage-capture: code-coverage-capture-hook +ifeq ($(CODE_COVERAGE_ENABLED),yes) + $(LCOV) $(code_coverage_quiet) --directory $(CODE_COVERAGE_DIRECTORY) --capture --output-file "$(CODE_COVERAGE_OUTPUT_FILE).tmp" --test-name "$(PACKAGE_NAME)-$(PACKAGE_VERSION)" --no-checksum --compat-libtool $(CODE_COVERAGE_LCOV_OPTIONS) + $(LCOV) $(code_coverage_quiet) --directory $(CODE_COVERAGE_DIRECTORY) --remove "$(CODE_COVERAGE_OUTPUT_FILE).tmp" "/tmp/*" $(CODE_COVERAGE_IGNORE_PATTERN) --output-file "$(CODE_COVERAGE_OUTPUT_FILE)" + -@rm -f $(CODE_COVERAGE_OUTPUT_FILE).tmp + LANG=C $(GENHTML) $(code_coverage_quiet) --prefix $(CODE_COVERAGE_DIRECTORY) --output-directory "$(CODE_COVERAGE_OUTPUT_DIRECTORY)" --title "$(PACKAGE_NAME)-$(PACKAGE_VERSION) Code Coverage" --legend --show-details "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_GENHTML_OPTIONS) + @echo "file://$(abs_builddir)/$(CODE_COVERAGE_OUTPUT_DIRECTORY)/index.html" +else + @echo "Need to reconfigure with --enable-code-coverage" +endif + +# Hook rule executed before code-coverage-capture, overridable by the user +code-coverage-capture-hook: + +ifeq ($(CODE_COVERAGE_ENABLED),yes) +clean: code-coverage-clean +code-coverage-clean: + -$(LCOV) --directory $(top_builddir) -z + -rm -rf $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_FILE).tmp $(CODE_COVERAGE_OUTPUT_DIRECTORY) + -find . -name "*.gcda" -o -name "*.gcov" -delete +endif + +GITIGNOREFILES ?= +GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY) + +DISTCHECK_CONFIGURE_FLAGS ?= +DISTCHECK_CONFIGURE_FLAGS += --disable-code-coverage + +.PHONY: check-code-coverage code-coverage-capture code-coverage-capture-hook code-coverage-clean +' + + AC_SUBST([CODE_COVERAGE_RULES]) + m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([CODE_COVERAGE_RULES])]) +]) + # Configure paths for GLIB # Owen Taylor 1997-2001 @@ -478,139 +659,16 @@ dnl in that directory will run the module’s test suite (`make check`) and buil dnl a code coverage report detailing the code which was touched, then print the dnl URI for the report. -AC_DEFUN([GNOME_CODE_COVERAGE],[ - dnl Check for --enable-code-coverage - AC_MSG_CHECKING([whether to build with code coverage support]) - AC_ARG_ENABLE([code-coverage], AS_HELP_STRING([--enable-code-coverage], [Whether to enable code coverage support]),, enable_code_coverage=no) - AM_CONDITIONAL([CODE_COVERAGE_ENABLED], [test x$enable_code_coverage = xyes]) - AC_SUBST([CODE_COVERAGE_ENABLED], [$enable_code_coverage]) - AC_MSG_RESULT($enable_code_coverage) - - AS_IF([ test "$enable_code_coverage" = "yes" ], [ - dnl Check if gcc is being used - AS_IF([ test "$GCC" = "no" ], [ - AC_MSG_ERROR([not compiling with gcc, which is required for gcov code coverage]) - ]) - - # List of supported lcov versions. - lcov_version_list="1.6 1.7 1.8 1.9 1.10 1.11" - - AC_CHECK_PROG([LCOV], [lcov], [lcov]) - AC_CHECK_PROG([GENHTML], [genhtml], [genhtml]) - - AS_IF([ test "$LCOV" ], [ - AC_CACHE_CHECK([for lcov version], gnome_cv_lcov_version, [ - gnome_cv_lcov_version=invalid - lcov_version=`$LCOV -v 2>/dev/null | $SED -e 's/^.* //'` - for lcov_check_version in $lcov_version_list; do - if test "$lcov_version" = "$lcov_check_version"; then - gnome_cv_lcov_version="$lcov_check_version (ok)" - fi - done - ]) - ], [ - lcov_msg="To enable code coverage reporting you must have one of the following lcov versions installed: $lcov_version_list" - AC_MSG_ERROR([$lcov_msg]) - ]) - - case $gnome_cv_lcov_version in - ""|invalid[)] - lcov_msg="You must have one of the following versions of lcov: $lcov_version_list (found: $lcov_version)." - AC_MSG_ERROR([$lcov_msg]) - LCOV="exit 0;" - ;; - esac - - AS_IF([ test -z "$GENHTML" ], [ - AC_MSG_ERROR([Could not find genhtml from the lcov package]) - ]) - - dnl Build the code coverage flags - CODE_COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" - CODE_COVERAGE_LDFLAGS="-lgcov" - - AC_SUBST([CODE_COVERAGE_CFLAGS]) - AC_SUBST([CODE_COVERAGE_LDFLAGS]) - ]) - -GNOME_CODE_COVERAGE_RULES=' -# Code coverage -# -# Optional: -# - CODE_COVERAGE_DIRECTORY: Top-level directory for code coverage reporting. -# (Default: $(top_builddir)) -# - CODE_COVERAGE_OUTPUT_FILE: Filename and path for the .info file generated -# by lcov for code coverage. (Default: -# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info) -# - CODE_COVERAGE_OUTPUT_DIRECTORY: Directory for generated code coverage -# reports to be created. (Default: -# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage) -# - CODE_COVERAGE_LCOV_OPTIONS: Extra options to pass to the lcov instance. -# (Default: empty) -# - CODE_COVERAGE_GENHTML_OPTIONS: Extra options to pass to the genhtml -# instance. (Default: empty) -# - CODE_COVERAGE_IGNORE_PATTERN: Extra glob pattern of files to ignore -# -# The generated report will be titled using the $(PACKAGE_NAME) and -# $(PACKAGE_VERSION). In order to add the current git hash to the title, -# use the git-version-gen script, available online. - -# Optional variables -CODE_COVERAGE_DIRECTORY ?= $(top_builddir) -CODE_COVERAGE_OUTPUT_FILE ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info -CODE_COVERAGE_OUTPUT_DIRECTORY ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage -CODE_COVERAGE_LCOV_OPTIONS ?= -CODE_COVERAGE_GENHTML_OPTIONS ?= -CODE_COVERAGE_IGNORE_PATTERN ?= - -code_coverage_quiet = $(code_coverage_quiet_$(V)) -code_coverage_quiet_ = $(code_coverage_quiet_$(AM_DEFAULT_VERBOSITY)) -code_coverage_quiet_0 = --quiet - -# Use recursive makes in order to ignore errors during check -check-code-coverage: -ifeq ($(CODE_COVERAGE_ENABLED),yes) - -$(MAKE) $(AM_MAKEFLAGS) -k check - $(MAKE) $(AM_MAKEFLAGS) code-coverage-capture -else - @echo "Need to reconfigure with --enable-code-coverage" -endif - -# Capture code coverage data -code-coverage-capture: code-coverage-capture-hook -ifeq ($(CODE_COVERAGE_ENABLED),yes) - $(LCOV) $(code_coverage_quiet) --directory $(CODE_COVERAGE_DIRECTORY) --capture --output-file "$(CODE_COVERAGE_OUTPUT_FILE).tmp" --test-name "$(PACKAGE_NAME)-$(PACKAGE_VERSION)" --no-checksum --compat-libtool $(CODE_COVERAGE_LCOV_OPTIONS) - $(LCOV) $(code_coverage_quiet) --directory $(CODE_COVERAGE_DIRECTORY) --remove "$(CODE_COVERAGE_OUTPUT_FILE).tmp" "/tmp/*" $(CODE_COVERAGE_IGNORE_PATTERN) --output-file "$(CODE_COVERAGE_OUTPUT_FILE)" - -@rm -f $(CODE_COVERAGE_OUTPUT_FILE).tmp - LANG=C $(GENHTML) $(code_coverage_quiet) --prefix $(CODE_COVERAGE_DIRECTORY) --output-directory "$(CODE_COVERAGE_OUTPUT_DIRECTORY)" --title "$(PACKAGE_NAME)-$(PACKAGE_VERSION) Code Coverage" --legend --show-details "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_GENHTML_OPTIONS) - @echo "file://$(abs_builddir)/$(CODE_COVERAGE_OUTPUT_DIRECTORY)/index.html" -else - @echo "Need to reconfigure with --enable-code-coverage" -endif - -# Hook rule executed before code-coverage-capture, overridable by the user -code-coverage-capture-hook: - -ifeq ($(CODE_COVERAGE_ENABLED),yes) -clean: code-coverage-clean -code-coverage-clean: - -$(LCOV) --directory $(top_builddir) -z - -rm -rf $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_FILE).tmp $(CODE_COVERAGE_OUTPUT_DIRECTORY) - -find . -name "*.gcda" -o -name "*.gcov" -delete -endif - -GITIGNOREFILES ?= -GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY) - -DISTCHECK_CONFIGURE_FLAGS ?= -DISTCHECK_CONFIGURE_FLAGS += --disable-code-coverage - -.PHONY: check-code-coverage code-coverage-capture code-coverage-capture-hook code-coverage-clean -' +AU_DEFUN([GNOME_CODE_COVERAGE],[ + AX_CODE_COVERAGE + GNOME_CODE_COVERAGE_RULES=$CODE_COVERAGE_RULES AC_SUBST([GNOME_CODE_COVERAGE_RULES]) m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([GNOME_CODE_COVERAGE_RULES])]) -]) +], +[[$0: This macro is deprecated. You should use AX_CODE_COVERAGE instead and +replace uses of GNOME_CODE_COVERAGE_RULES with CODE_COVERAGE_RULES. +See: http://www.gnu.org/software/autoconf-archive/ax_code_coverage.html#ax_code_coverage]]) # gnome-compiler-flags.m4 # @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for pygobject 3.13.91. +# Generated by GNU Autoconf 2.69 for pygobject 3.13.92. # # Report bugs to <http://bugzilla.gnome.org/enter_bug.cgi?product=pygobject>. # @@ -591,8 +591,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='pygobject' PACKAGE_TARNAME='pygobject' -PACKAGE_VERSION='3.13.91' -PACKAGE_STRING='pygobject 3.13.91' +PACKAGE_VERSION='3.13.92' +PACKAGE_STRING='pygobject 3.13.92' PACKAGE_BUGREPORT='http://bugzilla.gnome.org/enter_bug.cgi?product=pygobject' PACKAGE_URL='https://wiki.gnome.org/Projects/PyGObject/' @@ -638,6 +638,7 @@ am__EXEEXT_TRUE LTLIBOBJS LIBOBJS GNOME_CODE_COVERAGE_RULES +CODE_COVERAGE_RULES CODE_COVERAGE_LDFLAGS CODE_COVERAGE_CFLAGS GENHTML @@ -1394,7 +1395,7 @@ if test "$ac_init_help" = "long"; then # 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.13.91 to adapt to many kinds of systems. +\`configure' configures pygobject 3.13.92 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1464,7 +1465,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of pygobject 3.13.91:";; + short | recursive ) echo "Configuration of pygobject 3.13.92:";; esac cat <<\_ACEOF @@ -1602,7 +1603,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -pygobject configure 3.13.91 +pygobject configure 3.13.92 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1880,7 +1881,7 @@ cat >config.log <<_ACEOF 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.13.91, which was +It was created by pygobject $as_me 3.13.92, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2244,9 +2245,9 @@ $as_echo "#define PYGOBJECT_MINOR_VERSION 13" >>confdefs.h PYGOBJECT_MINOR_VERSION=13 -$as_echo "#define PYGOBJECT_MICRO_VERSION 91" >>confdefs.h +$as_echo "#define PYGOBJECT_MICRO_VERSION 92" >>confdefs.h -PYGOBJECT_MICRO_VERSION=91 +PYGOBJECT_MICRO_VERSION=92 ac_config_headers="$ac_config_headers config.h" @@ -2766,7 +2767,7 @@ fi # Define the identity of the package. PACKAGE='pygobject' - VERSION='3.13.91' + VERSION='3.13.92' cat >>confdefs.h <<_ACEOF @@ -14402,6 +14403,7 @@ $as_echo_n "checking for Gnome code coverage support... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build with code coverage support" >&5 $as_echo_n "checking whether to build with code coverage support... " >&6; } # Check whether --enable-code-coverage was given. @@ -14514,21 +14516,21 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lcov version" >&5 $as_echo_n "checking for lcov version... " >&6; } -if ${gnome_cv_lcov_version+:} false; then : +if ${ax_cv_lcov_version+:} false; then : $as_echo_n "(cached) " >&6 else - gnome_cv_lcov_version=invalid + ax_cv_lcov_version=invalid lcov_version=`$LCOV -v 2>/dev/null | $SED -e 's/^.* //'` for lcov_check_version in $lcov_version_list; do if test "$lcov_version" = "$lcov_check_version"; then - gnome_cv_lcov_version="$lcov_check_version (ok)" + ax_cv_lcov_version="$lcov_check_version (ok)" fi done fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gnome_cv_lcov_version" >&5 -$as_echo "$gnome_cv_lcov_version" >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_lcov_version" >&5 +$as_echo "$ax_cv_lcov_version" >&6; } else @@ -14537,7 +14539,7 @@ else fi - case $gnome_cv_lcov_version in + case $ax_cv_lcov_version in ""|invalid) lcov_msg="You must have one of the following versions of lcov: $lcov_version_list (found: $lcov_version)." as_fn_error $? "$lcov_msg" "$LINENO" 5 @@ -14559,7 +14561,7 @@ fi fi -GNOME_CODE_COVERAGE_RULES=' +CODE_COVERAGE_RULES=' # Code coverage # # Optional: @@ -14637,6 +14639,11 @@ DISTCHECK_CONFIGURE_FLAGS += --disable-code-coverage + GNOME_CODE_COVERAGE_RULES=$CODE_COVERAGE_RULES + + + + if test "x$GCC" = "xyes"; then @@ -15369,7 +15376,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # 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.13.91, which was +This file was extended by pygobject $as_me 3.13.92, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -15436,7 +15443,7 @@ _ACEOF 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.13.91 +pygobject config.status 3.13.92 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 90413b9..69d6edb 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,7 @@ m4_define(python3_min_ver, 3.1) dnl the pygobject version number m4_define(pygobject_major_version, 3) m4_define(pygobject_minor_version, 13) -m4_define(pygobject_micro_version, 91) +m4_define(pygobject_micro_version, 92) m4_define(pygobject_version, pygobject_major_version.pygobject_minor_version.pygobject_micro_version) dnl versions of packages we require ... diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c index 3d643fe..d63520d 100644 --- a/gi/pygi-argument.c +++ b/gi/pygi-argument.c @@ -1036,6 +1036,8 @@ array_success: { GType g_type; PyObject *py_type; + gboolean is_foreign = (info_type == GI_INFO_TYPE_STRUCT) && + (g_struct_info_is_foreign ((GIStructInfo *) info)); g_type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *) info); py_type = _pygi_type_import_by_gi_info ( (GIBaseInfo *) info); @@ -1055,7 +1057,7 @@ array_success: py_type, transfer, FALSE, /*copy_reference*/ - g_struct_info_is_foreign (info), + is_foreign, g_type_info_is_pointer (type_info)); Py_DECREF (py_type); @@ -1382,6 +1384,8 @@ _pygi_argument_to_object (GIArgument *arg, { PyObject *py_type; GType g_type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *) info); + gboolean is_foreign = (info_type == GI_INFO_TYPE_STRUCT) && + (g_struct_info_is_foreign ((GIStructInfo *) info)); /* Special case variant and none to force loading from py module. */ if (g_type == G_TYPE_VARIANT || g_type == G_TYPE_NONE) { @@ -1396,7 +1400,7 @@ _pygi_argument_to_object (GIArgument *arg, py_type, transfer, FALSE, /*is_allocated*/ - g_struct_info_is_foreign (info)); + is_foreign); Py_XDECREF (py_type); break; @@ -1703,7 +1707,8 @@ _pygi_argument_release (GIArgument *arg, if (direction == GI_DIRECTION_IN && transfer == GI_TRANSFER_NOTHING) { g_closure_unref (arg->v_pointer); } - } else if (g_struct_info_is_foreign ( (GIStructInfo*) info)) { + } else if (info_type == GI_INFO_TYPE_STRUCT && + g_struct_info_is_foreign ((GIStructInfo*) info)) { if (direction == GI_DIRECTION_OUT && transfer == GI_TRANSFER_EVERYTHING) { pygi_struct_foreign_release (info, arg->v_pointer); } diff --git a/gi/pygi-array.c b/gi/pygi-array.c index 4cfbd17..e2598cd 100644 --- a/gi/pygi-array.c +++ b/gi/pygi-array.c @@ -803,6 +803,7 @@ pygi_arg_garray_len_arg_setup (PyGIArgCache *arg_cache, child_cache->direction = direction; child_cache->to_py_marshaller = _pygi_marshal_to_py_basic_type_cache_adapter; child_cache->from_py_marshaller = _pygi_marshal_from_py_basic_type_cache_adapter; + child_cache->py_arg_index = -1; /* ugly edge case code: * diff --git a/gi/pygi-boxed.c b/gi/pygi-boxed.c index a1494b6..d5faeb1 100644 --- a/gi/pygi-boxed.c +++ b/gi/pygi-boxed.c @@ -206,6 +206,26 @@ _pygi_boxed_get_free_on_dealloc(PyGIBoxed *self, void *closure) return PyBool_FromLong( ((PyGBoxed *)self)->free_on_dealloc ); } +/** + * _pygi_boxed_copy_in_place: + * + * Replace the boxed pointer held by this wrapper with a boxed copy + * freeing the previously held pointer (when free_on_dealloc is TRUE). + * This can be used in cases where Python is passed a reference which + * it does not own and the wrapper is held by the Python program + * longer than the duration of a callback it was passed to. + */ +void +_pygi_boxed_copy_in_place (PyGIBoxed *self) +{ + PyGBoxed *pygboxed = (PyGBoxed *)self; + gpointer copy = g_boxed_copy (pygboxed->gtype, pyg_boxed_get_ptr (self)); + + boxed_del (self); + pyg_boxed_set_ptr (pygboxed, copy); + pygboxed->free_on_dealloc = TRUE; +} + static PyGetSetDef pygi_boxed_getsets[] = { { "_free_on_dealloc", (getter)_pygi_boxed_get_free_on_dealloc, (setter)0 }, { NULL, 0, 0 } diff --git a/gi/pygi-boxed.h b/gi/pygi-boxed.h index 189a02c..c8f40b7 100644 --- a/gi/pygi-boxed.h +++ b/gi/pygi-boxed.h @@ -34,6 +34,8 @@ PyObject * _pygi_boxed_new (PyTypeObject *pytype, void * _pygi_boxed_alloc (GIBaseInfo *info, gsize *size); +void _pygi_boxed_copy_in_place (PyGIBoxed *self); + void _pygi_boxed_register_types (PyObject *m); G_END_DECLS diff --git a/gi/pygi-marshal-cleanup.c b/gi/pygi-marshal-cleanup.c index 4ba6159..b0ec05a 100644 --- a/gi/pygi-marshal-cleanup.c +++ b/gi/pygi-marshal-cleanup.c @@ -95,8 +95,6 @@ pygi_marshal_cleanup_args_from_py_marshal_success (PyGIInvokeState *state, for (i = 0; i < _pygi_callable_cache_args_len (cache); i++) { PyGIArgCache *arg_cache = _pygi_callable_cache_get_arg (cache, i); PyGIMarshalCleanupFunc cleanup_func = arg_cache->from_py_cleanup; - PyObject *py_arg = PyTuple_GET_ITEM (state->py_in_args, - arg_cache->py_arg_index); gpointer cleanup_data = state->args_cleanup_data[i]; /* Only cleanup using args_cleanup_data when available. @@ -105,8 +103,9 @@ pygi_marshal_cleanup_args_from_py_marshal_success (PyGIInvokeState *state, * PyGIInvokeState.args_cleanup_data stores this data (via _invoke_marshal_in_args) * for the duration of the invoke up until this point. */ - if (cleanup_func && cleanup_data != NULL && + if (cleanup_func && cleanup_data != NULL && arg_cache->py_arg_index >= 0 && arg_cache->direction & PYGI_DIRECTION_FROM_PYTHON) { + PyObject *py_arg = PyTuple_GET_ITEM (state->py_in_args, arg_cache->py_arg_index); cleanup_func (state, arg_cache, py_arg, cleanup_data, TRUE); state->args_cleanup_data[i] = NULL; } @@ -167,8 +166,12 @@ pygi_marshal_cleanup_args_from_py_parameter_fail (PyGIInvokeState *state, PyGIArgCache *arg_cache = _pygi_callable_cache_get_arg (cache, i); PyGIMarshalCleanupFunc cleanup_func = arg_cache->from_py_cleanup; gpointer cleanup_data = state->args_cleanup_data[i]; - PyObject *py_arg = PyTuple_GET_ITEM (state->py_in_args, - arg_cache->py_arg_index); + PyObject *py_arg = NULL; + + if (arg_cache->py_arg_index < 0) { + continue; + } + py_arg = PyTuple_GET_ITEM (state->py_in_args, arg_cache->py_arg_index); if (cleanup_func && cleanup_data != NULL && arg_cache->direction == PYGI_DIRECTION_FROM_PYTHON) { diff --git a/gi/pygi-signal-closure.c b/gi/pygi-signal-closure.c index 3cf8486..652ac99 100644 --- a/gi/pygi-signal-closure.c +++ b/gi/pygi-signal-closure.c @@ -79,6 +79,8 @@ pygi_signal_closure_marshal(GClosure *closure, GISignalInfo *signal_info; gint n_sig_info_args; gint sig_info_highest_arg; + GSList *list_item = NULL; + GSList *pass_by_ref_structs = NULL; state = PyGILState_Ensure(); @@ -131,20 +133,28 @@ pygi_signal_closure_marshal(GClosure *closure, &free_array); } - /* Hack to ensure struct output args are passed-by-reference allowing + /* Hack to ensure struct arguments are passed-by-reference allowing * callback implementors to modify the struct values. This is needed * for keeping backwards compatibility and should be removed in future * versions which support signal output arguments as return values. * See: https://bugzilla.gnome.org/show_bug.cgi?id=735486 + * + * Note the logic here must match the logic path taken in _pygi_argument_to_object. */ - if (type_tag == GI_TYPE_TAG_INTERFACE && - g_arg_info_get_direction (&arg_info) == GI_DIRECTION_OUT) { + if (type_tag == GI_TYPE_TAG_INTERFACE) { GIBaseInfo *info = g_type_info_get_interface (&type_info); GIInfoType info_type = g_base_info_get_type (info); - if (info_type == GI_INFO_TYPE_STRUCT) { + if (info_type == GI_INFO_TYPE_STRUCT || + info_type == GI_INFO_TYPE_BOXED || + info_type == GI_INFO_TYPE_UNION) { + GType gtype = g_registered_type_info_get_g_type ((GIRegisteredTypeInfo *) info); - if (g_type_is_a (gtype, G_TYPE_BOXED)) { + gboolean is_foreign = (info_type == GI_INFO_TYPE_STRUCT) && + (g_struct_info_is_foreign ((GIStructInfo *) info)); + + if (!is_foreign && !g_type_is_a (gtype, G_TYPE_VALUE) && + g_type_is_a (gtype, G_TYPE_BOXED)) { pass_struct_by_ref = TRUE; } } @@ -153,8 +163,12 @@ pygi_signal_closure_marshal(GClosure *closure, } if (pass_struct_by_ref) { + /* transfer everything will ensure the struct is not copied when wrapped. */ item = _pygi_argument_to_object (&arg, &type_info, GI_TRANSFER_EVERYTHING); - ((PyGBoxed *)item)->free_on_dealloc = FALSE; + if (item && PyObject_IsInstance (item, (PyObject *) &PyGIBoxed_Type)) { + ((PyGBoxed *)item)->free_on_dealloc = FALSE; + pass_by_ref_structs = g_slist_prepend (pass_by_ref_structs, item); + } } else { item = _pygi_argument_to_object (&arg, &type_info, GI_TRANSFER_NOTHING); @@ -196,7 +210,24 @@ pygi_signal_closure_marshal(GClosure *closure, } Py_DECREF(ret); + /* Run through the list of structs which have been passed by reference and + * check if they are being held longer than the duration of the callback + * execution. This is determined if the ref count is greater than 1. + * A single ref is held by the argument list and any more would mean the callback + * stored a ref somewhere else. In this case we make an internal copy of + * the boxed struct so Python can own the memory to it. + */ + list_item = pass_by_ref_structs; + while (list_item) { + PyObject *item = list_item->data; + if (item->ob_refcnt > 1) { + _pygi_boxed_copy_in_place ((PyGIBoxed *)item); + } + list_item = g_slist_next (list_item); + } + out: + g_slist_free (pass_by_ref_structs); Py_DECREF(params); PyGILState_Release(state); } diff --git a/gi/pygi-struct-marshal.c b/gi/pygi-struct-marshal.c index 5068064..9bf3b54 100644 --- a/gi/pygi-struct-marshal.c +++ b/gi/pygi-struct-marshal.c @@ -528,7 +528,6 @@ arg_struct_from_py_setup (PyGIArgCache *arg_cache, GITransfer transfer) { PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache; - iface_cache->is_foreign = g_struct_info_is_foreign ( (GIStructInfo*)iface_info); if (g_struct_info_is_gtype_struct ((GIStructInfo*)iface_info)) { arg_cache->from_py_marshaller = arg_type_class_from_py_marshal; @@ -560,7 +559,6 @@ arg_struct_to_py_setup (PyGIArgCache *arg_cache, GIArgInfo *arg_info) { PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache; - iface_cache->is_foreign = g_struct_info_is_foreign ( (GIStructInfo*)iface_info); /* HACK to force GtkTreeModel:iter_next() and iter_previous() vfunc implementations * to receive their Gtk.TreeIter argument as pass-by-reference. We create a new @@ -615,6 +613,7 @@ pygi_arg_struct_new_from_info (GITypeInfo *type_info, GIInterfaceInfo *iface_info) { PyGIArgCache *cache = NULL; + PyGIInterfaceCache *iface_cache; cache = pygi_arg_interface_new_from_info (type_info, arg_info, @@ -624,6 +623,10 @@ pygi_arg_struct_new_from_info (GITypeInfo *type_info, if (cache == NULL) return NULL; + iface_cache = (PyGIInterfaceCache *)cache; + iface_cache->is_foreign = (g_base_info_get_type ((GIBaseInfo *) iface_info) == GI_INFO_TYPE_STRUCT) && + (g_struct_info_is_foreign ((GIStructInfo*) iface_info)); + if (direction & PYGI_DIRECTION_FROM_PYTHON) { arg_struct_from_py_setup (cache, iface_info, transfer); } diff --git a/tests/Makefile.am b/tests/Makefile.am index 62631dc..dedf243 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -149,13 +149,30 @@ check.gdb: check.nemiver: EXEC_NAME="nemiver" $(MAKE) check +# Note G_SLICE in these check variations is intended to clobber the default set in RUN_TESTS_ENV_VARS check.valgrind: - EXEC_NAME="G_SLICE=always-malloc valgrind --leak-check=full --show-possibly-lost=no --suppressions=$(top_srcdir)/tests/$(PYTHON_BASENAME).supp" G_DEBUG=gc-friendly $(MAKE) check + EXEC_NAME="G_SLICE=always-malloc G_DEBUG=gc-friendly \ + valgrind --leak-check=full --show-possibly-lost=no --num-callers=20 \ + --suppressions=$(top_srcdir)/tests/$(PYTHON_BASENAME).supp \ + " \ + $(MAKE) check check.valgrindlog: mkdir -p $(top_builddir)/tmp - EXEC_NAME="G_SLICE=always-malloc valgrind --child-silent-after-fork=yes --log-file=$(top_builddir)/tmp/`git rev-parse HEAD | cut -c1-8`-$$TEST_NAMES.log --leak-check=full --show-possibly-lost=no --suppressions=$(top_srcdir)/tests/$(PYTHON_BASENAME).supp" G_DEBUG=gc-friendly $(MAKE) check + EXEC_NAME="G_SLICE=always-malloc G_DEBUG=gc-friendly \ + valgrind --leak-check=full --show-possibly-lost=no --num-callers=20 \ + --suppressions=$(top_srcdir)/tests/$(PYTHON_BASENAME).supp \ + --child-silent-after-fork=yes \ + --log-file=$(top_builddir)/tmp/`git rev-parse HEAD | cut -c1-8`-$$TEST_NAMES.log \ + " \ + $(MAKE) check check.valgrindxml: mkdir -p $(top_builddir)/tmp - EXEC_NAME="G_SLICE=always-malloc valgrind --child-silent-after-fork=yes --xml=yes --xml-file=$(top_builddir)/tmp/`git rev-parse HEAD | cut -c1-8`-$$TEST_NAMES.xml --leak-check=full --show-possibly-lost=no --suppressions=$(top_srcdir)/tests/$(PYTHON_BASENAME).supp" G_DEBUG=gc-friendly $(MAKE) check + EXEC_NAME="G_SLICE=always-malloc G_DEBUG=gc-friendly \ + valgrind --leak-check=full --show-possibly-lost=no --num-callers=20 \ + --suppressions=$(top_srcdir)/tests/$(PYTHON_BASENAME).supp \ + --child-silent-after-fork=yes \ + --xml=yes --xml-file=$(top_builddir)/tmp/`git rev-parse HEAD | cut -c1-8`-$$TEST_NAMES.xml \ + " \ + $(MAKE) check diff --git a/tests/Makefile.in b/tests/Makefile.in index 0039b6a..f3cfd16 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -830,16 +830,33 @@ check.gdb: check.nemiver: EXEC_NAME="nemiver" $(MAKE) check +# Note G_SLICE in these check variations is intended to clobber the default set in RUN_TESTS_ENV_VARS check.valgrind: - EXEC_NAME="G_SLICE=always-malloc valgrind --leak-check=full --show-possibly-lost=no --suppressions=$(top_srcdir)/tests/$(PYTHON_BASENAME).supp" G_DEBUG=gc-friendly $(MAKE) check + EXEC_NAME="G_SLICE=always-malloc G_DEBUG=gc-friendly \ + valgrind --leak-check=full --show-possibly-lost=no --num-callers=20 \ + --suppressions=$(top_srcdir)/tests/$(PYTHON_BASENAME).supp \ + " \ + $(MAKE) check check.valgrindlog: mkdir -p $(top_builddir)/tmp - EXEC_NAME="G_SLICE=always-malloc valgrind --child-silent-after-fork=yes --log-file=$(top_builddir)/tmp/`git rev-parse HEAD | cut -c1-8`-$$TEST_NAMES.log --leak-check=full --show-possibly-lost=no --suppressions=$(top_srcdir)/tests/$(PYTHON_BASENAME).supp" G_DEBUG=gc-friendly $(MAKE) check + EXEC_NAME="G_SLICE=always-malloc G_DEBUG=gc-friendly \ + valgrind --leak-check=full --show-possibly-lost=no --num-callers=20 \ + --suppressions=$(top_srcdir)/tests/$(PYTHON_BASENAME).supp \ + --child-silent-after-fork=yes \ + --log-file=$(top_builddir)/tmp/`git rev-parse HEAD | cut -c1-8`-$$TEST_NAMES.log \ + " \ + $(MAKE) check check.valgrindxml: mkdir -p $(top_builddir)/tmp - EXEC_NAME="G_SLICE=always-malloc valgrind --child-silent-after-fork=yes --xml=yes --xml-file=$(top_builddir)/tmp/`git rev-parse HEAD | cut -c1-8`-$$TEST_NAMES.xml --leak-check=full --show-possibly-lost=no --suppressions=$(top_srcdir)/tests/$(PYTHON_BASENAME).supp" G_DEBUG=gc-friendly $(MAKE) check + EXEC_NAME="G_SLICE=always-malloc G_DEBUG=gc-friendly \ + valgrind --leak-check=full --show-possibly-lost=no --num-callers=20 \ + --suppressions=$(top_srcdir)/tests/$(PYTHON_BASENAME).supp \ + --child-silent-after-fork=yes \ + --xml=yes --xml-file=$(top_builddir)/tmp/`git rev-parse HEAD | cut -c1-8`-$$TEST_NAMES.xml \ + " \ + $(MAKE) check # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/tests/test_everything.py b/tests/test_everything.py index dfd1dc4..741de1a 100644 --- a/tests/test_everything.py +++ b/tests/test_everything.py @@ -33,6 +33,12 @@ else: UNICHAR = "♥" +const_str = b'const \xe2\x99\xa5 utf8' +if sys.version_info >= (3, 0): + const_str = const_str.decode('UTF-8') +noconst_str = 'non' + const_str + + class RawGList(ctypes.Structure): _fields_ = [('data', ctypes.c_void_p), ('next', ctypes.c_void_p), @@ -221,27 +227,34 @@ class TestEverything(unittest.TestCase): timeout = v.lookup_value('timeout', None) self.assertEqual(timeout.get_int32(), 10) - def test_string(self): - const_str = b'const \xe2\x99\xa5 utf8' - if sys.version_info >= (3, 0): - const_str = const_str.decode('UTF-8') - noconst_str = 'non' + const_str - + def test_utf8_const_return(self): self.assertEqual(Everything.test_utf8_const_return(), const_str) + + def test_utf8_nonconst_return(self): self.assertEqual(Everything.test_utf8_nonconst_return(), noconst_str) + + def test_utf8_out(self): self.assertEqual(Everything.test_utf8_out(), noconst_str) + def test_utf8_const_in(self): Everything.test_utf8_const_in(const_str) + + def test_utf8_inout(self): self.assertEqual(Everything.test_utf8_inout(const_str), noconst_str) + def test_filename_return(self): self.assertEqual(Everything.test_filename_return(), ['åäö', '/etc/fstab']) + def test_int_out_utf8(self): # returns g_utf8_strlen() in out argument self.assertEqual(Everything.test_int_out_utf8(''), 0) self.assertEqual(Everything.test_int_out_utf8('hello world'), 11) self.assertEqual(Everything.test_int_out_utf8('åäö'), 3) + def test_utf8_out_out(self): self.assertEqual(Everything.test_utf8_out_out(), ('first', 'second')) + + def test_utf8_out_nonconst_return(self): self.assertEqual(Everything.test_utf8_out_nonconst_return(), ('first', 'second')) def test_enum(self): @@ -356,53 +369,88 @@ class TestEverything(unittest.TestCase): # test that there are no duplicates returned self.assertEqual(len(attr_list), len(set(attr_list))) - def test_array(self): + def test_array_int_in_empty(self): self.assertEqual(Everything.test_array_int_in([]), 0) + + def test_array_int_in(self): self.assertEqual(Everything.test_array_int_in([1, 5, -2]), 4) + + def test_array_int_out(self): self.assertEqual(Everything.test_array_int_out(), [0, 1, 2, 3, 4]) + + def test_array_int_full_out(self): self.assertEqual(Everything.test_array_int_full_out(), [0, 1, 2, 3, 4]) + + def test_array_int_none_out(self): self.assertEqual(Everything.test_array_int_none_out(), [1, 2, 3, 4, 5]) + + def test_array_int_inout(self): self.assertEqual(Everything.test_array_int_inout([1, 5, 42, -8]), [6, 43, -7]) + def test_array_int_inout_empty(self): + self.assertEqual(Everything.test_array_int_inout([]), []) + + def test_array_gint8_in(self): if sys.version_info >= (3, 0): self.assertEqual(Everything.test_array_gint8_in(b'\x01\x03\x05'), 9) self.assertEqual(Everything.test_array_gint8_in([1, 3, 5, -50]), -41) + + def test_array_gint16_in(self): self.assertEqual(Everything.test_array_gint16_in([256, 257, -1000, 10000]), 9513) + + def test_array_gint32_in(self): self.assertEqual(Everything.test_array_gint32_in([30000, 1, -2]), 29999) + + def test_array_gint64_in(self): self.assertEqual(Everything.test_array_gint64_in([2 ** 33, 2 ** 34]), 2 ** 33 + 2 ** 34) + def test_array_gtype_in(self): self.assertEqual(Everything.test_array_gtype_in( [GObject.TYPE_STRING, GObject.TYPE_UINT64, GObject.TYPE_VARIANT]), '[gchararray,guint64,GVariant,]') - def test_array_fixed_size(self): + def test_array_fixed_size_int_in(self): # fixed length of 5 self.assertEqual(Everything.test_array_fixed_size_int_in([1, 2, -10, 5, 3]), 1) + + def test_array_fixed_size_int_in_error(self): self.assertRaises(ValueError, Everything.test_array_fixed_size_int_in, [1, 2, 3, 4]) self.assertRaises(ValueError, Everything.test_array_fixed_size_int_in, [1, 2, 3, 4, 5, 6]) + def test_array_fixed_size_int_out(self): self.assertEqual(Everything.test_array_fixed_size_int_out(), [0, 1, 2, 3, 4]) + + def test_array_fixed_size_int_return(self): self.assertEqual(Everything.test_array_fixed_size_int_return(), [0, 1, 2, 3, 4]) - def test_ptrarray(self): - # transfer container + def test_garray_container_return(self): + # GPtrArray transfer container result = Everything.test_garray_container_return() self.assertEqual(result, ['regress']) result = None - # transfer full + def test_garray_full_return(self): + # GPtrArray transfer full result = Everything.test_garray_full_return() self.assertEqual(result, ['regress']) result = None - def test_strv(self): + def test_strv_out(self): self.assertEqual(Everything.test_strv_out(), ['thanks', 'for', 'all', 'the', 'fish']) + + def test_strv_out_c(self): self.assertEqual(Everything.test_strv_out_c(), ['thanks', 'for', 'all', 'the', 'fish']) + + def test_strv_out_container(self): self.assertEqual(Everything.test_strv_out_container(), ['1', '2', '3']) + + def test_strv_outarg(self): self.assertEqual(Everything.test_strv_outarg(), ['1', '2', '3']) + def test_strv_in_gvalue(self): self.assertEqual(Everything.test_strv_in_gvalue(), ['one', 'two', 'three']) + def test_strv_in(self): Everything.test_strv_in(['1', '2', '3']) def test_glist(self): diff --git a/tests/test_gio.py b/tests/test_gio.py index 49e3d7f..0c773bc 100644 --- a/tests/test_gio.py +++ b/tests/test_gio.py @@ -266,3 +266,32 @@ class TestGApplication(unittest.TestCase): self.assertEqual(res, 42) self.assertSequenceEqual(app.args, ['spam']) self.assertSequenceEqual(app.local_args, ['spam', 'eggs']) + + @unittest.skipUnless(hasattr(Gio.Application, 'add_main_option'), + 'Requires newer version of GLib') + def test_add_main_option(self): + stored_options = [] + + def on_handle_local_options(app, options): + stored_options.append(options) + return 0 # Return 0 if options have been handled + + def on_activate(app): + pass + + app = Gio.Application() + app.add_main_option(long_name='string', + short_name=b's', + flags=0, + arg=GLib.OptionArg.STRING, + description='some string') + + app.connect('activate', on_activate) + app.connect('handle-local-options', on_handle_local_options) + app.run(['app', '-s', 'test string']) + + self.assertEqual(len(stored_options), 1) + options = stored_options[0] + self.assertTrue(options.contains('string')) + self.assertEqual(options.lookup_value('string').unpack(), + 'test string') diff --git a/tests/test_overrides_gtk.py b/tests/test_overrides_gtk.py index 395b157..d3351d4 100644 --- a/tests/test_overrides_gtk.py +++ b/tests/test_overrides_gtk.py @@ -1858,6 +1858,24 @@ class TestTextBuffer(unittest.TestCase): self.assertEqual(start.get_offset(), 6) self.assertEqual(end.get_offset(), 11) + def test_insert_text_signal_location_modification(self): + # Regression test for: https://bugzilla.gnome.org/show_bug.cgi?id=736175 + + def callback(buffer, location, text, length): + location.assign(buffer.get_end_iter()) + + buffer = Gtk.TextBuffer() + buffer.set_text('first line\n') + buffer.connect('insert-text', callback) + + # attempt insertion at the beginning of the buffer, the callback will + # modify the insert location to the end. + buffer.place_cursor(buffer.get_start_iter()) + buffer.insert_at_cursor('second line\n') + + self.assertEqual(buffer.get_property('text'), + 'first line\nsecond line\n') + @unittest.skipUnless(Gtk, 'Gtk not available') class TestContainer(unittest.TestCase): diff --git a/tests/test_signal.py b/tests/test_signal.py index 21d17c5..40cfb4f 100644 --- a/tests/test_signal.py +++ b/tests/test_signal.py @@ -1206,6 +1206,33 @@ class TestIntrospectedSignals(unittest.TestCase): self.assertEqual(obj.emit('sig-with-array-prop', [1, 2, GObject.G_MAXUINT]), None) self.assertEqual(obj.callback_arr, [1, 2, GObject.G_MAXUINT]) + def test_held_struct_ref(self): + held_structs = [] + + def callback(obj, struct): + # The struct held by Python will become a copy after this callback exits. + struct.some_int = 42 + struct.some_int8 = 42 + held_structs.append(struct) + + struct = Regress.TestSimpleBoxedA() + obj = Regress.TestObj() + + self.assertEqual(struct.some_int, 0) + self.assertEqual(struct.some_int8, 0) + + obj.connect('test-with-static-scope-arg', callback) + obj.emit('test-with-static-scope-arg', struct) + + # The held struct will be a copy of the modified struct. + self.assertEqual(len(held_structs), 1) + held_struct = held_structs[0] + self.assertEqual(held_struct.some_int, 42) + self.assertEqual(held_struct.some_int8, 42) + + # Boxed equality checks pointers by default. + self.assertNotEqual(struct, held_struct) + class _ConnectObjectTestBase(object): # Notes: |