diff --git a/importlib_metadata/__init__.py b/importlib_metadata/__init__.py index 3796fbce..0eebf847 100644 --- a/importlib_metadata/__init__.py +++ b/importlib_metadata/__init__.py @@ -179,9 +179,10 @@ class EntryPoint: ... ValueError: ('Invalid object reference...invalid-name... - The same thing happens on construction. + The invalid value is stored during construction and raises when accessed + or loaded. - >>> EntryPoint(name=None, group=None, value='invalid-name') + >>> EntryPoint(name=None, group=None, value='invalid-name').load() Traceback (most recent call last): ... ValueError: ('Invalid object reference...invalid-name... @@ -217,8 +218,6 @@ class EntryPoint: def __init__(self, name: str, value: str, group: str) -> None: vars(self).update(name=name, value=value, group=group) - # resolve the value now, raising ValueError if it's invalid - _ = self.module def load(self) -> Any: """Load the entry point from its definition. If only a module diff --git a/newsfragments/523.bugfix.rst b/newsfragments/523.bugfix.rst new file mode 100644 index 00000000..3519d5cb --- /dev/null +++ b/newsfragments/523.bugfix.rst @@ -0,0 +1,2 @@ +Defer validation of invalid ``EntryPoint.value`` values until their components +are accessed or they are loaded. diff --git a/tests/test_api.py b/tests/test_api.py index 1468e0a9..59d0a52d 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -132,6 +132,34 @@ def test_entry_points_missing_name(self): def test_entry_points_missing_group(self): assert entry_points(group='missing') == () + def test_entry_points_with_invalid_value_in_unselected_group(self): + alt_site_dir = self.fixtures.enter_context(fixtures.tmp_path()) + self.fixtures.enter_context(self.add_sys_path(alt_site_dir)) + pkg = { + "invalid-entry-points-1.0.dist-info": { + "METADATA": """ + Name: invalid-entry-points + Version: 1.0.0 + """, + "entry_points.txt": textwrap.dedent( + """ + [selected] + valid = importlib_metadata:EntryPoint + + [unselected] + invalid = invalid-name + """ + ), + }, + } + fixtures.build_files(pkg, alt_site_dir) + + entries = entry_points(group='selected') + + self.assertEqual([ep.name for ep in entries], ['valid']) + with self.assertRaises(ValueError): + entry_points(group='unselected')['invalid'].load() + def test_entry_points_allows_no_attributes(self): ep = entry_points().select(group='entries', name='main') with self.assertRaises(AttributeError):