Skip to content

fix(show): pick the env-compatible version for duplicated lock entries - #11003

Open
tarann26 wants to merge 2 commits into
python-poetry:mainfrom
tarann26:fix-8945-show-single-package-env-marker
Open

fix(show): pick the env-compatible version for duplicated lock entries#11003
tarann26 wants to merge 2 commits into
python-poetry:mainfrom
tarann26:fix-8945-show-single-package-env-marker

Conversation

@tarann26

Copy link
Copy Markdown

Pull Request Check List

Resolves: #8945

  • Added tests for changed code.
  • Updated documentation for changed code.

Problem

poetry show <package> reports the wrong version when the lock file contains multiple entries for the same package (e.g. marker-conditioned variants for different Python versions or platforms). _display_single_package_information() picks the first name-match and ignores environment markers:

for locked in locked_packages:
    if locked.name == canonicalized_package:
        pkg = locked
        break

So poetry show <pkg> can print a different version than poetry show (all packages) does for the same environment — the two views disagree, and the single-package view is the wrong one.

Fix

Make the single-package path select the environment-appropriate entry the same way the all-packages path already does. The solver-based environment resolution (Solver(...).use_environment(self.env)required_locked_packages) is extracted into a shared helper _required_locked_packages() used by both paths, so they can no longer disagree.

To keep the common case free of any new cost, the solver is only consulted when a package actually has more than one lock entry; for the usual single-entry case, selection and output are byte-identical to before. If none of the duplicate entries applies to the current environment, it falls back to the first match (so show still displays something rather than erroring). The fix is marker-agnostic — it works for python_version, sys_platform, and any other environment markers, since it defers entirely to the solver's environment resolution.

Note on a behaviour change

Because the single-package path now reuses the group-activated project root (needed so its selection matches the all-packages view), poetry show <pkg> now validates --only/--with/--without group names the same way poetry show already does: an undeclared group name now raises GroupNotFoundError instead of being silently ignored. Valid invocations and the plain poetry show <pkg> are unaffected. Happy to scope this out (only activate groups when duplicates are present) if you'd prefer to preserve the previous lenient behaviour for the single-package path.

Test

Adds tests in tests/console/commands/test_show.py (mirroring test_show_hides_incompatible_package_with_duplicate): a package with two marker-conditioned lock entries is shown with the environment-appropriate version, in both text and JSON output, plus a fallback case for when no entry applies to the current environment.

`poetry show <package>` selected the first lock-file entry matching the
package name, ignoring environment markers. When poetry.lock contains
several marker-conditioned entries for the same package (e.g. one per
platform), the single-package view could report a version that does not
apply to the current environment, disagreeing with the all-packages
`poetry show`.

Compute the environment-appropriate locked packages the same way the
all-packages path does, via a shared `_required_locked_packages` helper,
and select the matching entry from that set. Fall back to the first match
when none applies so the command still displays a version.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="tests/console/commands/test_show.py" line_range="1918-1927" />
<code_context>
+def test_show_single_package_with_duplicate_falls_back_when_env_excluded_8945(
</code_context>
<issue_to_address>
**suggestion (testing):** Fallback behavior when no env-compatible duplicate exists is only tested for text output; JSON output for the same scenario is untested.

Since the new env-compatible test already parametrizes `output_format` for both text and JSON, it would be good to do the same here so the fallback-to-first-match behavior is covered for `-f json` as well as text. You can either parametrize this test with `output_format_parametrize` to include JSON, or add a dedicated JSON test using `tester.execute("cachy -f json")` and asserting the result still falls back to version `0.1.0` when no lock entry matches the current environment.

Suggested implementation:

```python
@pytest.mark.parametrize("output_format", output_format_parametrize)
def test_show_single_package_with_duplicate_falls_back_when_env_excluded_8945(
    tester: CommandTester,
    poetry: Poetry,
    installed: Repository,
    repo: DummyRepository,
    output_format: str,
) -> None:

```

To fully implement the suggestion, the body of `test_show_single_package_with_duplicate_falls_back_when_env_excluded_8945` must be updated to:
1. Use `output_format` when invoking the command, e.g. `tester.execute(["show", "cachy", "-f", output_format])` or matching whatever convention other `output_format_parametrize` tests in this file already use.
2. Add conditional assertions similar to the existing env-compatible duplicate test:
   - For JSON: `result = json.loads(tester.io.fetch_output()); assert result["version"] == "0.1.0"`.
   - For text: `output = tester.io.fetch_output(); assert "0.1.0" in output` and assert that no other duplicate version is shown (e.g. `"0.1.1" not in output`), matching the expected fallback-to-first-match behavior.
3. Ensure any setup that currently assumes text output (e.g. checking strings directly) is moved under the `else` branch, with JSON-specific checks under the `if "json" in output_format:` branch, consistent with the pattern used in the existing parametrized duplicate-env-compatible test above.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +1918 to +1927
def test_show_single_package_with_duplicate_falls_back_when_env_excluded_8945(
tester: CommandTester,
poetry: Poetry,
installed: Repository,
repo: DummyRepository,
) -> None:
# https://github.com/python-poetry/poetry/issues/8945
# If none of the duplicate lock entries applies to the current environment,
# `poetry show <package>` should still display a version (the first match)
# rather than raising.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Fallback behavior when no env-compatible duplicate exists is only tested for text output; JSON output for the same scenario is untested.

Since the new env-compatible test already parametrizes output_format for both text and JSON, it would be good to do the same here so the fallback-to-first-match behavior is covered for -f json as well as text. You can either parametrize this test with output_format_parametrize to include JSON, or add a dedicated JSON test using tester.execute("cachy -f json") and asserting the result still falls back to version 0.1.0 when no lock entry matches the current environment.

Suggested implementation:

@pytest.mark.parametrize("output_format", output_format_parametrize)
def test_show_single_package_with_duplicate_falls_back_when_env_excluded_8945(
    tester: CommandTester,
    poetry: Poetry,
    installed: Repository,
    repo: DummyRepository,
    output_format: str,
) -> None:

To fully implement the suggestion, the body of test_show_single_package_with_duplicate_falls_back_when_env_excluded_8945 must be updated to:

  1. Use output_format when invoking the command, e.g. tester.execute(["show", "cachy", "-f", output_format]) or matching whatever convention other output_format_parametrize tests in this file already use.
  2. Add conditional assertions similar to the existing env-compatible duplicate test:
    • For JSON: result = json.loads(tester.io.fetch_output()); assert result["version"] == "0.1.0".
    • For text: output = tester.io.fetch_output(); assert "0.1.0" in output and assert that no other duplicate version is shown (e.g. "0.1.1" not in output), matching the expected fallback-to-first-match behavior.
  3. Ensure any setup that currently assumes text output (e.g. checking strings directly) is moved under the else branch, with JSON-specific checks under the if "json" in output_format: branch, consistent with the pattern used in the existing parametrized duplicate-env-compatible test above.

Parametrize test_show_single_package_with_duplicate_falls_back_when_env_excluded_8945
over text and json output, matching the env-compatible duplicate test, so the
fall-back-to-first-match behaviour is verified for both formats.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

poetry show <package> outputs incorrect version when poetry.lock contains multiple version for same package.

1 participant