package/python-gobject: bump to version 3.54.2

License hash changed due to formatting changes:
e80a612fd7

Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
Signed-off-by: Julien Olivain <ju.o@free.fr>
This commit is contained in:
James Hilliard
2025-09-15 17:47:20 -06:00
committed by Julien Olivain
parent 44e0ba2bd2
commit c95f07d59a
3 changed files with 5 additions and 169 deletions

View File

@@ -1,164 +0,0 @@
From 4b97688d527276fc1e835fed71dbb73bbd09ac11 Mon Sep 17 00:00:00 2001
From: Fiona Klute <fiona.klute@gmx.de>
Date: Tue, 25 Mar 2025 13:29:04 +0100
Subject: [PATCH] gi.events._Selector.get_map(): look up file objects by file
descriptor
File objects and their underlying file descriptors must be treated as
equivalent for lookup, or one may incorrectly be treated as not
registered when the other was used for the registration, leading to
bugs.
Fixes: #689
Signed-off-by: Fiona Klute <fiona.klute@gmx.de>
Upstream: https://gitlab.gnome.org/GNOME/pygobject/-/commit/4b97688d527276fc1e835fed71dbb73bbd09ac11
---
gi/events.py | 36 +++++++++++++++++++++-----
tests/test_events.py | 61 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 90 insertions(+), 7 deletions(-)
diff --git a/gi/events.py b/gi/events.py
index da4775dc..9eba1629 100644
--- a/gi/events.py
+++ b/gi/events.py
@@ -28,6 +28,7 @@ import threading
import selectors
import weakref
import warnings
+from collections.abc import Mapping
from contextlib import contextmanager
from . import _ossighelper
@@ -508,9 +509,33 @@ if sys.platform != 'win32':
# Subclass to attach _tag
pass
+ class _FileObjectMapping(Mapping):
+ def __init__(self, fd_dict):
+ self.fd_dict = fd_dict
+
+ def __len__(self):
+ return len(self.fd_dict)
+
+ def get(self, fileobj, default=None):
+ fd = _fileobj_to_fd(fileobj)
+ return self.fd_dict.get(fd, default)
+
+ def __getitem__(self, fileobj):
+ value = self.get(fileobj)
+ if value is None:
+ raise KeyError("{!r} is not registered".format(fileobj))
+ return value
+
+ def __iter__(self):
+ return iter(self.fd_dict)
+
class _Selector(_SelectorMixin, selectors.BaseSelector):
"""A Selector for gi.events.GLibEventLoop registering python IO with GLib."""
+ def __init__(self, context, loop):
+ super().__init__(context, loop)
+ self._map = _FileObjectMapping(self._fd_to_key)
+
def attach(self):
self._source.attach(self._loop._context)
@@ -559,15 +584,12 @@ if sys.platform != 'win32':
# We could override modify, but it is only slightly when the "events" change.
def get_key(self, fileobj):
- fd = _fileobj_to_fd(fileobj)
- return self._fd_to_key[fd]
+ return self._map[fileobj]
def get_map(self):
- """Return a mapping of file objects to selector keys."""
- # Horribly inefficient
- # It should never be called and exists just to prevent issues if e.g.
- # python decides to use it for debug purposes.
- return {k.fileobj: k for k in self._fd_to_key.values()}
+ """Return a mapping of file objects or file descriptors to
+ selector keys."""
+ return self._map
else:
diff --git a/tests/test_events.py b/tests/test_events.py
index a6585468..9dbf3827 100644
--- a/tests/test_events.py
+++ b/tests/test_events.py
@@ -46,6 +46,7 @@ import sys
import gi
import gi.events
import asyncio
+import socket
import threading
from gi.repository import GLib, Gio
@@ -344,3 +345,63 @@ class GLibEventLoopPolicyTests(unittest.TestCase):
self.assertEqual(order, [GLib.PRIORITY_HIGH] * 3 +
[GLib.PRIORITY_DEFAULT] * 3 +
[GLib.PRIORITY_DEFAULT_IDLE] * 3)
+
+ @unittest.skipIf(sys.platform == 'win32', 'add reader/writer not implemented')
+ def test_source_fileobj_fd(self):
+ """Regression test for
+ https://gitlab.gnome.org/GNOME/pygobject/-/issues/689
+ """
+ class Echo:
+ def __init__(self, sock, expect_bytes):
+ self.sock = sock
+ self.sent_bytes = 0
+ self.expect_bytes = expect_bytes
+ self.done = asyncio.Future()
+ self.data = bytes()
+
+ def send(self):
+ if self.done.done():
+ return
+ if self.sent_bytes < len(self.data):
+ self.sent_bytes += self.sock.send(
+ self.data[self.sent_bytes:])
+ print('sent', self.data)
+ if self.sent_bytes >= self.expect_bytes:
+ self.done.set_result(None)
+ self.sock.shutdown(socket.SHUT_WR)
+
+ def recv(self):
+ if self.done.done():
+ return
+ self.data += self.sock.recv(self.expect_bytes)
+ print('received', self.data)
+ if len(self.data) >= self.expect_bytes:
+ self.sock.shutdown(socket.SHUT_RD)
+
+ async def run():
+ loop = asyncio.get_running_loop()
+ s1, s2 = socket.socketpair()
+ sample = b'Hello!'
+ e = Echo(s1, len(sample))
+ # register using file object and file descriptor
+ loop.add_reader(s1, e.recv)
+ loop.add_writer(s1.fileno(), e.send)
+ s2.sendall(sample)
+ await asyncio.wait_for(e.done, timeout=2.0)
+ echo = bytes()
+ for _ in range(len(sample)):
+ echo += s2.recv(len(sample))
+ if len(echo) == len(sample):
+ break
+ # remove using file object and file descriptor
+ loop.remove_reader(s1)
+ loop.remove_writer(s1.fileno())
+ s1.close()
+ s2.close()
+ # check if the data was echoed correctly
+ self.assertEqual(sample, echo)
+
+ policy = self.create_policy()
+ loop = policy.get_event_loop()
+ loop.run_until_complete(run())
+ loop.close()
--
2.49.0

