Imported Upstream version 3.42.0 upstream/3.42.0
authorDongHun Kwak <dh0128.kwak@samsung.com>
Thu, 14 Jul 2022 02:08:00 +0000 (11:08 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Thu, 14 Jul 2022 02:08:00 +0000 (11:08 +0900)
18 files changed:
.gitignore
NEWS
docs/getting_started.rst
docs/guide/gtk_template.rst [new file with mode: 0644]
docs/guide/index.rst
docs/index.rst
gi/overrides/GObject.py
gi/pygflags.c
gi/pygi-info.c
meson.build
pyproject.toml
setup.py
subprojects/glib.wrap
subprojects/gobject-introspection.wrap
subprojects/libffi.wrap
subprojects/pycairo.wrap
tests/test_gobject.py
tests/testhelpermodule.c

index 6b29f6f076d74ed7a0cc378c4c5d3f025ffe7bcf..5c2211935e70571bbd7ceaa0b713d1e9313872d4 100644 (file)
@@ -85,3 +85,4 @@ Makefile.in
 *.pyd
 *.dll.a
 .coverage
+poetry.lock
\ No newline at end of file
diff --git a/NEWS b/NEWS
index fdaacadd494640c40590a8e438db1adf185e8efe..facff7058b6ae0addf9b164651b434fe0ee9d47c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,14 @@
+3.42.0 - 2021-09-19
+-------------------
+
+* meson: Bump minimum meson_version to 0.47.0
+* Expose GObject.Object.run_dispose() :issue:`470`
+* docs: document Gtk.Template. :issue:`396`
+* dev: Add poetry support
+* meson: use main branch for glib subproject
+* Fix some small memory leaks :mr:`178`
+
+
 3.40.1 - 2021-03-30
 -------------------
 
index a2f53dd32477c37f7081dfe619e98549d813a8b1..43b48d2a7148b312f7a7f3ea8adf70dac8b701b3 100644 (file)
@@ -91,7 +91,7 @@ Installing the system provided PyGObject:
 
 Installing from PyPI with pip:
   #) Open a terminal and enter your virtual environment
-  #) Execute ``sudo dnf install gcc gobject-introspection-devel cairo-devel pkg-config python3-devel gtk3``
+  #) Execute ``sudo dnf install gcc gobject-introspection-devel cairo-gobject-devel pkg-config python3-devel gtk3``
      to install the build dependencies and GTK
   #) Execute ``pip3 install pycairo`` to build and install Pycairo
   #) Execute ``pip3 install PyGObject`` to build and install PyGObject
diff --git a/docs/guide/gtk_template.rst b/docs/guide/gtk_template.rst
new file mode 100644 (file)
index 0000000..3e34060
--- /dev/null
@@ -0,0 +1,123 @@
+============
+Gtk.Template
+============
+
+A GtkWidget subclass can use a
+`GtkBuilder UI Definition <https://developer.gnome.org/gtk3/stable/GtkBuilder.html#BUILDER-UI>`__
+XML document as a template to create child widgets and set its own
+properties, without creating a GtkBuilder instance. This is implemented
+for Python by PyGObject with Gtk.Template.
+
+The subclass uses a ``@Gtk.Template`` decorator and declares a class
+variable ``__gtype_name__`` with the value of the XML ``template``
+element ``class`` attribute.
+
+Child widgets are declared, typically with the same names as the XML
+``object`` element ``id`` attributes, at the class level as instances
+of ``Gtk.Template.Child``.
+
+Signal handler methods, typically with the same names as the XML ``signal``
+element ``handler`` attributes, use the ``@Gtk.Template.Callback`` decorator.
+
+``Gtk.Template()`` takes a mandatory keyword argument passing the XML document
+or its location, either ``string``, ``filename`` or ``resource_path``.
+
+``Gtk.Template.Child()`` and ``Gtk.Template.Callback()`` optionally take
+a ``name`` argument matching the value of the respective XML attribute,
+in which case the Python attribute can have a different name.
+
+Examples
+--------
+
+.. code-block:: python
+
+    xml = """\
+    <interface>
+      <template class="example1" parent="GtkBox">
+        <child>
+          <object class="GtkButton" id="hello_button">
+            <property name="label">Hello World</property>
+            <signal name="clicked" handler="hello_button_clicked" swapped="no" />
+          </object>
+        </child>
+      </template>
+    </interface>
+    """
+
+    @Gtk.Template(string=xml)
+    class Foo(Gtk.Box):
+        __gtype_name__ = "example1"
+
+        hello_button = Gtk.Template.Child()
+
+        @Gtk.Template.Callback()
+        def hello_button_clicked(self, *args):
+            pass
+
+Python attribute names that are different to the XML values:
+
+.. code-block:: python
+
+    @Gtk.Template(string=xml)
+    class Foo(Gtk.Box):
+        __gtype_name__ = "example1"
+
+        my_button = Gtk.Template.Child("hello_button")
+
+        @Gtk.Template.Callback("hello_button_clicked")
+        def bar(self, *args):
+            pass
+
+
+To add widgets to the built-in child of a parent, describe the built-in widget
+in the XML with its ``child`` element having an ``internal-child`` attribute set
+to the name of the built-in widget:
+
+.. code-block:: XML
+
+    <interface>
+      <template class="example2" parent="GtkDialog">
+        <child internal-child="vbox">
+          <object class="GtkBox">
+            <child>
+              <object class="GtkButton" id="hello_button">
+                <property name="label">Hello World</property>
+              </object>
+            </child>
+          </object>
+        </child>
+      </template>
+    </interface>
+
+
+Subclasses that declare ``__gtype_name__`` can be used as objects in the XML:
+
+.. code-block:: python
+
+    xml = """\
+    <interface>
+      <template class="example3" parent="GtkBox">
+        <child>
+          <object class="ExampleButton" id="hello_button">
+            <property name="label">Hello World</property>
+            <signal name="clicked" handler="hello_button_clicked" swapped="no" />
+          </object>
+        </child>
+      </template>
+    </interface>
+    """
+
+
+    class HelloButton(Gtk.Button):
+        __gtype_name__ = "ExampleButton"
+
+
+    @Gtk.Template(string=xml)
+    class Foo(Gtk.Box):
+        __gtype_name__ = "example3"
+
+        hello_button = Gtk.Template.Child()
+
+        @Gtk.Template.Callback()
+        def hello_button_clicked(self, *args):
+            pass
index ac966d7ecc093033876adb50c542356a18da4752..e4dba05f365da657054febec9c7ba39d4440d75c 100644 (file)
@@ -9,6 +9,7 @@ User Guide
 
     api/index
     cairo_integration
+    gtk_template
     threading
     debug_profile
     deploy
index e78bb18ed5d63ed60bc46f9ba22270a3f1e5e923..af8b6e4cdf14b88569b54e9517c9e6c19278ba10 100644 (file)
@@ -82,7 +82,7 @@ Who Is Using PyGObject?
 * `Pithos <https://pithos.github.io/>`__ - a Pandora Radio client
 * `Pitivi <http://www.pitivi.org/>`__ - a free and open source video editor
 * `Quod Libet <https://quodlibet.readthedocs.io/>`__ - a music library manager / player
-* `Terminator <https://gnome-terminator.org/>` -- The Robot Future of Terminals
+* `Terminator <https://gnome-terminator.org/>`__ - The Robot Future of Terminals
 * `Transmageddon <http://www.linuxrising.org/>`__ - a video transcoder
 
 
index 95a3c1f36f2e1703083d1f902b7f832081cffc25..823c0b042c7b0ded1967f01ec6ae58897c198e19 100644 (file)
@@ -520,7 +520,6 @@ class Object(GObjectModule.Object):
     interface_install_property = _unsupported_method
     interface_list_properties = _unsupported_method
     notify_by_pspec = _unsupported_method
-    run_dispose = _unsupported_method
     watch_closure = _unsupported_method
 
     # Make all reference management methods private but still accessible.
index a9c443b6ce3d7afda26e588b93af9c1c0562b76d..df1280f99a8042bb5a36eb10432e9a87e8b13c99 100644 (file)
@@ -108,10 +108,13 @@ pyg_flags_repr(PyGFlags *self)
     tmp = generate_repr(self->gtype, (guint)PyLong_AsUnsignedLongMask ((PyObject*)self));
 
     module = PyObject_GetAttrString ((PyObject *)self, "__module__");
-    if (module == NULL)
+    if (module == NULL) {
+        g_free (tmp);
         return NULL;
+    }
 
     if (!PyUnicode_Check (module)) {
+        g_free (tmp);
         Py_DECREF (module);
         return NULL;
     }
index 19894e494077ff9b1d9bd9e1940be6d0efdd907c..aee5d4db108be831aab40f60c598b17a73560f7c 100644 (file)
@@ -1862,6 +1862,7 @@ _pygi_g_registered_type_info_check_object (GIRegisteredTypeInfo *info,
 
         object_type = (PyTypeObject *) PyObject_Type (object);
         if (object_type == NULL) {
+            g_free (type_name_expected);
             return -1;
         }
 
index ff6e583d73686520af0869647affac9d83d973c5..5b53432cd4f88b2c9558a1efe41862b1581e7b86 100644 (file)
@@ -1,6 +1,6 @@
 project('pygobject', 'c',
-  version : '3.40.1',
-  meson_version : '>= 0.46.0',
+  version : '3.42.0',
+  meson_version : '>= 0.47.0',
   default_options : [ 'warning_level=1',
                       'buildtype=debugoptimized'])
 
index 830e77afdf3b02dfef1389eb1dc8f8f797d9045d..dd8e7ea309f46ff4e60986cdd40898eb12f07110 100644 (file)
@@ -1,2 +1,19 @@
+[tool.poetry]
+name = "PyGObject"
+version = "3.42.0"
+description = "Python bindings for GObject Introspection"
+authors = ["Christoph Reiter"]
+
+[tool.poetry.dependencies]
+python = "^3.6"
+pycairo = "^1.16"
+
+[tool.poetry.dev-dependencies]
+pytest = "^6.0.0"
+flake8 = "^3.9.1"
+Sphinx = "^3.5.4"
+sphinx-rtd-theme = "^0.5.2"
+coverage = "^5.5"
+
 [build-system]
 requires = ["setuptools", "wheel", "pycairo"]
index 49cab4eb240c3433bb2c6bc777a2676cea170b70..8de69969240043723c157c342569e0e11cb28ceb 100755 (executable)
--- a/setup.py
+++ b/setup.py
@@ -37,7 +37,7 @@ from distutils import dir_util, log
 from distutils.spawn import find_executable
 
 
-PYGOBJECT_VERSION = "3.40.1"
+PYGOBJECT_VERSION = "3.42.0"
 GLIB_VERSION_REQUIRED = "2.56.0"
 GI_VERSION_REQUIRED = "1.56.0"
 PYCAIRO_VERSION_REQUIRED = "1.16.0"
index 87021ae4d9611defffe650565918a2d3a7c400ef..9e8b843fb8b6c498319c463a9f5b4ad55ec97f9b 100644 (file)
@@ -2,4 +2,5 @@
 directory=glib
 url=https://gitlab.gnome.org/GNOME/glib.git
 push-url=git@gitlab.gnome.org:GNOME/glib.git
-revision=master
+revision=main
+depth=1
index 561c20a8d61f02687c226104de8e4189f20dd83b..0fd976be15edb8df1eac29faa0bcc7727e6829b7 100644 (file)
@@ -3,3 +3,4 @@ directory=gobject-introspection
 url=https://gitlab.gnome.org/GNOME/gobject-introspection.git
 push-url=git@gitlab.gnome.org:GNOME/gobject-introspection.git
 revision=master
+depth=1
index 3d15e2a8a5962508dac60891957af62b88c97d39..f92e7363149d28fe2154b763df987b537b34c5e1 100644 (file)
@@ -2,3 +2,4 @@
 directory=libffi
 url=https://github.com/centricular/libffi.git
 revision=meson
+depth=1
index ba1c65682993a231ce7b828d9d89dc904b83dfa5..248c2fae5fae7de27a0c584ac5887fe32e8af68a 100644 (file)
@@ -2,3 +2,4 @@
 directory=pycairo
 url=https://github.com/pygobject/pycairo.git
 revision=pycairo-1.18
+depth=1
index f5a65bba4cb042f71a3de606912ab373fefa1a63..fbc3bb79110cf8e98772ee754af7d39cc7640afb 100644 (file)
@@ -67,6 +67,25 @@ def test_gobject_weak_ref():
 
 class TestGObjectAPI(unittest.TestCase):
 
+    def test_run_dispose(self):
+        class TestObject(GObject.GObject):
+            int_prop = GObject.Property(default=0, type=int)
+
+        obj = TestObject()
+        called = []
+
+        def on_notify(*args):
+            called.append(args)
+
+        obj.connect('notify::int-prop', on_notify)
+        obj.notify("int-prop")
+        obj.notify("int-prop")
+        # after this everything should be disconnected
+        obj.run_dispose()
+        obj.notify("int-prop")
+        obj.notify("int-prop")
+        assert len(called) == 2
+
     def test_call_method_uninitialized_instance(self):
         obj = GObject.Object.__new__(GObject.Object)
         with self.assertRaisesRegex(RuntimeError, '.*is not initialized'):
index e6f6ffe47f86349d09116bc91a4cb84fc1d9f261..eb17af87e65635cfd7b89fdeaac33e90ef9edad9 100644 (file)
@@ -362,11 +362,12 @@ test_paramspec_callback (GObject *object)
 static GValue *
 test_gvalue_callback (GObject *object, const GValue *v)
 {
-  GValue *ret = g_malloc0 (sizeof (GValue));
+  GValue *ret;
 
   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
   g_return_val_if_fail (G_IS_VALUE (v), NULL);
 
+  ret = g_malloc0 (sizeof (GValue));
   g_value_init (ret, G_VALUE_TYPE (v));
   g_value_copy (v, ret);
   return ret;
@@ -375,10 +376,11 @@ test_gvalue_callback (GObject *object, const GValue *v)
 static GValue *
 test_gvalue_ret_callback (GObject *object, GType type)
 {
-  GValue *ret = g_malloc0 (sizeof (GValue));
+  GValue *ret;
 
   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
 
+  ret = g_malloc0 (sizeof (GValue));
   g_value_init (ret, type);
 
   switch (type) {