feat(show): show wanted version for outdated packages - #10961
Open
Yijian6 wants to merge 1 commit into
Open
Conversation
There was a problem hiding this comment.
Hey - I've found 2 issues, and left some high level feedback:
- In
find_wanted_package, you construct a newVersionSelectoron every call; consider instantiating it once (e.g. as a cached attribute on the command) and reusing it to avoid repeated allocations duringshow --outdatedon larger dependency sets. - When
--outdatedis used without--latest,wanted_packagesis still populated but never read; you can skip computingwanted(andwanted_length) unlessshow_latestis true to reduce unnecessary work.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `find_wanted_package`, you construct a new `VersionSelector` on every call; consider instantiating it once (e.g. as a cached attribute on the command) and reusing it to avoid repeated allocations during `show --outdated` on larger dependency sets.
- When `--outdated` is used without `--latest`, `wanted_packages` is still populated but never read; you can skip computing `wanted` (and `wanted_length`) unless `show_latest` is true to reduce unnecessary work.
## Individual Comments
### Comment 1
<location path="tests/console/commands/test_show.py" line_range="902-899" />
<code_context>
+@output_format_parametrize
</code_context>
<issue_to_address>
**suggestion (testing):** Add a test case for transitive dependencies without root constraints where `wanted_version` should fall back to the latest version
The new test covers the capped-by-root-constraint case well, but there’s no test for the transitive-only case where no root requirement matches and `find_wanted_package` should set `wanted` to `latest`.
Please add a companion test that:
- Omits the `poetry.package.add_dependency(...)` call (making the dependency transitive-only).
- Asserts `wanted_version == 0.3.0` (the latest) instead of `0.2.0`.
- Uses `@output_format_parametrize` to cover both JSON and text output.
This will exercise the "no root constraint" branch and protect against regressions where `wanted_version` might incorrectly fall back to the installed version for transitive dependencies.
Suggested implementation:
```python
@output_format_parametrize
def test_show_outdated_wanted_version_transitive_dependency_uses_latest(
output_format: str,
tester: CommandTester,
poetry: Poetry,
installed: Repository,
repo: DummyRepository,
) -> None:
# Note: no poetry.package.add_dependency(...) here – cachy is only a transitive dependency
# Ensure the repository has a higher version available so that "latest" is 0.3.0
# (the concrete way to add packages should mirror the surrounding tests)
repo.add_package(Package("cachy", "0.3.0"))
if output_format == "json":
tester.execute("show cachy --outdated --format=json")
expected = {
"name": "cachy",
"current_version": "0.1.0",
"wanted_version": "0.3.0",
"latest_version": "0.3.0",
"description": "Cachy package",
"latest_status": "latest",
"installed_status": "installed",
}
assert json.loads(tester.io.fetch_output()) == expected
else:
tester.execute("show cachy --outdated")
expected = """\
cachy 0.1.0 0.3.0 0.3.0 Cachy package
"""
assert tester.io.fetch_output() == expected
@output_format_parametrize
def test_show_outdated_wanted_version_respects_dependency_constraint(
output_format: str,
tester: CommandTester,
poetry: Poetry,
installed: Repository,
repo: DummyRepository,
) -> None:
poetry.package.add_dependency(
Factory.create_dependency("cachy", ">=0.1.0,<0.3.0")
)
```
To integrate this cleanly with the existing test suite, you should:
1. Align the way the `Package("cachy", "0.3.0")` object is constructed with the rest of the file.
- If other tests use a helper like `get_package("cachy", "0.3.0")` or `Factory.create_poetry_package(...)`, use that instead of directly instantiating `Package`.
- If `Package` is not already imported in this file, either import it or adjust `repo.add_package(...)` to use the same factory/helper as the surrounding tests.
2. Ensure the CLI invocation matches the rest of the show/outdated tests:
- If other tests use `tester.execute("show cachy --outdated --format {}".format(output_format))` or `["show", "cachy", "--outdated", f"--format={output_format}"]`, mirror that pattern instead of the bare string used here.
- If the command is invoked without the package name for these scenarios (e.g. `show --outdated` lists all packages), adapt the `tester.execute(...)` call and the expected output accordingly so that we still assert `wanted_version == "0.3.0"` for `cachy`.
3. Adjust the expected JSON/text structure to match the actual schema used in this file:
- If the JSON payload uses different keys (e.g. `"version"` vs `"wanted_version"`) or nests package info in a list, update the `expected` structure and assertions accordingly, ensuring the test explicitly checks that the *wanted* version for `cachy` is `"0.3.0"`.
- Similarly, if the text output format uses a different column order, update the string so the “wanted” column is `0.3.0`, while “latest” still reflects the true latest (here also `0.3.0`).
These adjustments will make the new test a true companion to `test_show_outdated_wanted_version_respects_dependency_constraint` and ensure it exercises the “no root constraint / transitive-only” branch of `find_wanted_package`.
</issue_to_address>
### Comment 2
<location path="tests/console/commands/test_show.py" line_range="1280-1281" />
<code_context>
expected = """\
-cachy 0.1.0 0.2.0 Cachy package
-pendulum 2.0.0 2.0.1 Pendulum package
+cachy 0.1.0 0.1.0 0.2.0 Cachy package
+pendulum 2.0.0 2.0.1 2.0.1 Pendulum package
"""
assert tester.io.fetch_output() == expected
</code_context>
<issue_to_address>
**suggestion (testing):** Consider adding a narrow-terminal-width test to exercise the `write_wanted` and alignment logic
Since the new layout logic (`write_wanted`, `wanted_column_length`, updated `write_latest`, `why_end_column`, truncation) behaves differently on narrow terminals, it would be good to add a test that forces a small terminal width (e.g. via monkeypatching `shutil.get_terminal_size`) and verifies that when `write_wanted` is false, the `wanted_version` column is omitted while `latest_version` and descriptions still render with correct alignment/truncation.
Suggested implementation:
```python
expected = """\
@output_format_parametrize
def test_show_outdated_omits_wanted_column_on_narrow_terminal(
output_format: str,
tester: CommandTester,
poetry: Poetry,
installed: Repository,
repo: DummyRepository,
monkeypatch,
) -> None:
import os
import shutil
import pytest
# Only the human-readable text output exercises the column-width logic.
if output_format != "text":
pytest.skip("narrow-terminal layout is only relevant for text output")
# Force a very narrow terminal width so that the wanted column is dropped.
monkeypatch.setattr(
shutil,
"get_terminal_size",
lambda fallback=(80, 20): os.terminal_size((40, fallback[1])),
)
# Execute the `show outdated` command; fixtures set up outdated packages.
tester.execute("show", "outdated", "--format", output_format)
output = tester.io.fetch_output()
# When the terminal is narrow, the wanted column should be omitted while
# latest versions are still shown. We assert this structurally without
# depending on exact spacing.
lines = [line for line in output.splitlines() if line.strip()]
# Find lines corresponding to our known packages.
cachy_line = next(line for line in lines if "cachy" in line)
pendulum_line = next(line for line in lines if "pendulum" in line)
# Ensure that the "wanted" versions are not rendered, while installed/latest
# versions still appear. The concrete version values come from the fixtures.
# We rely on the fact that wanted_version != latest_version for these
# dependencies, so if the wanted column was rendered we'd see both.
assert cachy_line.count(".") <= 2
assert pendulum_line.count(".") <= 2
# Descriptions should still be aligned even when the wanted column is dropped.
# We approximate this by checking that the descriptions for different packages
# start at the same column.
# The description strings come from the repo fixtures, e.g. "Cachy package".
cachy_desc_token = "Cachy"
pendulum_desc_token = "Pendulum"
assert cachy_desc_token in cachy_line
assert pendulum_desc_token in pendulum_line
cachy_desc_start = cachy_line.index(cachy_desc_token)
pendulum_desc_start = pendulum_line.index(pendulum_desc_token)
assert cachy_desc_start == pendulum_desc_start
@output_format_parametrize
def test_show_outdated_wanted_version_respects_dependency_constraint(
output_format: str,
tester: CommandTester,
poetry: Poetry,
installed: Repository,
repo: DummyRepository,
) -> None:
```
1. Ensure that the fixtures used in this file always create outdated entries for `cachy` and `pendulum` with distinct `wanted_version` and `latest_version` values so that the `count(".")` heuristic correctly distinguishes between layouts with and without the wanted column.
2. If `shutil.get_terminal_size` is imported or referenced through a different module path inside the show command implementation (for example, `poetry.console.commands.show.shutil` or `poetry.console.commands.show_command.shutil`), adjust the `monkeypatch.setattr` target accordingly to patch the exact object used by the command.
3. If this test file does not currently import `pytest`, you may prefer to add a single top-level `import pytest` and remove the inline import inside the test function to match existing style in the file.
4. If the version strings or description tokens differ from those used in this test (`"Cachy"` and `"Pendulum"`), update the token strings to match the actual descriptions used by the fixtures so that the alignment assertion remains valid.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Yijian6
force-pushed
the
show-outdated-wanted-version
branch
2 times, most recently
from
June 24, 2026 04:22
7af72cb to
96285ae
Compare
Yijian6
force-pushed
the
show-outdated-wanted-version
branch
from
June 24, 2026 04:28
96285ae to
fc3d9c5
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds a wanted version to
poetry show --outdatedtext output and JSON output.Why
Closes #9495.
poetry show --outdatedcurrently reports the installed version and the latest version, but it does not show the highest version that still satisfies the project's dependency constraint. This makes it harder to tell whether a dependency can be updated with the current constraint or needs a constraint change.How
When
--outdatedis used, the command now resolves a constraint-compatible candidate from the active root dependency constraints and displays it between the installed and latest versions. Direct-origin dependencies keep their direct-origin display behavior, and transitive dependencies without a root constraint continue to use the latest version.Testing
python -m pytest tests\console\commands\test_show.py -q -k "outdated and not local_dependencies"python -m pytest tests\console\commands\test_show.py::test_show_latest_non_decorated tests\console\commands\test_show.py::test_show_latest_decorated -qruff check src\poetry\console\commands\show.py tests\console\commands\test_show.pymypy src\poetry\console\commands\show.pyBreaking changes
None. The JSON output gains a
wanted_versionfield for--outdatedresults.