Skip to content

Commit 346ddf2

Browse files
committed
Fix sdist directory name extraction in _prepare_sdist
str.rstrip() treats its argument as a set of characters, not a suffix string. For a .tar.gz archive, archive.suffix returns '.gz', so rstrip('.gz') strips the characters {'.', 'g', 'z'} from the right, giving 'package-1.0.tar' instead of 'package-1.0'. For .zip files the character-stripping behavior can be even worse — e.g. 'zipp-24.0.0.zip'.rstrip('.zip') over-strips because the package name itself ends with characters in the strip set. Replace rstrip with proper suffix matching against known archive extensions.
1 parent ad9ab00 commit 346ddf2

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

pr_body_1.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
## Problem
2+
3+
`Executor._remove()` catches `CalledProcessError`, but `run_pip()` never raises that — it wraps it inside `EnvCommandError`:
4+
5+
```python
6+
def run_pip(self, *args, **kwargs) -> int:
7+
try:
8+
self._env.run_pip(*args, **kwargs)
9+
except EnvCommandError as e:
10+
...
11+
raise # re-raises EnvCommandError, not CalledProcessError
12+
return 0
13+
```
14+
15+
So the handler in `_remove()`:
16+
17+
```python
18+
except CalledProcessError as e:
19+
if "not installed" in str(e):
20+
return 0
21+
```
22+
23+
is dead code. When pip reports "not installed", the `EnvCommandError` propagates to `_execute_operation`, which treats it as a fatal error and sets `self._shutdown = True`, aborting the entire installation.
24+
25+
This can happen during `poetry update` if a package was already removed externally (e.g. `pip uninstall` by hand).
26+
27+
## Fix
28+
29+
Catch `EnvCommandError` instead of `CalledProcessError`, and remove the now-unused import.

src/poetry/installation/chef.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,14 @@ def _prepare_sdist(
108108
if len(elements) == 1 and elements[0].is_dir():
109109
sdist_dir = elements[0]
110110
else:
111-
sdist_dir = archive_dir / archive.name.rstrip(suffix)
111+
# Remove known archive suffixes properly — rstrip treats
112+
# its argument as a character set, not a suffix string.
113+
stem = archive.name
114+
for ext in (".tar.gz", ".tar.bz2", ".tar.xz", ".tar", ".zip"):
115+
if stem.endswith(ext):
116+
stem = stem[: -len(ext)]
117+
break
118+
sdist_dir = archive_dir / stem
112119
if not sdist_dir.is_dir():
113120
sdist_dir = archive_dir
114121

0 commit comments

Comments
 (0)