Skip to content

Commit 8c58148

Browse files
committed
Improve invalid entry-points traceback (#3684)
2 parents 07cd680 + 44a90b2 commit 8c58148

File tree

3 files changed

+63
-23
lines changed

3 files changed

+63
-23
lines changed

changelog.d/3684.misc.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improved exception/traceback when invalid entry-points are specified.

setuptools/_entry_points.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import operator
33
import itertools
44

5+
from .errors import OptionError
56
from .extern.jaraco.text import yield_lines
67
from .extern.jaraco.functools import pass_none
78
from ._importlib import metadata
@@ -14,7 +15,14 @@ def ensure_valid(ep):
1415
Exercise one of the dynamic properties to trigger
1516
the pattern match.
1617
"""
17-
ep.extras
18+
try:
19+
ep.extras
20+
except AttributeError as ex:
21+
msg = (
22+
f"Problems to parse {ep}.\nPlease ensure entry-point follows the spec: "
23+
"https://packaging.python.org/en/latest/specifications/entry-points/"
24+
)
25+
raise OptionError(msg) from ex
1826

1927

2028
def load_group(value, group):

setuptools/tests/test_egg_info.py

Lines changed: 53 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,18 @@
66
import stat
77
import time
88
from typing import List, Tuple
9+
from pathlib import Path
910

1011
import pytest
1112
from jaraco import path
1213

14+
from setuptools import errors
1315
from setuptools.command.egg_info import (
14-
egg_info, manifest_maker, EggInfoDeprecationWarning, get_pkg_info_revision,
16+
EggInfoDeprecationWarning,
17+
egg_info,
18+
get_pkg_info_revision,
19+
manifest_maker,
20+
write_entries,
1521
)
1622
from setuptools.dist import Distribution
1723

@@ -24,6 +30,28 @@ class Environment(str):
2430
pass
2531

2632

33+
@pytest.fixture
34+
def env():
35+
with contexts.tempdir(prefix='setuptools-test.') as env_dir:
36+
env = Environment(env_dir)
37+
os.chmod(env_dir, stat.S_IRWXU)
38+
subs = 'home', 'lib', 'scripts', 'data', 'egg-base'
39+
env.paths = dict(
40+
(dirname, os.path.join(env_dir, dirname))
41+
for dirname in subs
42+
)
43+
list(map(os.mkdir, env.paths.values()))
44+
path.build({
45+
env.paths['home']: {
46+
'.pydistutils.cfg': DALS("""
47+
[egg_info]
48+
egg-base = %(egg-base)s
49+
""" % env.paths)
50+
}
51+
})
52+
yield env
53+
54+
2755
class TestEggInfo:
2856

2957
setup_script = DALS("""
@@ -51,27 +79,6 @@ def _extract_mv_version(pkg_info_lines: List[str]) -> Tuple[int, int]:
5179
version_str = pkg_info_lines[0].split(' ')[1]
5280
return tuple(map(int, version_str.split('.')[:2]))
5381

54-
@pytest.fixture
55-
def env(self):
56-
with contexts.tempdir(prefix='setuptools-test.') as env_dir:
57-
env = Environment(env_dir)
58-
os.chmod(env_dir, stat.S_IRWXU)
59-
subs = 'home', 'lib', 'scripts', 'data', 'egg-base'
60-
env.paths = dict(
61-
(dirname, os.path.join(env_dir, dirname))
62-
for dirname in subs
63-
)
64-
list(map(os.mkdir, env.paths.values()))
65-
path.build({
66-
env.paths['home']: {
67-
'.pydistutils.cfg': DALS("""
68-
[egg_info]
69-
egg-base = %(egg-base)s
70-
""" % env.paths)
71-
}
72-
})
73-
yield env
74-
7582
def test_egg_info_save_version_info_setup_empty(self, tmpdir_cwd, env):
7683
"""
7784
When the egg_info section is empty or not present, running
@@ -1084,3 +1091,27 @@ def test_egg_info_tag_only_once(self, tmpdir_cwd, env):
10841091

10851092
def test_get_pkg_info_revision_deprecated(self):
10861093
pytest.warns(EggInfoDeprecationWarning, get_pkg_info_revision)
1094+
1095+
1096+
class TestWriteEntries:
1097+
1098+
def test_invalid_entry_point(self, tmpdir_cwd, env):
1099+
dist = Distribution({"name": "foo", "version": "0.0.1"})
1100+
dist.entry_points = {"foo": "foo = invalid-identifier:foo"}
1101+
cmd = dist.get_command_obj("egg_info")
1102+
expected_msg = r"Problems to parse .*invalid-identifier.*"
1103+
with pytest.raises(errors.OptionError, match=expected_msg) as ex:
1104+
write_entries(cmd, "entry_points", "entry_points.txt")
1105+
assert "ensure entry-point follows the spec" in ex.value.args[0]
1106+
1107+
def test_valid_entry_point(self, tmpdir_cwd, env):
1108+
dist = Distribution({"name": "foo", "version": "0.0.1"})
1109+
dist.entry_points = {
1110+
"abc": "foo = bar:baz",
1111+
"def": ["faa = bor:boz"],
1112+
}
1113+
cmd = dist.get_command_obj("egg_info")
1114+
write_entries(cmd, "entry_points", "entry_points.txt")
1115+
content = Path("entry_points.txt").read_text(encoding="utf-8")
1116+
assert "[abc]\nfoo = bar:baz\n" in content
1117+
assert "[def]\nfaa = bor:boz\n" in content

0 commit comments

Comments
 (0)