Skip to content

Fix mypy errors from deprecated click.MultiCommand isinstance check#203

Closed
adamtheturtle wants to merge 1 commit into
janluke:masterfrom
adamtheturtle:adamtheturtle/fix-multicommand-mypy
Closed

Fix mypy errors from deprecated click.MultiCommand isinstance check#203
adamtheturtle wants to merge 1 commit into
janluke:masterfrom
adamtheturtle:adamtheturtle/fix-multicommand-mypy

Conversation

@adamtheturtle

@adamtheturtle adamtheturtle commented May 25, 2026

Copy link
Copy Markdown
Contributor

Fixes #202.

click.MultiCommand is deprecated since Click 8 and is no longer usable as the second argument to isinstance at the type level, causing mypy cloup to fail on master with two errors in cloup/_commands.py. click.Group exposes format_commands on every supported Click version (>= 8.0), so the behavior at runtime is unchanged. This also silences the DeprecationWarning emitted when format_help is called on a group.

In practice, the only MultiCommand cloup ever produces is cloup.Group (which subclasses click.Group), so the original check was already effectively a Group check.

Test plan

Tested across the full supported Click range (>= 8.0, < 9.0), Python 3.12, mypy 2.1.0:

Click pytest mypy --strict cloup
8.0.4 3 failures (pre-existing on master) 2 errors (pre-existing on master)
8.1.8 328 pass clean
8.2.1 328 pass clean
8.3.3 328 pass clean
8.4.1 328 pass 1 error in _params.pyi (fixed by #201)

The Click 8.0 issues reproduce on master without this change and are unrelated:

  • pytest: cloup/types.py passes executable=... to click.Path, a kwarg added in a later Click 8.x
  • mypy: two # type: ignore comments on @overload decorators (lines 273, 350) become unused because the underlying mypy warning doesn't fire against Click 8.0's older stubs

🤖 Generated with Claude Code

Fixes janluke#202.

`click.MultiCommand` is deprecated since Click 8 and is no longer usable
as the second argument to `isinstance` at the type level, which caused
`mypy cloup` to fail with two errors on master. `click.Group` exposes
`format_commands` on both Click 8.3 and 8.4, so the behavior is
unchanged. This also silences the runtime DeprecationWarning emitted
when calling `format_help` on a group.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@janluke

janluke commented May 26, 2026

Copy link
Copy Markdown
Owner

This change would break compatibility with click 8.1. Think of a user on click 8.1 who still uses a MultiCommand that is not a Group. For such user, Cloup would silently skip the commands section because a MultiCommand is not a Group. I'll fix this separately.

Easiest way is to require click >= 8.2. In that case, everything's fine because _MultiCommand subclasses Group. Nonetheless, I still need to support 8.1 because that's the only version that works in Python 3.9 and I can't drop support at this time (even if it's planned) as it breaks a bunch of stuff (e.g. docs with very old dependencies that I have no time to fix now).

So I will do this instead:

  • I requires click >= 8.1. This will make it impossible the bug with 8.0.
  • I'll replace the isinstance check in this PR with just __has_attr__(self, "format_commands") for now.

Closing this PR, as I'll apply the above changes instead. But thank you very much for this!

@janluke janluke closed this May 26, 2026
@adamtheturtle

Copy link
Copy Markdown
Contributor Author

Thank you!

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.

mypy fails on master with two errors in cloup/_commands.py

2 participants