Skip to content

Commit 2eca591

Browse files
committed
EntryPoint is no longer a namedtuple and ordering of EntryPoint objects is now deprecated.
1 parent 08d7def commit 2eca591

File tree

3 files changed

+35
-43
lines changed

3 files changed

+35
-43
lines changed

importlib_metadata/__init__.py

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
from ._collections import FreezableDefaultDict, Pair
1919
from ._compat import (
2020
NullFinder,
21-
PyPy_repr,
2221
install,
2322
pypy_partial,
2423
)
@@ -126,9 +125,7 @@ def valid(line):
126125
return line and not line.startswith('#')
127126

128127

129-
class EntryPoint(
130-
PyPy_repr, collections.namedtuple('EntryPointBase', 'name value group')
131-
):
128+
class EntryPoint:
132129
"""An entry point as defined by Python packaging conventions.
133130
134131
See `the packaging docs on entry points
@@ -159,6 +156,9 @@ class EntryPoint(
159156

160157
dist: Optional['Distribution'] = None
161158

159+
def __init__(self, *, name, value, group):
160+
vars(self).update(name=name, value=value, group=group)
161+
162162
def load(self):
163163
"""Load the entry point from its definition. If only a module
164164
is indicated by the value, return that module. Otherwise,
@@ -185,7 +185,7 @@ def extras(self):
185185
return list(re.finditer(r'\w+', match.group('extras') or ''))
186186

187187
def _for(self, dist):
188-
self.dist = dist
188+
vars(self).update(dist=dist)
189189
return self
190190

191191
def __iter__(self):
@@ -199,16 +199,31 @@ def __iter__(self):
199199
warnings.warn(msg, DeprecationWarning)
200200
return iter((self.name, self))
201201

202-
def __reduce__(self):
203-
return (
204-
self.__class__,
205-
(self.name, self.value, self.group),
206-
)
207-
208202
def matches(self, **params):
209203
attrs = (getattr(self, param) for param in params)
210204
return all(map(operator.eq, params.values(), attrs))
211205

206+
def _key(self):
207+
return tuple(getattr(self, key) for key in 'name value group'.split())
208+
209+
def __lt__(self, other):
210+
return self._key() < other._key()
211+
212+
def __eq__(self, other):
213+
return self._key() == other._key()
214+
215+
def __setattr__(self, name, value):
216+
raise AttributeError("EntryPoint objects are immutable.")
217+
218+
def __repr__(self):
219+
return (
220+
f'EntryPoint(name={self.name!r}, value={self.value!r}, '
221+
f'group={self.group!r})'
222+
)
223+
224+
def __hash__(self):
225+
return hash(self._key())
226+
212227

213228
class DeprecatedList(list):
214229
"""
@@ -356,15 +371,11 @@ def groups(self):
356371
def _from_text_for(cls, text, dist):
357372
return cls(ep._for(dist) for ep in cls._from_text(text))
358373

359-
@classmethod
360-
def _from_text(cls, text):
361-
return itertools.starmap(EntryPoint, cls._parse_groups(text or ''))
362-
363374
@staticmethod
364-
def _parse_groups(text):
375+
def _from_text(text):
365376
return (
366-
(item.value.name, item.value.value, item.name)
367-
for item in Sectioned.section_pairs(text)
377+
EntryPoint(name=item.value.name, value=item.value.value, group=item.name)
378+
for item in Sectioned.section_pairs(text or '')
368379
)
369380

370381

importlib_metadata/_compat.py

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import platform
33

44

5-
__all__ = ['install', 'NullFinder', 'PyPy_repr', 'Protocol']
5+
__all__ = ['install', 'NullFinder', 'Protocol']
66

77

88
try:
@@ -66,27 +66,6 @@ def find_spec(*args, **kwargs):
6666
find_module = find_spec
6767

6868

69-
class PyPy_repr:
70-
"""
71-
Override repr for EntryPoint objects on PyPy to avoid __iter__ access.
72-
Ref #97, #102.
73-
"""
74-
75-
affected = hasattr(sys, 'pypy_version_info')
76-
77-
def __compat_repr__(self): # pragma: nocover
78-
def make_param(name):
79-
value = getattr(self, name)
80-
return f'{name}={value!r}'
81-
82-
params = ', '.join(map(make_param, self._fields))
83-
return f'EntryPoint({params})'
84-
85-
if affected: # pragma: nocover
86-
__repr__ = __compat_repr__
87-
del affected
88-
89-
9069
def pypy_partial(val):
9170
"""
9271
Adjust for variable stacklevel on partial under PyPy.

tests/test_main.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,9 @@ def test_discovery(self):
223223
class TestEntryPoints(unittest.TestCase):
224224
def __init__(self, *args):
225225
super(TestEntryPoints, self).__init__(*args)
226-
self.ep = importlib_metadata.EntryPoint('name', 'value', 'group')
226+
self.ep = importlib_metadata.EntryPoint(
227+
name='name', value='value', group='group'
228+
)
227229

228230
def test_entry_point_pickleable(self):
229231
revived = pickle.loads(pickle.dumps(self.ep))
@@ -263,8 +265,8 @@ def test_sortable(self):
263265
"""
264266
sorted(
265267
[
266-
EntryPoint('b', 'val', 'group'),
267-
EntryPoint('a', 'val', 'group'),
268+
EntryPoint(name='b', value='val', group='group'),
269+
EntryPoint(name='a', value='val', group='group'),
268270
]
269271
)
270272

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy