Imported Upstream version 3.31.4 upstream/3.31.4
authorDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 24 Nov 2020 03:37:23 +0000 (12:37 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 24 Nov 2020 03:37:23 +0000 (12:37 +0900)
36 files changed:
.gitlab-ci.yml
.gitlab-ci/Dockerfile
.gitlab-ci/Dockerfile.gtk4
.gitlab-ci/run-docker-gtk4.sh
.gitlab-ci/run-docker.sh
.gitlab-ci/test-docker.sh
NEWS
README.rst
docs/Makefile
docs/further.rst
docs/getting_started.rst
docs/guide/api/gobject.rst
docs/guide/api/weakrefs.rst [new file with mode: 0644]
docs/guide/debug_profile.rst
docs/guide/porting.rst
docs/guide/testing.rst
docs/guide/threading.rst
docs/images/LICENSE
docs/index.rst
docs/packagingguide.rst
examples/demo/demo.py
examples/demo/demos/appwindow.py
examples/demo/demos/rotatedtext.py
gi/overrides/Gdk.py
gi/pygi-foreign-cairo.c
gi/pygi-object.c
meson.build
pygobject.doap
pygtkcompat/pygtkcompat.py
setup.py
tests/regressextra.c
tests/regressextra.h
tests/test_cairo.py
tests/test_gobject.py
tests/test_overrides_gtk.py
tests/test_pygtkcompat.py

index c7d66337c898f0c5d97609978ae71ae3c0f78492..819d19b5347d30a62cdaf16a15fa135078d10293 100644 (file)
@@ -1,4 +1,4 @@
-image: registry.gitlab.gnome.org/gnome/pygobject/main:v9
+image: registry.gitlab.gnome.org/gnome/pygobject/main:v10
 
 stages:
   - build_and_test
@@ -34,7 +34,7 @@ coverage:
     paths:
       - coverage/
   variables:
-    PYENV_VERSION: "3.6.7"
+    PYENV_VERSION: "3.6.8"
   script:
     - bash -x ./.gitlab-ci/coverage-docker.sh
 
@@ -91,24 +91,30 @@ python3.5:
 
 python3.6:
   variables:
-    PYENV_VERSION: "3.6.7"
+    PYENV_VERSION: "3.6.8"
   <<: *defaults
 
 python3.7:
   variables:
-    PYENV_VERSION: "3.7.1-debug"
+    PYENV_VERSION: "3.7.2-debug"
   <<: *defaults
 
-pypy2:
+pypy2.7:
   allow_failure: true
   variables:
-    PYENV_VERSION: "pypy2.7-6.0.0"
+    PYENV_VERSION: "pypy2.7-7.0.0"
   <<: *defaults
 
-pypy3:
+pypy3.5:
   allow_failure: true
   variables:
-    PYENV_VERSION: "pypy3.5-6.0.0"
+    PYENV_VERSION: "pypy3.5-7.0.0"
+  <<: *defaults
+
+pypy3.6:
+  allow_failure: true
+  variables:
+    PYENV_VERSION: "pypy3.6-7.0.0"
   <<: *defaults
 
 xenial-i386-py2:
@@ -122,7 +128,7 @@ xenial-i386-py2:
 
 gtk4:
   stage: build_and_test
-  image: registry.gitlab.gnome.org/gnome/pygobject/gtk4:v2
+  image: registry.gitlab.gnome.org/gnome/pygobject/gtk4:v3
   artifacts:
     paths:
       - coverage/
index 48e29609e744840ba1877f546cace85796058821..547b096f62aceac91bfc0428e993b9a14b5c058c 100644 (file)
@@ -39,11 +39,12 @@ ENV PYTHON_CONFIGURE_OPTS="--enable-shared"
 
 RUN curl -L https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer | bash
 
+RUN pyenv install pypy2.7-7.0.0
+RUN pyenv install pypy3.5-7.0.0
+RUN pyenv install pypy3.6-7.0.0
 RUN pyenv install --debug 2.7.15
 RUN pyenv install 3.5.6
-RUN pyenv install 3.6.7
-RUN pyenv install --debug 3.7.1
-RUN pyenv install pypy2.7-6.0.0
-RUN pyenv install pypy3.5-6.0.0
+RUN pyenv install 3.6.8
+RUN pyenv install --debug 3.7.2
 
 ENV PATH="/usr/lib/ccache:${PATH}"
index 6420e6681cef268a457c7b8159ec15050b4f2651..95b9aff8b9ddac8863f066533e1ba4f3725be26c 100644 (file)
@@ -1,8 +1,8 @@
-FROM registry.gitlab.gnome.org/gnome/pygobject/main:v9
+FROM registry.gitlab.gnome.org/gnome/pygobject/main:v10
 
 USER root
 
-RUN python3 -m pip install meson
+RUN python3 -m pip install meson==0.49.2
 
 ENV DEBIAN_FRONTEND noninteractive
 RUN apt-get update && apt-get install -y \
@@ -25,4 +25,4 @@ RUN git clone https://gitlab.gnome.org/GNOME/gtk.git \
     && rm -Rf gtk
 
 USER user
-ENV PYENV_VERSION 3.7.1-debug
+ENV PYENV_VERSION 3.7.2-debug
index 8bd0a16e5a2c1b6d00d7aad3ef2073deab3340a9..b333020b800d039209fe433a078cf0ba4012325c 100755 (executable)
@@ -2,7 +2,7 @@
 
 set -e
 
-TAG="registry.gitlab.gnome.org/gnome/pygobject/gtk4:v2"
+TAG="registry.gitlab.gnome.org/gnome/pygobject/gtk4:v3"
 
 sudo docker build --tag "${TAG}" --file "Dockerfile.gtk4" .
 sudo docker run --rm --security-opt label=disable \
index fe0cfc42920fbe33d4cc4ec8ebc9c13d7faa4a51..667f304d33e391f4ba1e6f1f25973aeeb2482a62 100755 (executable)
@@ -2,10 +2,10 @@
 
 set -e
 
-TAG="registry.gitlab.gnome.org/gnome/pygobject/main:v9"
+TAG="registry.gitlab.gnome.org/gnome/pygobject/main:v10"
 
 sudo docker build --build-arg HOST_USER_ID="$UID" --tag "${TAG}" \
     --file "Dockerfile" .
-sudo docker run -e PYENV_VERSION='3.7.1-debug' --rm --security-opt label=disable \
+sudo docker run -e PYENV_VERSION='3.7.2-debug' --rm --security-opt label=disable \
     --volume "$(pwd)/..:/home/user/app" --workdir "/home/user/app" \
     --tty --interactive "${TAG}" bash
index 4837d51f9b57bc2781e536994b8571e3f5d5ea93..7205f8b626c99ba84f6f4783491b00b6164ef366 100755 (executable)
@@ -30,14 +30,10 @@ export CFLAGS="-coverage -ftest-coverage -fprofile-arcs -Werror"
 /usr/bin/python3 -m pip install --user meson
 export PATH="${HOME}/.local/bin:${PATH}"
 export PKG_CONFIG_PATH="$(python -c 'import sys; sys.stdout.write(sys.prefix)')/lib/pkgconfig"
-# pycairo install under PyPy doesn't install a .pc file
-if [[ "${PYIMPL}" == "PyPy" ]]; then
-    meson _build -Dpython="$(which python)" -Dpycairo=false
-else
-    meson _build -Dpython="$(which python)"
-fi
+
+meson _build -Dpython="$(which python)"
 ninja -C _build
-xvfb-run -a meson test --timeout-multiplier 4 -C _build -v
+xvfb-run -a meson test --suite pygobject --timeout-multiplier 4 -C _build -v
 rm -Rf _build
 
 # CODE QUALITY
diff --git a/NEWS b/NEWS
index 62dd06cb4ac65802d79d73f19c928f8f7808520e..21448669a9a399ae9b6015aef27e903a1f226c77 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,11 @@
+3.31.4 - 2019-03-07
+-------------------
+
+* docs: document GObject.Object.weak_ref() :issue:`245`
+* cairo: Add cairo pattern foreign struct support :mr:`111` (:user:`Renato Florentino Garcia <renato_garcia>`)
+* cairo: Add cairo_matrix_t converter to GValue :mr:`112` (:user:`Renato Florentino Garcia <renato_garcia>`)
+
+
 3.31.3 - 2019-02-02
 -------------------
 
index b08d664dff1050cbe8b4c60541ee25a56b9b1b62..cc88c2896361cce652ebf435fd0c61c25a4620de 100644 (file)
@@ -6,9 +6,9 @@
 |
 
 **PyGObject** is a Python package which provides bindings for `GObject
-<https://developer.gnome.org/gobject/stable/>`__ based libraries such as `GTK+
+<https://developer.gnome.org/gobject/stable/>`__ based libraries such as `GTK
 <https://www.gtk.org/>`__, `GStreamer <https://gstreamer.freedesktop.org/>`__,
-`WebKitGTK+ <https://webkitgtk.org/>`__, `GLib
+`WebKitGTK <https://webkitgtk.org/>`__, `GLib
 <https://developer.gnome.org/glib/stable/>`__, `GIO
 <https://developer.gnome.org/gio/stable/>`__ and many more.
 
index 91dc99c5581c476f08b13e42fc49b5eec8c8f36b..55525c52254a31558a58aecd2c0b0950c014edf2 100644 (file)
@@ -6,7 +6,7 @@ all: _build
 images/%.svg: images/%.dia
        dia $< --export=$@ --filter=dia-svg
 
-_build: Makefile *.rst devguide/*.rst guide/*.rst conf.py images/*.png $(DIA_SVGS) ../README.rst ../NEWS
+_build: Makefile *.rst devguide/*.rst guide/*/*.rst guide/*.rst conf.py images/*.png $(DIA_SVGS) ../README.rst ../NEWS
        sphinx-build -b html . _build
 
 linkcheck:
index 832cf45ef287f866395dd538fddc5e37a8d0a59f..69223f50f49a1e1aa5a5d75c2383684057249fca 100644 (file)
@@ -2,8 +2,8 @@
 Further Resources
 =================
 
-`Python GTK+ 3 Tutorial <https://python-gtk-3-tutorial.readthedocs.io>`__
-    Many examples showing how to build an application using PyGObject and GTK+.
+`Python GTK 3 Tutorial <https://python-gtk-3-tutorial.readthedocs.io>`__
+    Many examples showing how to build an application using PyGObject and GTK.
 
 `Python GI API Reference <https://lazka.github.io/pgi-docs>`__
     Auto generated API documentation for many libraries accessible through
index ff9e657bfb4ea43c8df350491adc02ac2d08ec75..5e153f46d7dd82b7ec600c374e8f938869c63b11 100644 (file)
@@ -6,7 +6,7 @@
 Getting Started
 ===============
 
-To get things started we will try to run a very simple `GTK+
+To get things started we will try to run a very simple `GTK
 <https://www.gtk.org/>`_ based GUI application using the :doc:`PyGObject <index>` provided
 Python bindings. First create a small Python script called ``hello.py`` with
 the following content and save it somewhere:
@@ -22,7 +22,7 @@ the following content and save it somewhere:
     window.connect("destroy", Gtk.main_quit)
     Gtk.main()
 
-Before we can run the example application we need to install PyGObject, GTK+
+Before we can run the example application we need to install PyGObject, GTK
 and their dependencies. Follow the instructions for your platform below.
 
 ======================================================= ==================================================== ==========================================================
@@ -30,6 +30,11 @@ and their dependencies. Follow the instructions for your platform below.
 |windows-logo| :ref:`Windows <windows-getting-started>` |macosx-logo| :ref:`macOS <macosx-getting-started>`  |opensuse-logo| :ref:`openSUSE <opensuse-getting-started>`
 ======================================================= ==================================================== ==========================================================
 
+After running the example application have a look at the "`Python GTK 3
+Tutorial <https://python-gtk-3-tutorial.readthedocs.io>`__" for more examples
+on how to create GTK apps and the "`PyGObject API Reference
+<https://lazka.github.io/pgi-docs>`__" for API documentation for all supported
+libraries.
 
 .. _windows-getting-started:
 
@@ -41,7 +46,7 @@ and their dependencies. Follow the instructions for your platform below.
 #) Run ``C:\msys64\mingw32.exe`` - a terminal window should pop up
 #) Execute ``pacman -Suy``
 #) Execute ``pacman -S mingw-w64-i686-gtk3 mingw-w64-i686-python3-gobject``
-#) To test that GTK+3 is working you can run ``gtk3-demo``
+#) To test that GTK 3 is working you can run ``gtk3-demo``
 #) Copy the ``hello.py`` script you created to ``C:\msys64\home\<username>``
 #) In the mingw32 terminal execute ``python3 hello.py`` - a window should appear.
 
index 08c124b9634c25e1f6ffc7d63a2135293ca1eb8d..63aa051746d12d588f37d290321c6be8f386a56d 100644 (file)
@@ -22,6 +22,7 @@ In addition :obj:`GObject.Object` has support for :any:`signals <signals>` and
 
     signals
     properties
+    weakrefs
 
 
 Examples
diff --git a/docs/guide/api/weakrefs.rst b/docs/guide/api/weakrefs.rst
new file mode 100644 (file)
index 0000000..6ab9f28
--- /dev/null
@@ -0,0 +1,26 @@
+Weak References
+===============
+
+While Python has a builtin ``weakref`` module it only allows one to create
+weak references to Python objects, but with PyGObject the Python object
+"wrapping" a GObject and the GObject itself might not have the same lifetime.
+The wrapper can get garbage collected and a new wrapper created again at a
+later point.
+
+If you want to get notified when the underlying GObject gets finalized use
+``GObject.Object.weak_ref``:
+
+
+.. method:: GObject.Object.weak_ref(callback, *user_data)
+
+    Registers a callback to be called when the underlying GObject gets
+    finalized. The callback will receive the give `user_data`.
+
+    To unregister the callback call the ``unref()`` method of the returned
+    GObjectWeakRef object.
+
+    :param callback: A callback which will be called when the object
+        is finalized
+    :type callback: :func:`callable`
+    :param user_data: User data that will be passed to the callback
+    :returns: GObjectWeakRef
index 628bab1770c6812e326e4a244b38ca2145793d96..6b43a80b7842ffaed2ef8fb619077e7b19914b42 100644 (file)
@@ -17,7 +17,7 @@ recommended.
     jhbuild shell
     GOBJECT_DEBUG=instance-count GTK_DEBUG=interactive ./quodlibet.py
 
-* In the GTK+ Inspector switch to the "Statistics" tab
+* In the GTK Inspector switch to the "Statistics" tab
 * Sort by "Cumulative" and do the action which you suspect does leak or where
   you want to make sure it doesn't repeatedly. Like for example opening
   and closing a window or switching between media files to present.
index 462ed856c6260736eee366c214e7af79cd2a5d69..59107bfa77de18e3a3e11f58913e4970f544249a 100644 (file)
@@ -17,12 +17,12 @@ have to switch everything at once.
 Static Bindings Library Differences
 -----------------------------------
 
-**pygtk** supported GTK+ 2.0 and Python 2 only. PyGObject supports GTK+ >=3.0
-and Python 2/3. If you port away from pygtk you also have to move to GTK+ 3.0
+**pygtk** supported GTK 2.0 and Python 2 only. PyGObject supports GTK >=3.0
+and Python 2/3. If you port away from pygtk you also have to move to GTK 3.0
 at the same time. **pygtkcompat** described below can help you with that
 transition.
 
-**pygst** supports GStreamer 0.10 and Python 2 only. Like with GTK+ you have
+**pygst** supports GStreamer 0.10 and Python 2 only. Like with GTK you have
 to move to PyGObject and GStreamer 1.0 at the same time.
 
 **pygobject 2** supports glib 2.0 and Python 2. The new bindings also support
@@ -50,13 +50,13 @@ you have to make in the beginning, but nothing more.
 4) Continue to the next module...
 
 
-Porting Tips for GTK+
----------------------
+Porting Tips for GTK
+--------------------
 
-While PyGObject theoretically supports GTK+ 2.0 it is not really usable. It
-will be easier to port to GTK+ 3.0 right away.
+While PyGObject theoretically supports GTK 2.0 it is not really usable. It
+will be easier to port to GTK 3.0 right away.
 
-For some general advice regarding the migration from GTK+ 2.0 to 3.0 see the
+For some general advice regarding the migration from GTK 2.0 to 3.0 see the
 `offical migration guide
 <https://developer.gnome.org/gtk3/stable/gtk-migrating-2-to-3.html>`__. If you
 need to know how a C symbol is exposed in Python have a look at the `symbol
index 6a7c6632d1218fa6af9ee41eca2378ff0b339ea0..cae4fc7f3b4554314898851021db00bf19c256a0 100644 (file)
@@ -4,7 +4,7 @@
 Testing and Continuous Integration
 ==================================
 
-To get automated tests of GTK+ code running on a headless server use Xvfb
+To get automated tests of GTK code running on a headless server use Xvfb
 (virtual framebuffer X server). It provides the ``xvfb-run -a`` command which
 creates a temporary X server without the need for any real display hardware.
 
@@ -16,8 +16,8 @@ creates a temporary X server without the need for any real display hardware.
 Continuous Integration using Travis CI / CircleCI
 -------------------------------------------------
 
-Travis CI uses a rather old Ubuntu and thus the supported GTK+ is at 3.10 and
-PyGObject is at 3.12. If that's enough for you then have a look at our Travis
+Travis CI uses a rather old Ubuntu and thus the supported GTK is at 3.18 and
+PyGObject is at 3.20. If that's enough for you then have a look at our Travis
 CI example project:
 
     |github-logo| https://github.com/pygobject/pygobject-travis-ci-examples
@@ -25,7 +25,7 @@ CI example project:
     .. image:: https://travis-ci.org/pygobject/pygobject-travis-ci-examples.svg?branch=master
         :target: https://travis-ci.org/pygobject/pygobject-travis-ci-examples
 
-To get newer PyGObject, GTK+, etc. working on `Travis CI
+To get newer PyGObject, GTK, etc. working on `Travis CI
 <https://travis-ci.org>`__ or `CircleCI <https://circleci.com>`__ you can use
 Docker with an image of your choosing. Have a look at our Docker example
 project which runs tests on various Debian, Ubuntu and Fedora versions:
index c1bac32ff3690756641a87a2c6bb01f040c96d67..fea26d18bbed662051993372c97916cbb931232f 100644 (file)
@@ -17,7 +17,7 @@ Such an operation might be:
 
 The following examples show
 
-* how Python threads, running in parallel to GTK+, can interact with the UI
+* how Python threads, running in parallel to GTK, can interact with the UI
 * how to use and control asynchronous I/O operations in glib
 
 
@@ -66,7 +66,7 @@ while still showing feedback on the progress in a window.
 
 The example shows a simple window containing a progress bar. After everything
 is set up it constructs a Python thread, passes it a function to execute,
-starts the thread and the GTK+ main loop. After the main loop is started it is
+starts the thread and the GTK main loop. After the main loop is started it is
 possible to see the window and interact with it.
 
 In the background ``example_target()`` gets executed and calls
@@ -74,14 +74,14 @@ In the background ``example_target()`` gets executed and calls
 :func:`time.sleep` represents the blocking operation. :func:`GLib.idle_add`
 takes the ``update_progess()`` function and arguments that will get passed to
 the function and asks the main loop to schedule its execution in the main
-thread. This is needed because GTK+ isn't thread safe; only one thread, the
-main thread, is allowed to call GTK+ code at all times.
+thread. This is needed because GTK isn't thread safe; only one thread, the
+main thread, is allowed to call GTK code at all times.
 
 
 Threads: FAQ
 ------------
 
-* I'm porting code from pygtk (GTK+ 2) to PyGObject (GTK+ 3). Has anything 
+* I'm porting code from pygtk (GTK 2) to PyGObject (GTK 3). Has anything
   changed regarding threads?
 
   Short answer: No.
@@ -96,7 +96,7 @@ Threads: FAQ
 
   * Remove any :func:`Gdk.threads_init()`, :func:`Gdk.threads_enter` and  
     :func:`Gdk.threads_leave` calls. In case they get executed in a thread,
-    move the GTK+ code into its own function and schedule it using
+    move the GTK code into its own function and schedule it using
     :func:`GLib.idle_add`. Be aware that the newly created function will be
     executed some time later, so other stuff can happen in between.
 
@@ -110,12 +110,12 @@ Threads: FAQ
   In GStreamer, for example, some signals can be called from a different
   thread, see the respective signal documentation for when this is the case.
   In case you connect to such a signal you have to make sure to not call any
-  GTK+ code or use :func:`GLib.idle_add` accordingly.
+  GTK code or use :func:`GLib.idle_add` accordingly.
 
-* What if I need to call GTK+ code in signal handlers emitted from a thread?
+* What if I need to call GTK code in signal handlers emitted from a thread?
 
   In case you have a signal that is emitted from another thread and you need
-  to call GTK+ code during and not after signal handling, you can push the
+  to call GTK code during and not after signal handling, you can push the
   operation with an :class:`threading.Event` object to the main loop and wait
   in the signal handler until the operation gets scheduled and the result is
   available. Be aware that if the signal is emitted from the main loop this
index 0fbbdbf7baea1447de5c635a76e318e2146f491b..7572a310fffba5937a8931ba7128f54e7990b077 100644 (file)
@@ -1,3 +1,3 @@
-pygobject.svg and pygobject-small.svg are based on the GTK+ logo, created by
+pygobject.svg and pygobject-small.svg are based on the GTK logo, created by
 Andreas Nilsson, licensed under CC BY-SA 3.0. For more info see
 https://commons.wikimedia.org/wiki/File:GTK%2B_logo.svg
index 7b383c1c113a80eabdcde28013bcdb31d96dd56e..e000590380ec2c547045203d9769b7cfc2490edb 100644 (file)
@@ -29,9 +29,9 @@
     :end-before: ----
 
 If you want to write a Python application for `GNOME
-<https://www.gnome.org/>`__ or a Python GUI application using GTK+, then
+<https://www.gnome.org/>`__ or a Python GUI application using GTK, then
 PyGObject is the way to go. For more information on specific libraries check
-out the "`Python GTK+ 3 Tutorial
+out the "`Python GTK 3 Tutorial
 <https://python-gtk-3-tutorial.readthedocs.io>`__" and the "`Python GI API
 Reference <https://lazka.github.io/pgi-docs>`__".
 
index 7d6fafa9db3d8e861f1c6391c07cd3790591175f..eae5d75263c045fa8f41b2c7e43f44e4ebfd96bd 100644 (file)
@@ -40,6 +40,6 @@ Build dependencies:
 Test Suite dependencies:
 
     * The runtime dependencies
-    * GTK+ 3 (optional)
+    * GTK 3 (optional)
     * pango (optional)
     * pycairo (optional)
index d67935d949a3bdf611af5a1d19e860aecdecbfff..e06fd99d4819b0c7ee7dc257082ba90983c8f156 100755 (executable)
@@ -130,7 +130,7 @@ class GtkDemoApp(Gtk.Application):
 
     def on_activate(self, app):
         self.window = Gtk.ApplicationWindow.new(self)
-        self.window.set_title('PyGObject GTK+ Code Demos')
+        self.window.set_title('PyGObject GTK Code Demos')
         self.window.set_default_size(600, 400)
         self.setup_default_icon()
 
index 893ecc0fdf7df82c82656bd4dc05c7238dd2425e..edac46779d7239abbedda278df9b78eeca2c9678 100644 (file)
@@ -124,7 +124,7 @@ Boston, MA 02111-1307, USA.
     transparent = pixbuf.add_alpha(True, 0xff, 0xff, 0xff)
 
     about = Gtk.AboutDialog(parent=window,
-                            program_name='GTK+ Code Demos',
+                            program_name='GTK Code Demos',
                             version='0.1',
                             copyright='(C) 2010 The PyGI Team',
                             license=license,
@@ -133,7 +133,7 @@ Boston, MA 02111-1307, USA.
                             authors=authors,
                             documenters=documentors,
                             logo=transparent,
-                            title='About GTK+ Code Demos')
+                            title='About GTK Code Demos')
 
     about.connect('response', widget_destroy)
     about.show()
@@ -172,7 +172,7 @@ action_entries = (
      about_cb),
     ("Logo", "demo-gtk-logo",                   # name, stock id
      None, None,                                # label, accelerator
-     "GTK+",                                    # tooltip
+     "GTK",                                     # tooltip
      activate_action),
 )
 
index 806c1493977aa1777e553c2459ab4c59d6b8abee..8e4c2b7362ccfa087ec941dce85f47366874d80f 100644 (file)
@@ -32,7 +32,7 @@ import cairo
 import math
 
 
-UTF8_TEXT = u"I â™¥ GTK+"
+UTF8_TEXT = u"I â™¥ GTK"
 HEART = u"♥"
 BYTES_TEXT = UTF8_TEXT.encode("utf-8")
 BYTES_HEART = HEART.encode("utf-8")
index 5aea65ff0633c4ff6369e9a80c4c6a31fbfb386c..d77748e379c335a709e08859d1e0610f4761d448 100644 (file)
@@ -42,7 +42,7 @@ except (ValueError, ImportError):
     pass
 
 if GDK2 or GDK3:
-    # Gdk.Color was deprecated since 3.14 and dropped in Gtk+-4.0
+    # Gdk.Color was deprecated since 3.14 and dropped in Gtk-4.0
     class Color(Gdk.Color):
         MAX_VALUE = 65535
 
@@ -84,7 +84,7 @@ if GDK2 or GDK3:
     __all__.append('Color')
 
 if GDK3:
-    # Introduced since Gtk+-3.0
+    # Introduced since Gtk-3.0
     class RGBA(Gdk.RGBA):
         def __init__(self, red=1.0, green=1.0, blue=1.0, alpha=1.0):
             Gdk.RGBA.__init__(self)
@@ -139,7 +139,7 @@ if GDK2:
     Rectangle = override(Rectangle)
     __all__.append('Rectangle')
 elif GDK3:
-    # Newer GTK+/gobject-introspection (3.17.x) include GdkRectangle in the
+    # 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'):
@@ -361,7 +361,7 @@ if GDK2 or GDK3:
     Cursor = override(Cursor)
     __all__.append('Cursor')
 
-    # Gdk.Color was deprecated since 3.14 and dropped in Gtk+-4.0
+    # Gdk.Color was deprecated since 3.14 and dropped in Gtk-4.0
     color_parse = strip_boolean_result(Gdk.color_parse)
     __all__.append('color_parse')
 
index c99847bfa51ff6d3637cfa3dc181f64bca6db7c2..399fe75ef2991ca2425ec13cd6a4a29166aee60a 100644 (file)
@@ -409,6 +409,53 @@ cairo_scaled_font_from_gvalue (const GValue *value)
  * cairo_pattern_t marshaling
  */
 
+static PyObject *
+cairo_pattern_to_arg (PyObject        *value,
+                      GIInterfaceInfo *interface_info,
+                      GITransfer       transfer,
+                      GIArgument      *arg)
+{
+    cairo_pattern_t *pattern;
+
+    if (!PyObject_TypeCheck (value, &PycairoPattern_Type)) {
+        PyErr_SetString (PyExc_TypeError, "Expected cairo.Pattern");
+        return NULL;
+    }
+
+    pattern = ((PycairoPattern*) value)->pattern;
+    if (!pattern) {
+        PyErr_SetString (PyExc_ValueError, "Pattern instance wrapping a NULL pattern");
+        return NULL;
+    }
+
+    if (transfer != GI_TRANSFER_NOTHING)
+        pattern = cairo_pattern_reference (pattern);
+
+    arg->v_pointer = pattern;
+    Py_RETURN_NONE;
+}
+
+static PyObject *
+cairo_pattern_from_arg (GIInterfaceInfo *interface_info,
+                        GITransfer       transfer,
+                        gpointer         data)
+{
+    cairo_pattern_t *pattern = (cairo_pattern_t*) data;
+
+    if (transfer == GI_TRANSFER_NOTHING)
+        pattern = cairo_pattern_reference (pattern);
+
+    return PycairoPattern_FromPattern (pattern, NULL);
+}
+
+static PyObject *
+cairo_pattern_release (GIBaseInfo *base_info,
+                       gpointer    struct_)
+{
+    cairo_pattern_destroy ( (cairo_pattern_t*) struct_);
+    Py_RETURN_NONE;
+}
+
 static int
 cairo_pattern_to_gvalue (GValue *value, PyObject *obj)
 {
@@ -536,6 +583,36 @@ cairo_matrix_release (GIBaseInfo *base_info,
     Py_RETURN_NONE;
 }
 
+static int
+cairo_matrix_to_gvalue (GValue *value, PyObject *obj)
+{
+    cairo_matrix_t *matrix;
+
+    if (!PyObject_TypeCheck (obj, &PycairoMatrix_Type)) {
+        PyErr_SetString (PyExc_TypeError, "Expected cairo.Matrix");
+        return -1;
+    }
+
+    matrix = &(( (PycairoMatrix*) obj)->matrix);
+    if (!matrix) {
+        return -1;
+    }
+
+    g_value_set_boxed (value, matrix);
+    return 0;
+}
+
+static PyObject *
+cairo_matrix_from_gvalue (const GValue *value)
+{
+    cairo_matrix_t *matrix = g_value_get_boxed(value);
+    if (!matrix) {
+        Py_RETURN_NONE;
+    }
+
+    return PycairoMatrix_FromMatrix (matrix);
+}
+
 static PyMethodDef _gi_cairo_functions[] = { {0,} };
 PYGLIB_MODULE_START(_gi_cairo, "_gi_cairo")
 {
@@ -585,12 +662,22 @@ PYGLIB_MODULE_START(_gi_cairo, "_gi_cairo")
                                   cairo_font_options_from_arg,
                                   cairo_font_options_release);
 
+    pygi_register_foreign_struct ("cairo",
+                                  "Pattern",
+                                  cairo_pattern_to_arg,
+                                  cairo_pattern_from_arg,
+                                  cairo_pattern_release);
+
     pygi_register_foreign_struct ("cairo",
                                   "Region",
                                   cairo_region_to_arg,
                                   cairo_region_from_arg,
                                   cairo_region_release);
 
+    pyg_register_gtype_custom (CAIRO_GOBJECT_TYPE_MATRIX,
+                               cairo_matrix_from_gvalue,
+                               cairo_matrix_to_gvalue);
+
     pyg_register_gtype_custom (CAIRO_GOBJECT_TYPE_CONTEXT,
                                cairo_context_from_gvalue,
                                cairo_context_to_gvalue);
index bd5e08595455b3c87dc17c364a302fe926a40ed0..79170e3fab41bb58a768b237b1ae88827134e3ce 100644 (file)
@@ -252,7 +252,7 @@ pygi_arg_gobject_to_py_called_from_c (GIArgument *arg,
     PyObject *object;
 
     /* HACK:
-     * The following hack is to work around GTK+ sending signals which
+     * The following hack is to work around GTK sending signals which
      * contain floating widgets in them. This assumes control of how
      * references are added by the PyGObject wrapper and avoids the sink
      * behavior by explicitly passing GI_TRANSFER_EVERYTHING as the transfer
index 26249c280fc1619ef25463bbd39b0540e8095be1..c8551de62d740667ebe625b75b3858d3d0563086 100644 (file)
@@ -1,5 +1,5 @@
 project('pygobject', 'c',
-  version : '3.31.3',
+  version : '3.31.4',
   meson_version : '>= 0.46.0',
   default_options : [ 'warning_level=1',
                       'buildtype=debugoptimized'])
index cca2a48890b6f208f83e7aee57c30a1109a8ac9a..4d12c73c52e1dc215b4e65bb223c888447aaf312 100644 (file)
@@ -7,7 +7,7 @@
   <name xml:lang="en">PyGObject</name>
   <shortdesc xml:lang="en">Python bindings for GObject Introspection</shortdesc>
   <description>
-GObject is a object system used by GTK+,  GStreamer and other libraries.
+GObject is a object system used by GTK, GStreamer and other libraries.
 
 PyGObject provides a convenient wrapper for use in Python programs when accessing GObject libraries.
 
index 85eb35b28f47ba47e63325b2a5a0a7267e29b781..c9711c6895c1066258b10e303e07961fef4d64a6 100644 (file)
@@ -199,10 +199,7 @@ def enable_gtk(version='3.0'):
     _patch(Gdk, "PixbufLoader", GdkPixbuf.PixbufLoader.new_with_type)
     _patch(Gdk, "pixbuf_new_from_data", GdkPixbuf.Pixbuf.new_from_data)
     _patch(Gdk, "pixbuf_new_from_file", GdkPixbuf.Pixbuf.new_from_file)
-    try:
-        _patch(Gdk, "pixbuf_new_from_file_at_scale", GdkPixbuf.Pixbuf.new_from_file_at_scale)
-    except AttributeError:
-        pass
+    _patch(Gdk, "pixbuf_new_from_file_at_scale", GdkPixbuf.Pixbuf.new_from_file_at_scale)
     _patch(Gdk, "pixbuf_new_from_file_at_size", GdkPixbuf.Pixbuf.new_from_file_at_size)
     _patch(Gdk, "pixbuf_new_from_inline", GdkPixbuf.Pixbuf.new_from_inline)
     _patch(Gdk, "pixbuf_new_from_stream", GdkPixbuf.Pixbuf.new_from_stream)
@@ -230,20 +227,6 @@ def enable_gtk(version='3.0'):
 
     _patch(Gdk, "pixbuf_get_formats", get_formats)
 
-    orig_get_frame_extents = Gdk.Window.get_frame_extents
-
-    def get_frame_extents(window):
-        try:
-            try:
-                rect = Gdk.Rectangle(0, 0, 0, 0)
-            except TypeError:
-                rect = Gdk.Rectangle()
-            orig_get_frame_extents(window, rect)
-        except TypeError:
-            rect = orig_get_frame_extents(window)
-        return rect
-    _patch(Gdk.Window, "get_frame_extents", get_frame_extents)
-
     orig_get_origin = Gdk.Window.get_origin
 
     def get_origin(self):
@@ -412,10 +395,7 @@ def enable_gtk(version='3.0'):
     _patch(Gtk, "image_new_from_file", Gtk.Image.new_from_file)
     _patch(Gtk, "settings_get_default", Gtk.Settings.get_default)
     _patch(Gtk, "window_set_default_icon", Gtk.Window.set_default_icon)
-    try:
-        _patch(Gtk, "clipboard_get", Gtk.Clipboard.get)
-    except AttributeError:
-        pass
+    _patch(Gtk, "clipboard_get", Gtk.Clipboard.get)
 
     # AccelGroup
     _patch(Gtk.AccelGroup, "connect_group", Gtk.AccelGroup.connect)
index d48271036924b1196bee7079ef54192aa616ae55..861a1db59619f18209b088918fea4a56a4b9f107 100755 (executable)
--- a/setup.py
+++ b/setup.py
@@ -41,7 +41,7 @@ from distutils import dir_util, log
 from distutils.spawn import find_executable
 
 
-PYGOBJECT_VERSION = "3.31.3"
+PYGOBJECT_VERSION = "3.31.4"
 GLIB_VERSION_REQUIRED = "2.48.0"
 GI_VERSION_REQUIRED = "1.46.0"
 PYCAIRO_VERSION_REQUIRED = "1.11.1"
index a1426782b8c78a0436e806158501cf050e001cc0..d6af90bf1a17e711801e4c473fa19efdbbcb2967 100644 (file)
@@ -173,6 +173,58 @@ regress_test_cairo_path_full_in_full_return (cairo_path_t *path)
     return path;
 }
 
+/**
+ * regress_test_cairo_pattern_full_in:
+ * @pattern: (transfer full):
+ */
+void
+regress_test_cairo_pattern_full_in (cairo_pattern_t *pattern)
+{
+    cairo_pattern_destroy (pattern);
+}
+
+/**
+ * regress_test_cairo_pattern_none_in:
+ * @pattern: (transfer none):
+ */
+void
+regress_test_cairo_pattern_none_in (cairo_pattern_t *pattern)
+{
+    cairo_t *cr = regress_test_cairo_context_full_return ();
+    cairo_set_source (cr, pattern);
+    g_assert (cairo_status (cr) == CAIRO_STATUS_SUCCESS);
+    cairo_destroy (cr);
+}
+
+/**
+ * regress_test_cairo_pattern_none_return:
+ *
+ * Returns: (transfer none):
+ */
+cairo_pattern_t*
+regress_test_cairo_pattern_none_return (void)
+{
+    static cairo_pattern_t *pattern;
+
+    if (pattern == NULL) {
+        pattern = cairo_pattern_create_rgb(0.1, 0.2, 0.3);
+    }
+
+    return pattern;
+}
+
+/**
+ * regress_test_cairo_pattern_full_return:
+ *
+ * Returns: (transfer full):
+ */
+cairo_pattern_t *
+regress_test_cairo_pattern_full_return (void)
+{
+    cairo_pattern_t *pattern = cairo_pattern_create_rgb(0.5, 0.6, 0.7);
+    return pattern;
+}
+
 /**
  * regress_test_cairo_region_full_in:
  * @region: (transfer full):
index 6f5d2f564defaad09e8c893df53bd5ad5cc086aa..0b40ab0498557a418b815cd32cc4e5bcc0ac19e8 100644 (file)
@@ -34,6 +34,14 @@ void regress_test_cairo_path_none_in (cairo_path_t *path);
 _GI_TEST_EXTERN
 cairo_path_t * regress_test_cairo_path_full_in_full_return (cairo_path_t *path);
 _GI_TEST_EXTERN
+void regress_test_cairo_pattern_full_in (cairo_pattern_t *pattern);
+_GI_TEST_EXTERN
+void regress_test_cairo_pattern_none_in (cairo_pattern_t *pattern);
+_GI_TEST_EXTERN
+cairo_pattern_t* regress_test_cairo_pattern_none_return (void);
+_GI_TEST_EXTERN
+cairo_pattern_t * regress_test_cairo_pattern_full_return (void);
+_GI_TEST_EXTERN
 cairo_font_options_t *regress_test_cairo_font_options_full_return (void);
 _GI_TEST_EXTERN
 cairo_font_options_t *regress_test_cairo_font_options_none_return (void);
index f4d0d7c9df55df20b2a05c9b737d8d15af663b9f..37a6ac3863a35c6b646226f17d2389a7aae70578 100644 (file)
@@ -34,12 +34,14 @@ class Test(unittest.TestCase):
     def test_gvalue_converters(self):
         surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10)
         context = cairo.Context(surface)
+        matrix = cairo.Matrix()
         objects = {
             'CairoContext': context,
             'CairoSurface': surface,
             'CairoFontFace': context.get_font_face(),
             'CairoScaledFont': context.get_scaled_font(),
             'CairoPattern': context.get_source(),
+            'CairoMatrix': matrix,
         }
         for type_name, cairo_obj in objects.items():
             gtype = GObject.type_from_name(type_name)
@@ -115,6 +117,27 @@ class Test(unittest.TestCase):
         options = cairo.FontOptions()
         Regress.test_cairo_font_options_none_in(options)
 
+    def test_cairo_pattern_full_in(self):
+        pattern = cairo.SolidPattern(1, 1, 1, 1)
+        Regress.test_cairo_pattern_full_in(pattern)
+
+        with pytest.raises(TypeError):
+            Regress.test_cairo_pattern_full_in(object())
+
+    def test_cairo_pattern_none_in(self):
+        pattern = cairo.SolidPattern(1, 1, 1, 1)
+        Regress.test_cairo_pattern_none_in(pattern)
+
+    def test_cairo_pattern_full_return(self):
+        pattern = Regress.test_cairo_pattern_full_return()
+        self.assertTrue(isinstance(pattern, cairo.Pattern))
+        self.assertTrue(isinstance(pattern, cairo.SolidPattern))
+
+    def test_cairo_pattern_none_return(self):
+        pattern = Regress.test_cairo_pattern_none_return()
+        self.assertTrue(isinstance(pattern, cairo.Pattern))
+        self.assertTrue(isinstance(pattern, cairo.SolidPattern))
+
     def test_cairo_region_full_in(self):
         region = cairo.Region()
         Regress.test_cairo_region_full_in(region)
index 7816510caef8778632efd630a7b56dd507bf2049..bba12cb7210838791172f86d50cd9dd0f74bab17 100644 (file)
@@ -6,6 +6,8 @@ import sys
 import gc
 import unittest
 import warnings
+import weakref
+import platform
 
 import pytest
 
@@ -18,6 +20,53 @@ import testhelper
 from .helper import capture_glib_deprecation_warnings
 
 
+@pytest.mark.skipif(platform.python_implementation() == "PyPy", reason="crashes")
+def test_gobject_weak_ref():
+
+    called = []
+
+    def callback(*args):
+        called.extend(args)
+
+    # object gets finalized
+    obj = GObject.Object()
+    obj.weak_ref(callback, 1)
+    del obj
+    gc.collect()
+    gc.collect()
+    assert called == [1]
+    del called[:]
+
+    # wrapper gets finalized first
+    obj = GObject.Object()
+    pyref = weakref.ref(obj, lambda x: callback(-2))
+    value = GObject.Value(GObject.Object, obj)
+    ref = obj.weak_ref(callback, 2)
+    del obj
+    gc.collect()
+    assert called == [-2]
+    del pyref
+    value.unset()
+    gc.collect()
+    assert called == [-2, 2]
+    del called[:]
+
+    # weakref gets unregistered first
+    obj = GObject.Object()
+    ref = obj.weak_ref(callback, 3)
+    ref.unref()
+    del obj
+    gc.collect()
+    assert not called
+
+    # weakref gets GCed
+    obj = GObject.Object()
+    obj.weak_ref(callback, 4)
+    gc.collect()
+    del obj
+    assert called == [4]
+
+
 class TestGObjectAPI(unittest.TestCase):
 
     def test_call_method_uninitialized_instance(self):
index fe98051ca01dba10e4402b448b271f731950aea4..627d5760d6af22fded9cdf4193ec5172358a3891 100644 (file)
@@ -532,7 +532,7 @@ class TestGtk(unittest.TestCase):
         self.assertTrue(isinstance(button, Gtk.Widget))
 
         if Gtk_version != "4.0":
-            # Using stock items causes hard warning in devel versions of GTK+.
+            # Using stock items causes hard warning in devel versions of GTK.
             with capture_glib_warnings(allow_warnings=True):
                 button = Gtk.Button.new_from_stock(Gtk.STOCK_CLOSE)
 
@@ -771,7 +771,7 @@ class TestGtk(unittest.TestCase):
     def test_toolbutton(self):
         # PyGTK compat
 
-        # Using stock items causes hard warning in devel versions of GTK+.
+        # Using stock items causes hard warning in devel versions of GTK.
         with capture_glib_warnings(allow_warnings=True):
             button = Gtk.ToolButton()
             self.assertEqual(button.props.stock_id, None)
index da220b59fb4da11f8ffe809d6c623ca2bc78c29e..3e6a69eacb1c69d233111473d26f7afce34333d7 100644 (file)
@@ -6,6 +6,8 @@ from __future__ import absolute_import
 import unittest
 import base64
 
+import pytest
+import gi
 import pygtkcompat
 from pygtkcompat.pygtkcompat import _disable_all as disable_all
 
@@ -114,6 +116,106 @@ class TestGTKCompat(unittest.TestCase):
     def tearDown(self):
         disable_all()
 
+    def test_window_get_frame_extents(self):
+        import gtk
+        import gtk.gdk
+        w = gtk.Window()
+        w.realize()
+        rect = w.window.get_frame_extents()
+        assert isinstance(rect, gtk.gdk.Rectangle)
+
+    def test_window_get_geometry(self):
+        import gtk
+        w = gtk.Window()
+        w.realize()
+        with capture_gi_deprecation_warnings():
+            geo = w.window.get_geometry()
+        assert isinstance(geo, tuple)
+        assert len(geo) == 5
+
+    def test_action_set_tool_item_type(self):
+        import gtk
+        with pytest.warns(gi.PyGIDeprecationWarning):
+            gtk.Action().set_tool_item_type(gtk.Action)
+
+    def test_treeviewcolumn_pack(self):
+        import gtk
+        col = gtk.TreeViewColumn()
+        col.pack_end(gtk.CellRendererText())
+        col.pack_start(gtk.CellRendererText())
+
+    def test_cell_layout_pack(self):
+        import gtk
+        layout = gtk.EntryCompletion()
+        layout.pack_end(gtk.CellRendererText())
+        layout.pack_start(gtk.CellRendererText())
+
+    def test_cell_layout_cell_data_func(self):
+        import gtk
+
+        def func(*args):
+            pass
+
+        layout = gtk.EntryCompletion()
+        render = gtk.CellRendererText()
+        layout.set_cell_data_func(render, func)
+
+    def test_combo_row_separator_func(self):
+        import gtk
+
+        def func(*args):
+            pass
+
+        combo = gtk.ComboBox()
+        combo.set_row_separator_func(func)
+
+    def test_container_install_child_property(self):
+        import gtk
+
+        box = gtk.Box()
+        with pytest.warns(gi.PyGIDeprecationWarning):
+            box.install_child_property(0, None)
+
+    def test_combo_box_new_text(self):
+        import gtk
+
+        combo = gtk.combo_box_new_text()
+        assert isinstance(combo, gtk.ComboBox)
+        combo.append_text("foo")
+
+    def test_scale(self):
+        import gtk
+
+        adjustment = gtk.Adjustment()
+        assert gtk.HScale()
+        assert gtk.HScale(adjustment).get_adjustment() == adjustment
+        adjustment = gtk.Adjustment()
+        assert gtk.VScale()
+        assert gtk.VScale(adjustment).get_adjustment() == adjustment
+
+    def test_stock_add(self):
+        import gtk
+
+        gtk.stock_add([])
+
+    def test_text_view_scroll_to_mark(self):
+        import gtk
+
+        view = gtk.TextView()
+        buf = view.get_buffer()
+        mark = gtk.TextMark(name="foo")
+        buf.add_mark(mark, buf.get_end_iter())
+        view.scroll_to_mark(mark, 0.0)
+
+    def test_window_set_geometry_hints(self):
+        import gtk
+
+        w = gtk.Window()
+        w.set_geometry_hints(None, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+        w.set_geometry_hints(None, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1)
+        with pytest.raises(TypeError):
+            w.set_geometry_hints(None, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
+
     def test_buttons(self):
         import gtk.gdk
         self.assertEqual(gtk.gdk._2BUTTON_PRESS, 5)