View File

@@ -1,3 +1,3 @@
# from https://download.gnome.org/sources/pygobject/3.52/pygobject-3.52.3.sha256sum
sha256 00e427d291e957462a8fad659a9f9c8be776ff82a8b76bdf402f1eaeec086d82 pygobject-3.52.3.tar.gz
sha256 32434afcc8666ba060e111d715bfdb6c2d5dd8a35fa4d3ab8ad67d8f850d2f2b COPYING
# from https://download.gnome.org/sources/pygobject/3.54/pygobject-3.54.2.sha256sum
sha256 03cffeb49d8a1879b621d8f606ac904218019a0ae699b1cd3780a8ee611e696b pygobject-3.54.2.tar.gz
sha256 f4cac31434b287b10a70b81c62cfa973d250417f8f248c4c1b5566d061ecfb2f COPYING

View File

@@ -4,8 +4,8 @@
#
################################################################################
PYTHON_GOBJECT_VERSION_MAJOR = 3.52
PYTHON_GOBJECT_VERSION = $(PYTHON_GOBJECT_VERSION_MAJOR).3
PYTHON_GOBJECT_VERSION_MAJOR = 3.54
PYTHON_GOBJECT_VERSION = $(PYTHON_GOBJECT_VERSION_MAJOR).2
PYTHON_GOBJECT_SOURCE = pygobject-$(PYTHON_GOBJECT_VERSION).tar.gz
PYTHON_GOBJECT_SITE = https://download.gnome.org/sources/pygobject/$(PYTHON_GOBJECT_VERSION_MAJOR)
PYTHON_GOBJECT_LICENSE = LGPL-2.1+