diff --git a/0001-IntrospectionModule-handle-two-threads-loading-type-.patch b/0001-IntrospectionModule-handle-two-threads-loading-type-.patch deleted file mode 100644 index a38c813..0000000 --- a/0001-IntrospectionModule-handle-two-threads-loading-type-.patch +++ /dev/null @@ -1,290 +0,0 @@ -From 1212d1cd3d4b47294770408a7abd18bc4c578a64 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Wed, 10 Jun 2020 18:04:07 -0400 -Subject: [PATCH] IntrospectionModule: handle two threads loading type at same - time - -If two threads are trying to load a type at exactly the same time, -it's possible for two wrappers to get generated for the type. -One thread will end up with the wrapper that's not blessed as the -"real" one and future calls will fail. The blessed wrapper will -be incomplete, and so future calls from it will fail as well. - -This commit adds a lock to ensure the two threads don't stomp -on each others toes. ---- - gi/module.py | 110 +++++++++++++++++++++++++++------------------------ - 1 file changed, 58 insertions(+), 52 deletions(-) - -diff --git a/gi/module.py b/gi/module.py -index f9e26bc2..93b8e6a3 100644 ---- a/gi/module.py -+++ b/gi/module.py -@@ -1,53 +1,54 @@ - # -*- Mode: Python; py-indent-offset: 4 -*- - # vim: tabstop=4 shiftwidth=4 expandtab - # - # Copyright (C) 2007-2009 Johan Dahlin - # - # module.py: dynamic module for introspected libraries. - # - # This library is free software; you can redistribute it and/or - # modify it under the terms of the GNU Lesser General Public - # License as published by the Free Software Foundation; either - # version 2.1 of the License, or (at your option) any later version. - # - # This library is distributed in the hope that it will be useful, - # but WITHOUT ANY WARRANTY; without even the implied warranty of - # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - # Lesser General Public License for more details. - # - # You should have received a copy of the GNU Lesser General Public - # License along with this library; if not, write to the Free Software - # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 - # USA - - import importlib -+from threading import Lock - - import gi - - from ._gi import \ - Repository, \ - FunctionInfo, \ - RegisteredTypeInfo, \ - EnumInfo, \ - ObjectInfo, \ - InterfaceInfo, \ - ConstantInfo, \ - StructInfo, \ - UnionInfo, \ - CallbackInfo, \ - Struct, \ - Boxed, \ - CCallback, \ - enum_add, \ - enum_register_new_gtype_and_add, \ - flags_add, \ - flags_register_new_gtype_and_add, \ - GInterface - from .types import \ - GObjectMeta, \ - StructMeta - - from ._constants import \ - TYPE_NONE, \ - TYPE_BOXED, \ - TYPE_POINTER, \ -@@ -90,152 +91,157 @@ def get_interfaces_for_object(object_info): - namespace = interface_info.get_namespace() - name = interface_info.get_name() - - module = importlib.import_module('gi.repository.' + namespace) - interfaces.append(getattr(module, name)) - return interfaces - - - class IntrospectionModule(object): - """An object which wraps an introspection typelib. - - This wrapping creates a python module like representation of the typelib - using gi repository as a foundation. Accessing attributes of the module - will dynamically pull them in and create wrappers for the members. - These members are then cached on this introspection module. - """ - def __init__(self, namespace, version=None): - """Might raise gi._gi.RepositoryError""" - - repository.require(namespace, version) - self._namespace = namespace - self._version = version - self.__name__ = 'gi.repository.' + namespace - - path = repository.get_typelib_path(self._namespace) - self.__path__ = [path] - - if self._version is None: - self._version = repository.get_version(self._namespace) - -+ self._lock = Lock() -+ - def __getattr__(self, name): - info = repository.find_by_name(self._namespace, name) - if not info: - raise AttributeError("%r object has no attribute %r" % ( - self.__name__, name)) - - if isinstance(info, EnumInfo): - g_type = info.get_g_type() -- wrapper = g_type.pytype - -- if wrapper is None: -- if info.is_flags(): -- if g_type.is_a(TYPE_FLAGS): -- wrapper = flags_add(g_type) -- else: -- assert g_type == TYPE_NONE -- wrapper = flags_register_new_gtype_and_add(info) -- else: -- if g_type.is_a(TYPE_ENUM): -- wrapper = enum_add(g_type) -+ with self._lock: -+ wrapper = g_type.pytype -+ -+ if wrapper is None: -+ if info.is_flags(): -+ if g_type.is_a(TYPE_FLAGS): -+ wrapper = flags_add(g_type) -+ else: -+ assert g_type == TYPE_NONE -+ wrapper = flags_register_new_gtype_and_add(info) - else: -- assert g_type == TYPE_NONE -- wrapper = enum_register_new_gtype_and_add(info) -- -- wrapper.__info__ = info -- wrapper.__module__ = 'gi.repository.' + info.get_namespace() -- -- # Don't use upper() here to avoid locale specific -- # identifier conversion (e. g. in Turkish 'i'.upper() == 'i') -- # see https://bugzilla.gnome.org/show_bug.cgi?id=649165 -- ascii_upper_trans = ''.maketrans( -- 'abcdefgjhijklmnopqrstuvwxyz', -- 'ABCDEFGJHIJKLMNOPQRSTUVWXYZ') -- for value_info in info.get_values(): -- value_name = value_info.get_name_unescaped().translate(ascii_upper_trans) -- setattr(wrapper, value_name, wrapper(value_info.get_value())) -- for method_info in info.get_methods(): -- setattr(wrapper, method_info.__name__, method_info) -- -- if g_type != TYPE_NONE: -- g_type.pytype = wrapper -+ if g_type.is_a(TYPE_ENUM): -+ wrapper = enum_add(g_type) -+ else: -+ assert g_type == TYPE_NONE -+ wrapper = enum_register_new_gtype_and_add(info) -+ -+ wrapper.__info__ = info -+ wrapper.__module__ = 'gi.repository.' + info.get_namespace() -+ -+ # Don't use upper() here to avoid locale specific -+ # identifier conversion (e. g. in Turkish 'i'.upper() == 'i') -+ # see https://bugzilla.gnome.org/show_bug.cgi?id=649165 -+ ascii_upper_trans = ''.maketrans( -+ 'abcdefgjhijklmnopqrstuvwxyz', -+ 'ABCDEFGJHIJKLMNOPQRSTUVWXYZ') -+ for value_info in info.get_values(): -+ value_name = value_info.get_name_unescaped().translate(ascii_upper_trans) -+ setattr(wrapper, value_name, wrapper(value_info.get_value())) -+ for method_info in info.get_methods(): -+ setattr(wrapper, method_info.__name__, method_info) -+ -+ if g_type != TYPE_NONE: -+ g_type.pytype = wrapper - - elif isinstance(info, RegisteredTypeInfo): - g_type = info.get_g_type() - - # Create a wrapper. - if isinstance(info, ObjectInfo): - parent = get_parent_for_object(info) - interfaces = tuple(interface for interface in get_interfaces_for_object(info) - if not issubclass(parent, interface)) - bases = (parent,) + interfaces - metaclass = GObjectMeta - elif isinstance(info, CallbackInfo): - bases = (CCallback,) - metaclass = GObjectMeta - elif isinstance(info, InterfaceInfo): - bases = (GInterface,) - metaclass = GObjectMeta - elif isinstance(info, (StructInfo, UnionInfo)): - if g_type.is_a(TYPE_BOXED): - bases = (Boxed,) - elif (g_type.is_a(TYPE_POINTER) or - g_type == TYPE_NONE or - g_type.fundamental == g_type): - bases = (Struct,) - else: - raise TypeError("unable to create a wrapper for %s.%s" % (info.get_namespace(), info.get_name())) - metaclass = StructMeta - else: - raise NotImplementedError(info) - -- # Check if there is already a Python wrapper that is not a parent class -- # of the wrapper being created. If it is a parent, it is ok to clobber -- # g_type.pytype with a new child class wrapper of the existing parent. -- # Note that the return here never occurs under normal circumstances due -- # to caching on the __dict__ itself. -- if g_type != TYPE_NONE: -- type_ = g_type.pytype -- if type_ is not None and type_ not in bases: -- self.__dict__[name] = type_ -- return type_ -- -- dict_ = { -- '__info__': info, -- '__module__': 'gi.repository.' + self._namespace, -- '__gtype__': g_type -- } -- wrapper = metaclass(name, bases, dict_) -- -- # Register the new Python wrapper. -- if g_type != TYPE_NONE: -- g_type.pytype = wrapper -+ with self._lock: -+ # Check if there is already a Python wrapper that is not a parent class -+ # of the wrapper being created. If it is a parent, it is ok to clobber -+ # g_type.pytype with a new child class wrapper of the existing parent. -+ # Note that the return here never occurs under normal circumstances due -+ # to caching on the __dict__ itself. -+ if g_type != TYPE_NONE: -+ type_ = g_type.pytype -+ if type_ is not None and type_ not in bases: -+ self.__dict__[name] = type_ -+ return type_ -+ -+ dict_ = { -+ '__info__': info, -+ '__module__': 'gi.repository.' + self._namespace, -+ '__gtype__': g_type -+ } -+ wrapper = metaclass(name, bases, dict_) -+ -+ # Register the new Python wrapper. -+ if g_type != TYPE_NONE: -+ g_type.pytype = wrapper - - elif isinstance(info, FunctionInfo): - wrapper = info - elif isinstance(info, ConstantInfo): - wrapper = info.get_value() - else: - raise NotImplementedError(info) - - # Cache the newly created wrapper which will then be - # available directly on this introspection module instead of being - # lazily constructed through the __getattr__ we are currently in. - self.__dict__[name] = wrapper - return wrapper - - def __repr__(self): - path = repository.get_typelib_path(self._namespace) - return "" % (self._namespace, path) - - def __dir__(self): - # Python's default dir() is just dir(self.__class__) + self.__dict__.keys() - result = set(dir(self.__class__)) - result.update(self.__dict__.keys()) - - # update *set* because some repository attributes have already been - # wrapped by __getattr__() and included in self.__dict__; but skip - # Callback types, as these are not real objects which we can actually - # get - namespace_infos = repository.get_infos(self._namespace) - result.update(info.get_name() for info in namespace_infos if - not isinstance(info, CallbackInfo)) --- -2.31.1 - diff --git a/pygobject3.spec b/pygobject3.spec index 228fa6d..d593ba0 100644 --- a/pygobject3.spec +++ b/pygobject3.spec @@ -1,17 +1,16 @@ %define glib2_version 2.56.0 %define gobject_introspection_version 1.56.0 %define pycairo_version 1.16.0 -%define python2_version 2.7 -%define python3_version 3.4 +%define python3_version 3.7 Name: pygobject3 -Version: 3.42.2 -Release: 3%{?dist} +Version: 3.43.1 +Release: 1%{?dist} Summary: Python bindings for GObject Introspection License: LGPLv2+ and MIT URL: https://wiki.gnome.org/Projects/PyGObject -Source0: https://download.gnome.org/sources/pygobject/3.42/pygobject-%{version}.tar.xz +Source0: https://download.gnome.org/sources/pygobject/3.43/pygobject-%{version}.tar.xz BuildRequires: pkgconfig(cairo-gobject) BuildRequires: pkgconfig(glib-2.0) >= %{glib2_version} @@ -26,8 +25,6 @@ BuildRequires: python3-setuptools %global py_reproducible_pyc_path %{buildroot}%{python3_sitelib} BuildRequires: /usr/bin/marshalparser -Patch10001: 0001-IntrospectionModule-handle-two-threads-loading-type-.patch - %description The %{name} package provides a convenient wrapper for the GObject library for use in Python programs. @@ -105,6 +102,9 @@ This package contains files required to embed PyGObject %{_libdir}/pkgconfig/pygobject-3.0.pc %changelog +* Mon Feb 06 2023 David King - 3.43.1-1 +- Update to 3.43.1 + * Fri Jan 20 2023 Fedora Release Engineering - 3.42.2-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild diff --git a/sources b/sources index 4f2d8b8..c6be64a 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (pygobject-3.42.2.tar.xz) = eb604f839e0702e8aeff0f19665e44c05c56cae02ce892e9ab8a95ddb0d5d0216182d0c9a0059fc8e05990c0d5707f2f7456d8924bbfb95ce1d9a42908ac0119 +SHA512 (pygobject-3.43.1.tar.xz) = e12e53368a94f49daacf24519d9bd65ca11481d6a3059635bebaec43a84d2620fb619c2eac36f7f6b0202a6268b1990f9452355e13b114a4988de18fe30ce66e