Skip to content

Commit 10c9d65

Browse files
committed
fix(ux): better error report when no links found
1 parent 78f39ae commit 10c9d65

File tree

1 file changed

+67
-1
lines changed

1 file changed

+67
-1
lines changed

src/poetry/installation/chooser.py

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,16 @@ def choose_for(self, package: Package) -> Link:
5050
Return the url of the selected archive for a given package.
5151
"""
5252
links = []
53+
54+
# these are used only for providing insightful errors to the user
55+
unsupported_wheels = set()
56+
links_seen = 0
57+
wheels_skipped = 0
58+
sdists_skipped = 0
59+
5360
for link in self._get_links(package):
61+
links_seen += 1
62+
5463
if link.is_wheel:
5564
if not self._no_binary_policy.allows(package.name):
5665
logger.debug(
@@ -59,6 +68,7 @@ def choose_for(self, package: Package) -> Link:
5968
link.filename,
6069
package.name,
6170
)
71+
wheels_skipped += 1
6272
continue
6373

6474
if not Wheel(link.filename).is_supported_by_environment(self._env):
@@ -67,6 +77,7 @@ def choose_for(self, package: Package) -> Link:
6777
" environment",
6878
link.filename,
6979
)
80+
unsupported_wheels.add(link.filename)
7081
continue
7182

7283
if link.ext in {".egg", ".exe", ".msi", ".rpm", ".srpm"}:
@@ -80,12 +91,67 @@ def choose_for(self, package: Package) -> Link:
8091
link.filename,
8192
package.name,
8293
)
94+
sdists_skipped += 1
8395
continue
8496

8597
links.append(link)
8698

8799
if not links:
88-
raise RuntimeError(f"Unable to find installation candidates for {package}")
100+
messages = []
101+
info = (
102+
f"This is likely not a Poetry issue.\n\n"
103+
f" - {links_seen} candidates were identified for the package\n"
104+
)
105+
106+
if wheels_skipped > 0:
107+
info += f" - {wheels_skipped} wheels were skipped due to your <c1>installer.no-binary</> policy\n"
108+
109+
if sdists_skipped > 0:
110+
info += f" - {sdists_skipped} source distributions were skipped due to your <c1>installer.only-binary</> policy\n"
111+
112+
if unsupported_wheels:
113+
info += (
114+
f" - {len(unsupported_wheels)} wheels were skipped as your project's environment does not support "
115+
f"the identified abi tags\n"
116+
)
117+
118+
messages.append(ConsoleMessage(info))
119+
120+
if unsupported_wheels:
121+
messages += [
122+
ConsoleMessage(
123+
"The following wheels were skipped as the current project environment does not support them "
124+
"due to abi compatibility issues.",
125+
debug=True,
126+
),
127+
ConsoleMessage("\n".join(unsupported_wheels), debug=True)
128+
.indent(" - ")
129+
.wrap("warning"),
130+
ConsoleMessage(
131+
"If you would like to see the supported tags in your project environment, you can execute "
132+
"the following command:\n\n"
133+
" <c1>python -c 'from packaging.tags import sys_tags; print(\"\\n\".join(set(str(t) for t in sys_tags())))'</>\n\n"
134+
"<warning>The above expects you to have <c1>packaging</> package installed in the environment.",
135+
debug=True,
136+
),
137+
]
138+
139+
messages.append(
140+
ConsoleMessage(
141+
f"Make sure the lockfile is up-to-date. You can try one of the following;\n\n"
142+
f" 1. <b>Regenerate lockfile: </><fg=yellow>poetry lock --no-cache --regenerate</>\n"
143+
f" 2. <b>Update package : </><fg=yellow>poetry update --no-cache {package.name}</>\n\n"
144+
f"If neither works, please check your source to verify {package.name} has released distributions "
145+
f"that are compatible with your current environment."
146+
)
147+
.make_section("Solutions")
148+
.wrap("info")
149+
)
150+
151+
raise PoetryRuntimeError(
152+
reason=f"Unable to find installation candidates for {package}",
153+
messages=messages,
154+
)
89155

90156
# Get the best link
91157
chosen = max(links, key=lambda link: self._sort_key(package, link))

0 commit comments

Comments
 (0)