Skip to content

Commit e3c1639

Browse files
authored
Merge pull request #121 from cloudblue/cr/LITE-33618
LITE-33618: Replace deprecated pkg_resources with importlib.resources for setuptools >= 82 compatibility
2 parents e6feead + 9e28af3 commit e3c1639

3 files changed

Lines changed: 105 additions & 21 deletions

File tree

connect/eaas/core/extension.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
import inspect
33
import json
44
import os
5+
from importlib.resources import files
56
from typing import Dict, List, Union
67

78
import anvil.server
8-
import pkg_resources
99
from fastapi import APIRouter
1010

1111
from connect.client import AsyncConnectClient, ConnectClient
@@ -31,7 +31,7 @@
3131
class ApplicationBase:
3232

3333
@classmethod
34-
def get_descriptor(cls) -> dict: # pragma: no cover
34+
def get_descriptor(cls) -> dict:
3535
"""
3636
Returns the **extension.json** extension descriptor.
3737
@@ -50,10 +50,7 @@ def get_descriptor(cls) -> dict: # pragma: no cover
5050
```
5151
"""
5252
return json.load(
53-
pkg_resources.resource_stream(
54-
cls.__module__,
55-
'extension.json',
56-
),
53+
files(cls.__module__).joinpath('extension.json').open('r'),
5754
)
5855

5956
@classmethod

tests/connect/eaas/core/test_extension.py

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
import json
12
import os
3+
from importlib.metadata import EntryPoint
24

35
import pytest
46
from fastapi_utils.inferring_router import InferringRouter
5-
from pkg_resources import EntryPoint
67

78
from connect.client import AsyncConnectClient, ConnectClient
89
from connect.eaas.core.constants import UNAUTHORIZED_ENDPOINT_ATTR_NAME
@@ -131,6 +132,61 @@ async def schedulable2(self, request):
131132
assert MyExtension(None, None, None).schedulable1.__doc__ == 'This is schedulable'
132133

133134

135+
def test_get_descriptor(tmp_path, monkeypatch):
136+
pkg_dir = tmp_path / 'fake_ext'
137+
pkg_dir.mkdir()
138+
(pkg_dir / '__init__.py').write_text('')
139+
descriptor = {
140+
'name': 'Test Extension',
141+
'description': 'A test extension',
142+
'version': '1.0.0',
143+
'audience': ['vendor'],
144+
}
145+
(pkg_dir / 'extension.json').write_text(json.dumps(descriptor))
146+
147+
monkeypatch.syspath_prepend(str(tmp_path))
148+
149+
class MyExtension(EventsApplicationBase):
150+
pass
151+
152+
MyExtension.__module__ = 'fake_ext'
153+
154+
assert MyExtension.get_descriptor() == descriptor
155+
156+
157+
def test_get_descriptor_file_not_found(tmp_path, monkeypatch):
158+
pkg_dir = tmp_path / 'fake_ext_no_json'
159+
pkg_dir.mkdir()
160+
(pkg_dir / '__init__.py').write_text('')
161+
162+
monkeypatch.syspath_prepend(str(tmp_path))
163+
164+
class MyExtension(EventsApplicationBase):
165+
pass
166+
167+
MyExtension.__module__ = 'fake_ext_no_json'
168+
169+
with pytest.raises(FileNotFoundError):
170+
MyExtension.get_descriptor()
171+
172+
173+
def test_get_descriptor_invalid_json(tmp_path, monkeypatch):
174+
pkg_dir = tmp_path / 'fake_ext_bad_json'
175+
pkg_dir.mkdir()
176+
(pkg_dir / '__init__.py').write_text('')
177+
(pkg_dir / 'extension.json').write_text('not valid json{')
178+
179+
monkeypatch.syspath_prepend(str(tmp_path))
180+
181+
class MyExtension(EventsApplicationBase):
182+
pass
183+
184+
MyExtension.__module__ = 'fake_ext_bad_json'
185+
186+
with pytest.raises(json.JSONDecodeError):
187+
MyExtension.get_descriptor()
188+
189+
134190
def test_get_variables():
135191

