Skip to content

Commit de84cf4

Browse files
authored
Remove deprecated pkg_resources in favor of importlib (#82)
* Use importlib if available and fallback to pkg_resources in python < 3.8 * style change
1 parent efb23ad commit de84cf4

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

sh_scrapy/crawl.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,16 +119,23 @@ def _run_scrapy(argv, settings):
119119

120120

121121
def _run_pkgscript(argv):
122-
import pkg_resources
123122
if argv[0].startswith('py:'):
124123
argv[0] = argv[0][3:]
125124
scriptname = argv[0]
126125
sys.argv = argv
127126

128127
def get_distribution():
129-
for ep in pkg_resources.WorkingSet().iter_entry_points('scrapy'):
128+
try:
129+
import importlib.metadata
130+
eps = importlib.metadata.entry_points(group='scrapy')
131+
except ImportError:
132+
import pkg_resources
133+
eps = pkg_resources.WorkingSet().iter_entry_points('scrapy')
134+
135+
for ep in eps:
130136
if ep.name == 'settings':
131137
return ep.dist
138+
132139
d = get_distribution()
133140
if not d:
134141
raise ValueError(SCRAPY_SETTINGS_ENTRYPOINT_NOT_FOUND)

tests/test_crawl.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import json
44
import mock
55
import pytest
6+
import unittest
67
from scrapy.settings import Settings
78

89
import sh_scrapy.crawl
@@ -120,6 +121,7 @@ def test_run_pkg_script(run_pkg_mock):
120121
assert run_pkg_mock.call_args[0] == (['py:script.py'],)
121122

122123

124+
@unittest.skipIf(sys.version_info > (3,7), "Requires Python 3.7 or lower")
123125
@mock.patch('pkg_resources.WorkingSet')
124126
def test_run_pkg_script_distribution_not_found(working_set_class):
125127
fake_set = mock.Mock()
@@ -128,6 +130,14 @@ def test_run_pkg_script_distribution_not_found(working_set_class):
128130
with pytest.raises(ValueError):
129131
_run(['py:script.py'], {'SETTING': 'VALUE'})
130132

133+
@unittest.skipIf(sys.version_info < (3,8), "Requires Python 3.8 or higher")
134+
@mock.patch('importlib.metadata.entry_points')
135+
def test_run_pkg_script_distribution_not_found_python_3_8_plus(working_set_class):
136+
fake_set = mock.Mock()
137+
fake_set.iter_entry_points.return_value = iter(())
138+
working_set_class.return_value = [fake_set]
139+
with pytest.raises(ValueError):
140+
_run(['py:script.py'], {'SETTING': 'VALUE'})
131141

132142
@mock.patch('sh_scrapy.crawl._run_scrapy')
133143
def test_run_scrapy_spider(run_scrapy_mock):
@@ -155,6 +165,7 @@ def get_working_set(working_set_class):
155165
return working_set
156166

157167

168+
@unittest.skipIf(sys.version_info > (3,7), "Requires Python 3.7 or lower")
158169
@mock.patch('pkg_resources.WorkingSet')
159170
def test_run_pkgscript_base_usage(working_set_class):
160171
working_set = get_working_set(working_set_class)
@@ -167,6 +178,25 @@ def test_run_pkgscript_base_usage(working_set_class):
167178
'script.py', {'__name__': '__main__'})
168179
assert sys.argv == ['script.py', 'arg1', 'arg2']
169180

181+
def get_entry_points_mock():
182+
"""Helper to configure a fake entry point"""
183+
ep = mock.Mock()
184+
ep.name = 'settings'
185+
ep.dist.run_script = mock.Mock()
186+
return [ep]
187+
188+
@unittest.skipIf(sys.version_info < (3,8), "Requires Python 3.8 or higher")
189+
@mock.patch('importlib.metadata.entry_points')
190+
def test_run_pkgscript_base_usage_python_3_8_plus(entry_points_mock):
191+
entry_points_mock.return_value = get_entry_points_mock()
192+
_run_pkgscript(['py:script.py', 'arg1', 'arg2'])
193+
assert entry_points_mock.called
194+
assert entry_points_mock.call_args[1] == {'group': 'scrapy'}
195+
ep = entry_points_mock.return_value[0]
196+
assert ep.dist.run_script.called
197+
assert ep.dist.run_script.call_args[0] == ('script.py', {'__name__': '__main__'})
198+
assert sys.argv == ['script.py', 'arg1', 'arg2']
199+
170200

171201
@mock.patch.dict(os.environ, {
172202
'SHUB_SETTINGS': '{"project_settings": {"SETTING....'})

0 commit comments

Comments
 (0)