Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-fs for openSUSE:Factory checked in at 2026-09-28 10:38:59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-fs (Old) and /work/SRC/openSUSE:Factory/.python-fs.new.383539 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-fs" Mon Sep 28 10:38:59 2026 rev:21 rq:1380292 version:2.4.16 Changes: -------- --- /work/SRC/openSUSE:Factory/python-fs/python-fs.changes 2026-09-10 11:52:06.581398327 +0200 +++ /work/SRC/openSUSE:Factory/.python-fs.new.383539/python-fs.changes 2026-09-28 10:40:16.902439726 +0200 @@ -1,0 +2,6 @@ +Fri Sep 25 03:11:33 UTC 2026 - Steve Kowalik <[email protected]> + +- Add patch no-more-pkg-resources.patch: + * Stop using pkg_resources to discover entry points. + +------------------------------------------------------------------- New: ---- no-more-pkg-resources.patch ----------(New B)---------- New: - Add patch no-more-pkg-resources.patch: * Stop using pkg_resources to discover entry points. ----------(New E)---------- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-fs.spec ++++++ --- /var/tmp/diff_new_pack.xZ2rDb/_old 2026-09-28 10:40:17.546466731 +0200 +++ /var/tmp/diff_new_pack.xZ2rDb/_new 2026-09-28 10:40:17.548466815 +0200 @@ -31,6 +31,8 @@ Patch1: support-pyftpdlib-2.0.patch # PATCH-FIX-OPENSUSE Support Python 3.15 changes Patch2: support-python-315.patch +# PATCH-FIX-UPSTREAM Based on gh#PyFilesystem/pyfilesystem2#589 & gh#PyFilesystem/pyfilesystem2#590 +Patch3: no-more-pkg-resources.patch BuildRequires: %{python_module appdirs >= 1.4.3} BuildRequires: %{python_module parameterized} BuildRequires: %{python_module pip} @@ -45,7 +47,6 @@ BuildRequires: fdupes BuildRequires: python-rpm-macros Requires: python-appdirs >= 1.4.3 -Requires: python-setuptools Requires: python-six >= 1.10.0 Recommends: python-pyftpdlib BuildArch: noarch ++++++ no-more-pkg-resources.patch ++++++ >From 136e7e257eebfcd1f561a6b2f897eb8bfd44574e Mon Sep 17 00:00:00 2001 From: Eli Schwartz <[email protected]> Date: Sun, 15 Sep 2024 21:25:34 -0400 Subject: [PATCH] migrate entrypoints handling to standard library importlib.metadata We wrap a couple different versions of the stdlib interface, and fall back to pkg_resources for compatibility with existing use cases on very old versions of python. For python 3.8 and on, we make sure to completely avoid external dependencies, even backports. Bug: https://github.com/PyFilesystem/pyfilesystem2/issues/577 --- fs/opener/registry.py | 38 ++++++++++++++++------ tests/test_opener.py | 74 +++++++++++++++++++++++++++++++++---------- 2 files changed, 87 insertions(+), 25 deletions(-) Index: fs-2.4.16/fs/opener/registry.py =================================================================== --- fs-2.4.16.orig/fs/opener/registry.py +++ fs-2.4.16/fs/opener/registry.py @@ -8,7 +8,7 @@ import typing import collections import contextlib -import pkg_resources +import sys from ..errors import ResourceReadOnly from .base import Opener @@ -21,6 +21,30 @@ if typing.TYPE_CHECKING: from ..base import FS +if sys.version_info >= (3, 8): + import importlib.metadata + + if sys.version_info >= (3, 10): + + def entrypoints(group, name=None): + ep = importlib.metadata.entry_points(group=group, name=name) + return tuple(n for n in ep) + + else: + + def entrypoints(group, name=None): + ep = importlib.metadata.entry_points() + if name: + return tuple(n for n in ep.get(group, ()) if n.name == name) + return ep.get(group, ()) + +else: + import pkg_resources + + def entrypoints(group, name=None): + return tuple(pkg_resources.iter_entry_points(group, name)) + + class Registry(object): """A registry for `Opener` instances.""" @@ -74,10 +98,7 @@ class Registry(object): """`list`: the list of supported protocols.""" _protocols = list(self._protocols) if self.load_extern: - _protocols.extend( - entry_point.name - for entry_point in pkg_resources.iter_entry_points("fs.opener") - ) + _protocols.extend(n.name for n in entrypoints("fs.opener")) _protocols = list(collections.OrderedDict.fromkeys(_protocols)) return _protocols @@ -101,10 +122,9 @@ class Registry(object): """ protocol = protocol or self.default_opener - if self.load_extern: - entry_point = next( - pkg_resources.iter_entry_points("fs.opener", protocol), None - ) + ep = entrypoints("fs.opener", protocol) + if self.load_extern and ep: + entry_point = ep[0] else: entry_point = None Index: fs-2.4.16/tests/test_opener.py =================================================================== --- fs-2.4.16.orig/tests/test_opener.py +++ fs-2.4.16/tests/test_opener.py @@ -3,7 +3,6 @@ from __future__ import unicode_literals import sys import os -import pkg_resources import shutil import tempfile import unittest @@ -13,7 +12,7 @@ from fs.appfs import UserDataFS from fs.memoryfs import MemoryFS from fs.opener import errors, registry from fs.opener.parse import ParseResult -from fs.opener.registry import Registry +from fs.opener.registry import Registry, entrypoints from fs.osfs import OSFS try: @@ -21,6 +20,11 @@ try: except ImportError: import mock +if sys.version_info >= (3, 8): + import importlib.metadata +else: + import pkg_resources + class TestParse(unittest.TestCase): def test_registry_repr(self): @@ -111,14 +115,25 @@ class TestRegistry(unittest.TestCase): def test_registry_protocols(self): # Check registry.protocols list the names of all available extension - extensions = [ - pkg_resources.EntryPoint("proto1", "mod1"), - pkg_resources.EntryPoint("proto2", "mod2"), - ] - m = mock.MagicMock(return_value=extensions) - with mock.patch.object( - sys.modules["pkg_resources"], "iter_entry_points", new=m - ): + if sys.version_info >= (3, 8): + extensions = ( + importlib.metadata.EntryPoint("proto1", "mod1", "fs.opener"), + importlib.metadata.EntryPoint("proto2", "mod2", "fs.opener"), + ) + if sys.version_info >= (3, 10): + m = mock.MagicMock(return_value=extensions) + else: + m = mock.MagicMock(return_value={"fs.opener": extensions}) + patch = mock.patch("importlib.metadata.entry_points", m) + else: + extensions = [ + pkg_resources.EntryPoint("proto1", "mod1"), + pkg_resources.EntryPoint("proto2", "mod2"), + ] + m = mock.MagicMock(return_value=extensions) + patch = mock.patch("pkg_resources.iter_entry_points", m) + + with patch: self.assertIn("proto1", opener.registry.protocols) self.assertIn("proto2", opener.registry.protocols) @@ -129,11 +144,19 @@ class TestRegistry(unittest.TestCase): def test_entry_point_load_error(self): entry_point = mock.MagicMock() + entry_point.name = "test" entry_point.load.side_effect = ValueError("some error") - iter_entry_points = mock.MagicMock(return_value=iter([entry_point])) - - with mock.patch("pkg_resources.iter_entry_points", iter_entry_points): + if sys.version_info >= (3, 8): + if sys.version_info >= (3, 10): + entry_points = mock.MagicMock(return_value=tuple([entry_point])) + else: + entry_points = mock.MagicMock(return_value={"fs.opener": [entry_point]}) + patch = mock.patch("importlib.metadata.entry_points", entry_points) + else: + iter_entry_points = mock.MagicMock(return_value=iter([entry_point])) + patch = mock.patch("pkg_resources.iter_entry_points", iter_entry_points) + with patch: with self.assertRaises(errors.EntryPointError) as ctx: opener.open_fs("test://") self.assertEqual( @@ -145,10 +168,19 @@ class TestRegistry(unittest.TestCase): pass entry_point = mock.MagicMock() + entry_point.name = "test" entry_point.load = mock.MagicMock(return_value=NotAnOpener) - iter_entry_points = mock.MagicMock(return_value=iter([entry_point])) - with mock.patch("pkg_resources.iter_entry_points", iter_entry_points): + if sys.version_info >= (3, 8): + if sys.version_info >= (3, 10): + entry_points = mock.MagicMock(return_value=tuple([entry_point])) + else: + entry_points = mock.MagicMock(return_value={"fs.opener": [entry_point]}) + patch = mock.patch("importlib.metadata.entry_points", entry_points) + else: + iter_entry_points = mock.MagicMock(return_value=iter([entry_point])) + patch = mock.patch("pkg_resources.iter_entry_points", iter_entry_points) + with patch: with self.assertRaises(errors.EntryPointError) as ctx: opener.open_fs("test://") self.assertEqual("entry point did not return an opener", str(ctx.exception)) @@ -162,10 +194,20 @@ class TestRegistry(unittest.TestCase): pass entry_point = mock.MagicMock() + entry_point.name = "test" entry_point.load = mock.MagicMock(return_value=BadOpener) - iter_entry_points = mock.MagicMock(return_value=iter([entry_point])) - with mock.patch("pkg_resources.iter_entry_points", iter_entry_points): + if sys.version_info >= (3, 8): + if sys.version_info >= (3, 10): + entry_points = mock.MagicMock(return_value=tuple([entry_point])) + else: + entry_points = mock.MagicMock(return_value={"fs.opener": [entry_point]}) + patch = mock.patch("importlib.metadata.entry_points", entry_points) + else: + iter_entry_points = mock.MagicMock(return_value=iter([entry_point])) + patch = mock.patch("pkg_resources.iter_entry_points", iter_entry_points) + + with patch: with self.assertRaises(errors.EntryPointError) as ctx: opener.open_fs("test://") self.assertEqual( @@ -217,7 +259,7 @@ class TestOpeners(unittest.TestCase): def test_repr(self): # Check __repr__ works - for entry_point in pkg_resources.iter_entry_points("fs.opener"): + for entry_point in entrypoints("fs.opener"): _opener = entry_point.load() repr(_opener()) Index: fs-2.4.16/fs/__init__.py =================================================================== --- fs-2.4.16.orig/fs/__init__.py +++ fs-2.4.16/fs/__init__.py @@ -1,7 +1,7 @@ """Python filesystem abstraction layer. """ -__import__("pkg_resources").declare_namespace(__name__) # type: ignore +__path__ = __import__("pkgutil").extend_path(__path__, __name__) from . import path from ._fscompat import fsdecode, fsencode Index: fs-2.4.16/fs/opener/__init__.py =================================================================== --- fs-2.4.16.orig/fs/opener/__init__.py +++ fs-2.4.16/fs/opener/__init__.py @@ -3,7 +3,7 @@ """ # Declare fs.opener as a namespace package -__import__("pkg_resources").declare_namespace(__name__) # type: ignore +__path__ = __import__("pkgutil").extend_path(__path__, __name__) # Import opener modules so that `registry.install` if called on each opener from . import appfs, ftpfs, memoryfs, osfs, tarfs, tempfs, zipfs Index: fs-2.4.16/setup.cfg =================================================================== --- fs-2.4.16.orig/setup.cfg +++ fs-2.4.16/setup.cfg @@ -41,7 +41,7 @@ setup_requires = setuptools >=38.3.0 install_requires = appdirs~=1.4.3 - setuptools + setuptools ; python_version < '3.8' six ~=1.10 enum34 ~=1.1.6 ; python_version < '3.4' typing ~=3.6 ; python_version < '3.6'