136192
vars = [
Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
from connect.eaas.core.validation.helpers import get_code_context
22

33

4-
def test_get_code_context_module(mocker, faker):
4+
def test_get_code_context_module(mocker):
55
mocker.patch(
66
'connect.eaas.core.validation.helpers.inspect.getsourcefile',
77
return_value='path/file.py',
88
)
99

10-
code_lines = [f'{line}\n' for line in faker.paragraphs(nb=10)]
11-
12-
code = ''.join(code_lines)
10+
pattern = 'target_pattern'
11+
pattern_line = 6
12+
code_lines = [f'line {i}\n' for i in range(10)]
13+
code_lines[pattern_line] = f'something {pattern} something\n'
1314

1415
mocker.patch(
1516
'connect.eaas.core.validation.helpers.inspect.getsourcelines',
@@ -23,23 +24,25 @@ def test_get_code_context_module(mocker, faker):
2324
return_value=True,
2425
)
2526

26-
result = get_code_context(mocker.MagicMock(), 'country store build before')
27+
result = get_code_context(mocker.MagicMock(), pattern)
2728

29+
expected_lineno = 1 + pattern_line
2830
assert result['file'] == 'path/file.py'
2931
assert result['start_line'] == 1
30-
assert result['lineno'] == 7
31-
assert result['code'] == ''.join(code.splitlines(keepends=True)[0:7 + 3])
32+
assert result['lineno'] == expected_lineno
33+
assert result['code'] == ''.join(code_lines[0:expected_lineno + 3])
3234

3335

34-
def test_get_code_context_function(mocker, faker):
36+
def test_get_code_context_function(mocker):
3537
mocker.patch(
3638
'connect.eaas.core.validation.helpers.inspect.getsourcefile',
3739
return_value='path/file.py',
3840
)
3941

40-
code_lines = [f'{line}\n' for line in faker.paragraphs(nb=10)]
41-
42-
code = ''.join(code_lines)
42+
pattern = 'target_pattern'
43+
pattern_line = 6
44+
code_lines = [f'line {i}\n' for i in range(10)]
45+
code_lines[pattern_line] = f'something {pattern} something\n'
4346

4447
mocker.patch(
4548
'connect.eaas.core.validation.helpers.inspect.getsourcelines',
@@ -53,9 +56,37 @@ def test_get_code_context_function(mocker, faker):
5356
return_value=False,
5457
)
5558

56-
result = get_code_context(mocker.MagicMock(), 'country store build before')
59+
result = get_code_context(mocker.MagicMock(), pattern)
5760

5861
assert result['file'] == 'path/file.py'
5962
assert result['start_line'] == 1
60-
assert result['lineno'] == 7
61-
assert result['code'] == ''.join(code.splitlines(keepends=True))
63+
assert result['lineno'] == 1 + pattern_line
64+
assert result['code'] == ''.join(code_lines)
65+
66+
67+
def test_get_code_context_pattern_not_found(mocker):
68+
mocker.patch(
69+
'connect.eaas.core.validation.helpers.inspect.getsourcefile',
70+
return_value='path/file.py',
71+
)
72+
73+
code_lines = [f'line {i}\n' for i in range(10)]
74+
75+
mocker.patch(
76+
'connect.eaas.core.validation.helpers.inspect.getsourcelines',
77+
return_value=(
78+
code_lines,
79+
5,
80+
),
81+
)
82+
mocker.patch(
83+
'connect.eaas.core.validation.helpers.inspect.ismodule',
84+
return_value=False,
85+
)
86+
87+
result = get_code_context(mocker.MagicMock(), 'nonexistent_pattern')
88+
89+
assert result['file'] == 'path/file.py'
90+
assert result['start_line'] == 5
91+
assert result['lineno'] == 5
92+
assert result['code'] == ''.join(code_lines)

0 commit comments

Comments
 (0)