Skip to content

Commit 9c8ddfa

Browse files
committed
fix: remove pkg_resources dependency on python 3
Fixes #232 Signed-off-by: Martin Styk <[email protected]>
1 parent e18af99 commit 9c8ddfa

File tree

10 files changed

+158
-21
lines changed

10 files changed

+158
-21
lines changed

Client/setup.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,18 @@ def bash_completion_dir():
5555
(bash_completion_dir(), ['bash-completion/bkr']),
5656
],
5757

58+
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*, !=3.7.*, !=3.8.*',
5859
classifiers=[
5960
'Development Status :: 5 - Production/Stable',
6061
'Operating System :: POSIX :: Linux',
6162
'Programming Language :: Python :: 2.7',
62-
'Programming Language :: Python :: 3.6',
63-
'Programming Language :: Python :: 3.7',
63+
'Programming Language :: Python :: 3.9',
64+
'Programming Language :: Python :: 3.10',
65+
'Programming Language :: Python :: 3.11',
66+
'Programming Language :: Python :: 3.12',
67+
'Programming Language :: Python :: 3.13',
68+
'Programming Language :: Python :: 3.14',
69+
'Programming Language :: Python :: 3.15',
6470
'License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)',
6571
],
6672

Client/src/bkr/__init__.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
2-
try:
3-
__import__('pkg_resources').declare_namespace(__name__)
4-
except ImportError:
2+
import sys
3+
if sys.version_info[0] >= 3:
54
from pkgutil import extend_path
65
__path__ = extend_path(__path__, __name__)
6+
else:
7+
try:
8+
__import__('pkg_resources').declare_namespace(__name__)
9+
except ImportError:
10+
from pkgutil import extend_path
11+
__path__ = extend_path(__path__, __name__)

Client/src/bkr/client/__init__.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@
1414
import xml.dom.minidom
1515
from optparse import OptionGroup
1616

17-
import pkg_resources
1817
from six.moves.urllib_parse import urljoin
1918

19+
from bkr.common.resources import resource_listdir, resource_string
20+
2021
from bkr.client.command import Command
2122
from bkr.common.pyconfig import PyConfigParser
2223

@@ -52,9 +53,15 @@ def host_filter_presets():
5253
return _host_filter_presets
5354

5455
_host_filter_presets = {}
55-
config_files = (
56-
sorted(glob.glob(pkg_resources.resource_filename('bkr.client', 'host-filters/*.conf')))
57-
+ sorted(glob.glob('/etc/beaker/host-filters/*.conf')))
56+
for name in sorted(resource_listdir('bkr.client', 'host-filters')):
57+
if name.endswith('.conf'):
58+
content = resource_string('bkr.client', 'host-filters/' + name).decode('utf-8', errors='replace')
59+
for line in content.splitlines():
60+
matched = re.match(r'^(\w+)\s+(\S+.*)$', line)
61+
if matched:
62+
preset, xml = matched.groups()
63+
_host_filter_presets[preset] = xml
64+
config_files = sorted(glob.glob('/etc/beaker/host-filters/*.conf'))
5865
user_config_file = os.path.expanduser('~/.beaker_client/host-filter')
5966
if os.path.exists(user_config_file):
6067
config_files.append(user_config_file)

Client/src/bkr/client/commands/cmd_job_submit.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,10 @@
106106
import xml.dom.minidom
107107

108108
import lxml.etree
109-
import pkg_resources
110109
import six
111110

111+
from bkr.common.resources import resource_stream
112+
112113
from bkr.client import BeakerCommand
113114
from bkr.client.convert import Convert
114115
from bkr.client.task_watcher import *
@@ -211,7 +212,7 @@ def run(self, *args, **kwargs):
211212
if not jobs:
212213
jobs = ['-'] # read one job from stdin by default
213214
job_schema = lxml.etree.RelaxNG(lxml.etree.parse(
214-
pkg_resources.resource_stream('bkr.common', 'schema/beaker-job.rng')))
215+
resource_stream('bkr.common', 'schema/beaker-job.rng')))
215216

216217
self.set_hub(**kwargs)
217218
submitted_jobs = []

Client/src/bkr/client/main.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@
1414
from optparse import SUPPRESS_HELP
1515

1616
import gssapi
17-
import pkg_resources
1817
from six.moves.xmlrpc_client import Fault
1918

19+
from bkr.common.resources import iter_entry_points
20+
2021
from bkr.client.command import BeakerClientConfigurationError
2122
from bkr.client.command import ClientCommandContainer
2223
from bkr.client.command import CommandOptionParser
@@ -41,7 +42,7 @@ def register_all(cls):
4142
# Load subcommands from setuptools entry points in the bkr.client.commands
4243
# group. This is the new, preferred way for other packages to provide their
4344
# own bkr subcommands.
44-
for entrypoint in pkg_resources.iter_entry_points('bkr.client.commands'):
45+
for entrypoint in iter_entry_points('bkr.client.commands'):
4546
cls.register_plugin(entrypoint.load(), name=entrypoint.name)
4647

4748

Common/bkr/__init__.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
2-
try:
3-
__import__('pkg_resources').declare_namespace(__name__)
4-
except ImportError:
2+
import sys
3+
if sys.version_info[0] >= 3:
54
from pkgutil import extend_path
65
__path__ = extend_path(__path__, __name__)
6+
else:
7+
try:
8+
__import__('pkg_resources').declare_namespace(__name__)
9+
except ImportError:
10+
from pkgutil import extend_path
11+
__path__ = extend_path(__path__, __name__)

