Skip to content

attrs match type narrowing failure #13804

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Tinche opened this issue Oct 3, 2022 · 3 comments
Closed

attrs match type narrowing failure #13804

Tinche opened this issue Oct 3, 2022 · 3 comments
Labels
bug mypy got something wrong

Comments

@Tinche
Copy link
Contributor

Tinche commented Oct 3, 2022

Bug Report

Hello Mypy friends!

While playing around with yet another proposal for sum types (typing-sig message forthcoming), I think I found a small issue with attrs and the match statement.

To Reproduce

from typing import Generic, TypeVar

from attrs import frozen
from typing_extensions import assert_never

T = TypeVar("T")


@frozen
class Some(Generic[T]):
    val: T

Expected and Actual Behavior

Now we define a function that handles it.

def takes_opt(opt: Some[int]) -> None:
    match opt:
        case Some(val):
            reveal_type(opt)  # Correct, Some[int]
            reveal_type(opt.val)  # Correct, int
            reveal_type(val)  # Incorrect, Any
            pass
        case _:
            assert_never(opt)

So I'm going to guess it's an issue with how we generate attrs __match_args__, maybe for generic types. I might try solving this myself, or it would be awesome if someone more knowledgeable could solve it first.

If I use dataclasses it works properly.

Your Environment

  • Mypy version used: mypy 0.982 (compiled: yes)
  • Mypy command-line flags:
  • Mypy configuration options from mypy.ini (and other config files):
  • Python version used: Python 3.10.6
@Tinche Tinche added the bug mypy got something wrong label Oct 3, 2022
@sobolevn
Copy link
Member

sobolevn commented Oct 4, 2022

Not directly related, but check out our Some implementation: https://returns.readthedocs.io/en/latest/pages/maybe.html

@mgedmin
Copy link
Contributor

mgedmin commented Nov 9, 2024

I think I stumbled upon this bug too. Given

class PrintableKey(bytes):
    __match_args__ = ('ch', )

    @property
    def ch(self) -> str:
        return self.decode('UTF-8')

now

match event:
    case PrintableKey(ch):
        reveal_type(ch)  # mypy thinks it's PrintableKey

versus

match event:
    case PrintableKey(ch=ch):
        reveal_type(ch)  # mypy correctly deduces it's str

@brianschubert
Copy link
Collaborator

Duplicate of #13612. This bug was fixed in #13618, which landed with v0.990.

@mgedmin Good find! That's a different bug (one that has to do with some special handling for class patterns involving builtin types). Could you please open a new issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong
Projects
None yet
Development

No branches or pull requests

4 participants