Visitar URL original
👹 Feed the hobgoblins (delint). · python/importlib_metadata@2f37725 · GitHub
Skip to content

Commit 2f37725

Browse files
committed
👹 Feed the hobgoblins (delint).
Ref jaraco/skeleton#210
1 parent 91b99f0 commit 2f37725

6 files changed

Lines changed: 66 additions & 31 deletions

File tree

‎importlib_metadata/__init__.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,8 @@ class EntryPoint:
217217

218218
def __init__(self, name: str, value: str, group: str) -> None:
219219
vars(self).update(name=name, value=value, group=group)
220-
self.module
220+
# resolve the value now, raising ValueError if it's invalid
221+
_ = self.module
221222

222223
def load(self) -> Any:
223224
"""Load the entry point from its definition. If only a module

‎importlib_metadata/_adapters.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class Message(email.message.Message):
5454
<BLANKLINE>
5555
"""
5656

57-
multiple_use_keys = set(
57+
multiple_use_keys = frozenset(
5858
map(
5959
FoldedCase,
6060
[

‎tests/compat/py314.py‎

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,60 @@
22
import sys
33
import types
44
import warnings
5+
from collections.abc import Mapping
56

67
from test.support import warnings_helper as orig
78

89
if sys.version_info >= (3, 15):
910
from builtins import frozendict
1011
else:
1112

12-
def frozendict(*args, **kwargs) -> types.MappingProxyType:
13+
class frozendict(Mapping):
1314
"""
1415
Approximate frozendict, added to builtins in Python 3.15.
1516
16-
A mapping proxy is read-only, so as long as the mapping it wraps
17-
has no other referents, it's effectively immutable.
17+
Accepts anything dict() accepts and presents it read-only.
1818
1919
>>> frozendict(a=1)['a']
2020
1
2121
>>> frozendict({'a': 1}) == {'a': 1}
2222
True
23+
>>> frozendict(a=1)
24+
frozendict({'a': 1})
25+
26+
Hashable when the values are.
27+
28+
>>> hash(frozendict(a=1)) == hash(frozendict(a=1))
29+
True
30+
31+
Unlike a mapping proxy, supports copying, so callers may take a
32+
mutable snapshot to alter.
33+
34+
>>> import copy
35+
>>> spec = frozendict(pkg={'META': 'lower'})
36+
>>> altered = copy.deepcopy(spec)
37+
>>> altered['pkg']['META'] = 'UPPER'
38+
>>> spec['pkg']['META']
39+
'lower'
2340
"""
24-
return types.MappingProxyType(dict(*args, **kwargs))
41+
42+
def __init__(self, *args, **kwargs):
43+
self._data = dict(*args, **kwargs)
44+
45+
def __getitem__(self, key):
46+
return self._data[key]
47+
48+
def __iter__(self):
49+
return iter(self._data)
50+
51+
def __len__(self):
52+
return len(self._data)
53+
54+
def __hash__(self):
55+
return hash(frozenset(self._data.items()))
56+
57+
def __repr__(self):
58+
return f'{type(self).__name__}({self._data!r})'
2559

2660

2761
@contextlib.contextmanager

‎tests/fixtures.py‎

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from . import _path
1414
from ._path import FilesSpec
1515
from .compat.py312 import import_helper
16+
from .compat.py314 import frozendict
1617

1718

1819
@contextlib.contextmanager
@@ -70,7 +71,7 @@ def setUp(self):
7071

7172

7273
class DistInfoPkg(OnSysPath, SiteBuilder):
73-
files: FilesSpec = {
74+
files: FilesSpec = frozendict({
7475
"distinfo_pkg-1.0.0.dist-info": {
7576
"METADATA": """
7677
Name: distinfo-pkg
@@ -94,7 +95,7 @@ class DistInfoPkg(OnSysPath, SiteBuilder):
9495
def main():
9596
print("hello world")
9697
""",
97-
}
98+
})
9899

99100
def make_uppercase(self):
100101
"""
@@ -113,7 +114,7 @@ class DistInfoPkgEditable(DistInfoPkg):
113114
"""
114115

115116
some_hash = '524127ce937f7cb65665130c695abd18ca386f60bb29687efb976faa1596fdcc'
116-
files: FilesSpec = {
117+
files: FilesSpec = frozendict({
117118
'distinfo_pkg-1.0.0.dist-info': {
118119
'direct_url.json': json.dumps({
119120
"archive_info": {
@@ -123,22 +124,22 @@ class DistInfoPkgEditable(DistInfoPkg):
123124
"url": "file:///path/to/distinfo_pkg-1.0.0.editable-py3-none-any.whl",
124125
})
125126
},
126-
}
127+
})
127128

128129

129130
class DistInfoPkgWithDot(OnSysPath, SiteBuilder):
130-
files: FilesSpec = {
131+
files: FilesSpec = frozendict({
131132
"pkg_dot-1.0.0.dist-info": {
132133
"METADATA": """
133134
Name: pkg.dot
134135
Version: 1.0.0
135136
""",
136137
},
137-
}
138+
})
138139

139140

140141
class DistInfoPkgWithDotLegacy(OnSysPath, SiteBuilder):
141-
files: FilesSpec = {
142+
files: FilesSpec = frozendict({
142143
"pkg.dot-1.0.0.dist-info": {
143144
"METADATA": """
144145
Name: pkg.dot
@@ -151,15 +152,15 @@ class DistInfoPkgWithDotLegacy(OnSysPath, SiteBuilder):
151152
Version: 1.0.0
152153
""",
153154
},
154-
}
155+
})
155156

156157

157158
class DistInfoPkgOffPath(SiteBuilder):
158159
files = DistInfoPkg.files
159160

160161

161162
class EggInfoPkg(OnSysPath, SiteBuilder):
162-
files: FilesSpec = {
163+
files: FilesSpec = frozendict({
163164
"egginfo_pkg.egg-info": {
164165
"PKG-INFO": """
165166
Name: egginfo-pkg
@@ -191,11 +192,11 @@ class EggInfoPkg(OnSysPath, SiteBuilder):
191192
def main():
192193
print("hello world")
193194
""",
194-
}
195+
})
195196

196197

197198
class EggInfoPkgPipInstalledNoToplevel(OnSysPath, SiteBuilder):
198-
files: FilesSpec = {
199+
files: FilesSpec = frozendict({
199200
"egg_with_module_pkg.egg-info": {
200201
"PKG-INFO": "Name: egg_with_module-pkg",
201202
# SOURCES.txt is made from the source archive, and contains files
@@ -222,11 +223,11 @@ class EggInfoPkgPipInstalledNoToplevel(OnSysPath, SiteBuilder):
222223
def main():
223224
print("hello world")
224225
""",
225-
}
226+
})
226227

227228

228229
class EggInfoPkgPipInstalledExternalDataFiles(OnSysPath, SiteBuilder):
229-
files: FilesSpec = {
230+
files: FilesSpec = frozendict({
230231
"egg_with_module_pkg.egg-info": {
231232
"PKG-INFO": "Name: egg_with_module-pkg",
232233
# SOURCES.txt is made from the source archive, and contains files
@@ -256,11 +257,11 @@ class EggInfoPkgPipInstalledExternalDataFiles(OnSysPath, SiteBuilder):
256257
def main():
257258
print("hello world")
258259
""",
259-
}
260+
})
260261

261262

262263
class EggInfoPkgPipInstalledNoModules(OnSysPath, SiteBuilder):
263-
files: FilesSpec = {
264+
files: FilesSpec = frozendict({
264265
"egg_with_no_modules_pkg.egg-info": {
265266
"PKG-INFO": "Name: egg_with_no_modules-pkg",
266267
# SOURCES.txt is made from the source archive, and contains files
@@ -282,11 +283,11 @@ class EggInfoPkgPipInstalledNoModules(OnSysPath, SiteBuilder):
282283
# top_level.txt correctly reflects that no modules are installed
283284
"top_level.txt": b"\n",
284285
},
285-
}
286+
})
286287

287288

288289
class EggInfoPkgSourcesFallback(OnSysPath, SiteBuilder):
289-
files: FilesSpec = {
290+
files: FilesSpec = frozendict({
290291
"sources_fallback_pkg.egg-info": {
291292
"PKG-INFO": "Name: sources_fallback-pkg",
292293
# SOURCES.txt is made from the source archive, and contains files
@@ -304,11 +305,11 @@ class EggInfoPkgSourcesFallback(OnSysPath, SiteBuilder):
304305
def main():
305306
print("hello world")
306307
""",
307-
}
308+
})
308309

309310

310311
class EggInfoFile(OnSysPath, SiteBuilder):
311-
files: FilesSpec = {
312+
files: FilesSpec = frozendict({
312313
"egginfo_file.egg-info": """
313314
Metadata-Version: 1.0
314315
Name: egginfo_file
@@ -321,7 +322,7 @@ class EggInfoFile(OnSysPath, SiteBuilder):
321322
Description: UNKNOWN
322323
Platform: UNKNOWN
323324
""",
324-
}
325+
})
325326

326327

327328
# dedent all text strings before writing

‎tests/test_api.py‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,8 @@ def test_name_normalization(self):
5454
def test_prefix_not_matched(self):
5555
prefixes = 'p', 'pkg', 'pkg.'
5656
for prefix in prefixes:
57-
with self.subTest(prefix):
58-
with self.assertRaises(PackageNotFoundError):
59-
distribution(prefix)
57+
with self.subTest(prefix), self.assertRaises(PackageNotFoundError):
58+
distribution(prefix)
6059

6160
def test_for_top_level(self):
6261
tests = [

‎tests/test_main.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ def test_abc_enforced(self):
5858
dict(name=''),
5959
)
6060
def test_invalid_inputs_to_from_name(self, name):
61-
with self.assertRaises(Exception):
61+
with self.assertRaises(ValueError):
6262
Distribution.from_name(name)
6363

6464

@@ -165,7 +165,7 @@ def test_missing_metadata(self):
165165
"""
166166
fixtures.build_files(self.make_pkg('foo-4.3', files={}), self.site_dir)
167167
with self.assertRaises(MetadataNotFound):
168-
Distribution.from_name('foo').metadata
168+
_ = Distribution.from_name('foo').metadata
169169
with self.assertRaises(MetadataNotFound):
170170
metadata('foo')
171171

0 commit comments

Comments
 (0)