Common/bkr/common/resources.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Copyright Contributors to the Beaker project.
2+
# SPDX-License-Identifier: GPL-2.0-or-later
3+
4+
import sys
5+
6+
if sys.version_info >= (3, 9):
7+
import importlib.resources
8+
import importlib.metadata
9+
10+
def resource_stream(package, resource_name):
11+
return importlib.resources.files(package).joinpath(resource_name).open("rb")
12+
13+
def resource_string(package, resource_name):
14+
return importlib.resources.files(package).joinpath(resource_name).read_bytes()
15+
16+
def resource_listdir(package, resource_name):
17+
return [
18+
item.name
19+
for item in importlib.resources.files(package)
20+
.joinpath(resource_name)
21+
.iterdir()
22+
]
23+
24+
def resource_exists(package, resource_name):
25+
traversable = importlib.resources.files(package).joinpath(resource_name)
26+
return traversable.is_file() or traversable.is_dir()
27+
28+
if sys.version_info >= (3, 10):
29+
def iter_entry_points(group):
30+
return importlib.metadata.entry_points(group=group)
31+
else:
32+
def iter_entry_points(group):
33+
return importlib.metadata.entry_points().get(group, [])
34+
35+
else:
36+
from pkg_resources import (
37+
resource_stream,
38+
resource_string,
39+
resource_listdir,
40+
resource_exists,
41+
iter_entry_points,
42+
)
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Copyright Contributors to the Beaker project.
2+
# SPDX-License-Identifier: GPL-2.0-or-later
3+
4+
import unittest
5+
6+
from bkr.common.resources import (
7+
resource_stream,
8+
resource_string,
9+
resource_listdir,
10+
resource_exists,
11+
iter_entry_points,
12+
)
13+
14+
15+
class ResourceStreamTest(unittest.TestCase):
16+
def test_resource_stream_returns_readable_file_object(self):
17+
f = resource_stream("bkr.common", "schema/beaker-job.rng")
18+
try:
19+
data = f.read()
20+
self.assertIsInstance(data, bytes)
21+
self.assertGreater(len(data), 0)
22+
self.assertIn(b"<grammar", data)
23+
finally:
24+
f.close()
25+
26+
27+
class ResourceStringTest(unittest.TestCase):
28+
def test_resource_string_returns_bytes(self):
29+
data = resource_string("bkr.common", "schema/beaker-job.rng")
30+
self.assertIsInstance(data, bytes)
31+
self.assertGreater(len(data), 0)
32+
self.assertIn(b"<grammar", data)
33+
34+
35+
class ResourceListdirTest(unittest.TestCase):
36+
def test_resource_listdir_returns_list(self):
37+
entries = resource_listdir("bkr.common", "schema")
38+
self.assertIsInstance(entries, list)
39+
self.assertIn("beaker-job.rng", entries)
40+
self.assertIn("beaker-task.rng", entries)
41+
42+
43+
class ResourceExistsTest(unittest.TestCase):
44+
def test_resource_exists_true_for_file(self):
45+
self.assertTrue(resource_exists("bkr.common", "schema/beaker-job.rng"))
46+
47+
def test_resource_exists_true_for_directory(self):
48+
self.assertTrue(resource_exists("bkr.common", "schema"))
49+
50+
def test_resource_exists_false(self):
51+
self.assertFalse(resource_exists("bkr.common", "schema/nonexistent.xyz"))
52+
53+
54+
class IterEntryPointsTest(unittest.TestCase):
55+
def test_iter_entry_points_returns_iterable(self):
56+
eps = iter_entry_points("console_scripts")
57+
result = list(eps)
58+
self.assertIsInstance(result, list)
59+
60+
def test_iter_entry_points_empty_group(self):
61+
eps = iter_entry_points("nonexistent.group.12345")
62+
result = list(eps)
63+
self.assertEqual(result, [])

Common/bkr/common/test_schema.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55
# (at your option) any later version.
66

77
import unittest
8-
import pkg_resources
98
import lxml.etree
109

10+
from bkr.common.resources import resource_stream
11+
1112
class SchemaTestBase(unittest.TestCase):
1213

1314
schema_doc = None # filled by setUpClass
@@ -26,7 +27,7 @@ class TaskSchemaTest(SchemaTestBase):
2627

2728
@classmethod
2829
def setUpClass(cls):
29-
cls.schema_doc = lxml.etree.parse(pkg_resources.resource_stream(
30+
cls.schema_doc = lxml.etree.parse(resource_stream(
3031
'bkr.common', 'schema/beaker-task.rng'))
3132

3233
def test_minimal_task(self):
@@ -86,7 +87,7 @@ class JobSchemaTest(SchemaTestBase):
8687

8788
@classmethod
8889
def setUpClass(cls):
89-
cls.schema_doc = lxml.etree.parse(pkg_resources.resource_stream(
90+
cls.schema_doc = lxml.etree.parse(resource_stream(
9091
'bkr.common', 'schema/beaker-job.rng'))
9192

9293
def test_minimal_job(self):

Common/setup.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,18 @@
3030
'schema/*.ttl',
3131
'default.conf']},
3232

33+
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*, !=3.7.*, !=3.8.*',
3334
classifiers=[
3435
'Development Status :: 5 - Production/Stable',
3536
'Operating System :: POSIX :: Linux',
3637
'Programming Language :: Python :: 2.7',
37-
'Programming Language :: Python :: 3.6',
38-
'Programming Language :: Python :: 3.7',
38+
'Programming Language :: Python :: 3.9',
39+
'Programming Language :: Python :: 3.10',
40+
'Programming Language :: Python :: 3.11',
41+
'Programming Language :: Python :: 3.12',
42+
'Programming Language :: Python :: 3.13',
43+
'Programming Language :: Python :: 3.14',
44+
'Programming Language :: Python :: 3.15',
3945
'License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)',
4046
],
4147
)

0 commit comments

Comments
 (0)