Skip to content

Fix nested Concatenate with ellipsis crash#21414

Open
cyphercodes wants to merge 5 commits intopython:masterfrom
cyphercodes:fix/paramspec-nested-concatenate-ellipsis
Open

Fix nested Concatenate with ellipsis crash#21414
cyphercodes wants to merge 5 commits intopython:masterfrom
cyphercodes:fix/paramspec-nested-concatenate-ellipsis

Conversation

@cyphercodes
Copy link
Copy Markdown

Fixes #21404.

This rejects a nested Concatenate[...] when it appears in the prefix arguments of another Concatenate, including the Concatenate[Concatenate[...], ...] crash case from the issue. The existing nested-Concatenate error path only handled the ParamSpec-prefix form, so the ellipsis form could reach Parameters(...) with another Parameters object nested inside it.

Tests:

  • pytest -n0 mypy/test/testcheck.py::TypeCheckSuite::check-parameter-specification.test -k testStackedConcatenateIsIllegal -q
  • pytest -n0 mypy/test/testcheck.py::TypeCheckSuite::check-parameter-specification.test -q
  • python -m mypy --config-file mypy_self_check.ini mypy/typeanal.py
  • python -m mypy --config-file mypy_self_check.ini -p mypy
  • pre-commit run --files mypy/typeanal.py test-data/unit/check-parameter-specification.test
  • git diff --check

@github-actions

This comment has been minimized.

@A5rocks
Copy link
Copy Markdown
Collaborator

A5rocks commented May 7, 2026

IMO we should disallow Concatenate[...] there by construction, just like for Concatenate[P]. See:

from typing import Callable, Concatenate, ParamSpec

P = ParamSpec("P")
f: Callable[Concatenate[Concatenate[int, P], ...], object]  # E: Invalid location for Concatenate

Potentially related to #21425. I think this PR currently just duplicates effort.

@cyphercodes
Copy link
Copy Markdown
Author

Updated this PR to address the latest review feedback from @A5rocks:

  • Removed the local prefix-argument guard from apply_concatenate_operator.
  • Treat Parameters returned by nested Concatenate[...] the same way as the existing invalid Concatenate location path in anal_type, so the new Concatenate[Concatenate[...], ...] case is rejected by construction with the standard diagnostic.

Local verification:

  • python -m pytest -q 'mypy/test/testcheck.py::TypeCheckSuite::check-parameter-specification.test::testStackedConcatenateIsIllegal'
  • python -m pytest -q 'mypy/test/testcheck.py::TypeCheckSuite::check-parameter-specification.test::testParamSpecLocations' 'mypy/test/testcheck.py::TypeCheckSuite::check-parameter-specification.test::testParamSpecEllipsisInConcatenate' 'mypy/test/testcheck.py::TypeCheckSuite::check-parameter-specification.test::testStackedConcatenateIsIllegal'
  • git diff --check

@github-actions

This comment has been minimized.

@cyphercodes
Copy link
Copy Markdown
Author

Updated the expected output for the tuple/Concatenate data-case failure that showed up in CI.

Verification:

  • python3 -m pytest mypy/test/testcheck.py::TypeCheckSuite::check-tuples.test::testTuplePassedParameters -q
  • git diff --check

@github-actions

This comment has been minimized.

[case testTuplePassedParameters]
from typing_extensions import Concatenate

def c(t: tuple[Concatenate[int, ...]]) -> None: # E: Cannot use "[int, VarArg(Any), KwArg(Any)]" for tuple, only for ParamSpec
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think we can remove this old error codepath? I can't imagine a scenario where it's useful...

Comment thread mypy/typeanal.py Outdated
and analyzed.flavor == ParamSpecFlavor.BARE
):
if analyzed.prefix.arg_types:
if not allow_param_spec:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think this can be simpler if you check isinstance for the 2 types up here. Then you can deduplicate the error codepaths.

@cyphercodes
Copy link
Copy Markdown
Author

Updated this PR for the latest review feedback from @A5rocks:

  • Simplified the allow_param_spec=False handling by checking ParamSpecType/Parameters together and sharing the final error-type assignment.
  • Removed the old tuple[Concatenate[int, ...]] test case/error path from check-tuples.test.

Local verification:

  • python3 -m pytest -q mypy/test/testcheck.py --tb=short -k 'testParamSpecLocations or testParamSpecEllipsisInConcatenate or testStackedConcatenateIsIllegal'
  • python3 -m pytest -q mypy/test/testcheck.py --tb=short -k 'check-tuples.test'
  • git diff --check

@github-actions

This comment has been minimized.

@cyphercodes
Copy link
Copy Markdown
Author

Updated this PR to fix the CI self-typecheck failure after the last review update.

Change:

  • Added an explicit ParamSpecType narrowing assert before using .name in the non-Concatenate diagnostic path.

Local verification:

  • python3 -m mypy --config-file mypy_self_check.ini -p mypy -p mypyc -n0
  • python3 -m pytest -q mypy/test/testcheck.py --tb=short -k 'testParamSpecLocations or testParamSpecEllipsisInConcatenate or testStackedConcatenateIsIllegal'
  • python3 -m pytest -q mypy/test/testcheck.py --tb=short -k 'check-tuples.test'
  • git diff --check

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 7, 2026

According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅

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.

Assertion failure crash: assert not any(isinstance(t, Parameters) for t in arg_types)

2 participants