File: use-importlib.patch

package info (click to toggle)
errbot 6.2.0%2Bds-7
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,856 kB
  • sloc: python: 11,572; makefile: 163; sh: 97
file content (202 lines) | stat: -rw-r--r-- 6,450 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
From: Sijis Aviles <sijis.aviles+github@gmail.com>
Date: Thu, 5 Jun 2025 21:04:47 -0700
Subject: refactor: use importlib instead of pkg_resources (#1669)

* refactor: use importlib instead of pkg_resources

* fix: remove try/except import check for importlib

* fix: workaround to support python 3.9 and older

* tests: add basic entry_point_plugins tests

I needed to further adjust the files lookup to ignore distributions that were
not found.

* docs: add info to CHANGES

Origin: backport, https://github.com/errbotio/errbot/pull/1669
Bug-Debian: https://bugs.debian.org/1083380
Last-Update: 2026-01-06
---
 errbot/repo_manager.py | 53 +++++++++++++++++++++-----------------------------
 errbot/utils.py        | 31 +++++++++++++++++++++++++----
 tests/utils_test.py    | 24 ++++++++++++++++++++++-
 3 files changed, 72 insertions(+), 36 deletions(-)

diff --git a/errbot/repo_manager.py b/errbot/repo_manager.py
index 1651593..ffc1c39 100644
--- a/errbot/repo_manager.py
+++ b/errbot/repo_manager.py
@@ -6,6 +6,7 @@ import shutil
 import tarfile
 from collections import namedtuple
 from datetime import datetime, timedelta
+from importlib.metadata import distribution
 from os import path
 from pathlib import Path
 from typing import Dict, Generator, List, Optional, Sequence, Tuple, Union
@@ -91,40 +92,30 @@ def check_dependencies(req_path: Path) -> Tuple[Optional[str], Sequence[str]]:
     Or None, [] if everything is OK.
     """
     log.debug("check dependencies of %s", req_path)
-    # noinspection PyBroadException
-    try:
-        from pkg_resources import get_distribution
-
-        missing_pkg = []
-
-        if not req_path.is_file():
-            log.debug("%s has no requirements.txt file", req_path)
-            return None, missing_pkg
-
-        with req_path.open() as f:
-            for line in f:
-                stripped = line.strip()
-                # skip empty lines.
-                if not stripped:
-                    continue
-
-                # noinspection PyBroadException
-                try:
-                    get_distribution(stripped)
-                except Exception:
-                    missing_pkg.append(stripped)
-        if missing_pkg:
-            return (
-                f"You need these dependencies for {req_path}: " + ",".join(missing_pkg),
-                missing_pkg,
-            )
+    missing_pkg = []
+
+    if not req_path.is_file():
+        log.debug("%s has no requirements.txt file", req_path)
         return None, missing_pkg
-    except Exception:
-        log.exception("Problem checking for dependencies.")
+
+    with req_path.open() as f:
+        for line in f:
+            stripped = line.strip()
+            # skip empty lines.
+            if not stripped:
+                continue
+
+            # noinspection PyBroadException
+            try:
+                distribution(stripped)
+            except Exception:
+                missing_pkg.append(stripped)
+    if missing_pkg:
         return (
-            "You need to have setuptools installed for the dependency check of the plugins",
-            [],
+            f"You need these dependencies for {req_path}: " + ",".join(missing_pkg),
+            missing_pkg,
         )
+    return None, missing_pkg
 
 
 class BotRepoManager(StoreMixin):
diff --git a/errbot/utils.py b/errbot/utils.py
index 68d7d70..658e801 100644
--- a/errbot/utils.py
+++ b/errbot/utils.py
@@ -1,8 +1,10 @@
 import collections
 import fnmatch
+import importlib.metadata
 import inspect
 import logging
 import os
+import pathlib
 import re
 import sys
 import time
@@ -10,7 +12,6 @@ from functools import wraps
 from platform import system
 from typing import List, Tuple, Union
 
-import pkg_resources
 from dulwich import porcelain
 
 log = logging.getLogger(__name__)
@@ -199,9 +200,31 @@ def collect_roots(base_paths: List, file_sig: str = "*.plug") -> List:
 
 def entry_point_plugins(group):
     paths = []
-    for entry_point in pkg_resources.iter_entry_points(group):
-        ep = next(pkg_resources.iter_entry_points(group, entry_point.name))
-        paths.append(f"{ep.dist.module_path}/{entry_point.module_name}")
+
+    eps = importlib.metadata.entry_points()
+    try:
+        entry_points = eps.select(group=group)
+    except AttributeError:
+        # workaround to support python 3.9 and older
+        entry_points = eps.get(group, ())
+
+    for entry_point in entry_points:
+        module_name = entry_point.module
+        file_name = module_name.replace(".", "/") + ".py"
+        try:
+            files = entry_point.dist.files
+        except AttributeError:
+            # workaround to support python 3.9 and older
+            try:
+                files = importlib.metadata.distribution(entry_point.name).files
+            except importlib.metadata.PackageNotFoundError:
+                # entrypoint is not a distribution, so let's skip looking for files
+                continue
+
+        for f in files:
+            if file_name == str(f):
+                parent = str(pathlib.Path(f).resolve().parent)
+                paths.append(f"{parent}/{module_name}")
     return paths
 
 
diff --git a/tests/utils_test.py b/tests/utils_test.py
index 858ee7d..cde8f1d 100644
--- a/tests/utils_test.py
+++ b/tests/utils_test.py
@@ -1,4 +1,7 @@
 # coding=utf-8
+import logging
+import sys
+
 from datetime import timedelta
 
 import pytest
@@ -8,7 +11,12 @@ from errbot.backends.test import ShallowConfig
 from errbot.bootstrap import CORE_STORAGE, bot_config_defaults
 from errbot.storage import StoreMixin
 from errbot.storage.base import StoragePluginBase
-from errbot.utils import *
+from errbot.utils import (
+    entry_point_plugins,
+    format_timedelta,
+    split_string_after,
+    version2tuple,
+)
 
 log = logging.getLogger(__name__)
 
@@ -100,3 +108,17 @@ def test_split_string_after_returns_two_chunks_when_chunksize_equals_half_length
     splitter = split_string_after(str_, int(len(str_) / 2))
     split = [chunk for chunk in splitter]
     assert ["foobar2000", "foobar2000"] == split
+
+
+def test_entry_point_plugins_no_groups():
+    result = entry_point_plugins("does_not_exist")
+    assert [] == result
+
+
+def test_entry_point_plugins_valid_groups():
+    results = entry_point_plugins("console_scripts")
+    match = False
+    for result in results:
+        if result.endswith("errbot/errbot.cli"):
+            match = True
+    assert match