Skip to content
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

Python 3.10 match statement causing false positive unsupported-membership-test #5967

Closed
dragonpaw opened this issue Mar 25, 2022 · 5 comments
Labels
Astroid Related to astroid Control flow Requires control flow understanding Duplicate 🐫 Duplicate of an already existing issue False Positive 🦟 A message is emitted but nothing is wrong with the code inference Match case python 3.10

Comments

@dragonpaw
Copy link

dragonpaw commented Mar 25, 2022

Bug description

"""Strange pylint bug?

This code, when checked with pylint, will report an error on the line 25-27
"""


def test(thing: str | list | None) -> list[str]:
    """Breaks pylint. But not if written as an if statement. Has to be a match."""
    match thing:
        case list():
            return thing
        case str():
            return [thing]
        case None:
            return []
        case _:
            raise ValueError("WTF?")


test("foo")
test(list("foo"))
test(None)

# reports: Value 'test('foo')' doesn't support membership test (unsupported-membership-test)
print("foo" in test("foo"))
print("foo" in test(list("foo")))
print("foo" in test(None))

test(42)  # Raises correctly

Command used

pylint ~/src/wtf.py

Pylint output

************* Module wtf
/Users/ash/src/wtf.py:25:15: E1135: Value 'test('foo')' doesn't support membership test (unsupported-membership-test)
/Users/ash/src/wtf.py:26:15: E1135: Value 'test(list('foo'))' doesn't support membership test (unsupported-membership-test)
/Users/ash/src/wtf.py:27:15: E1135: Value 'test(None)' doesn't support membership test (unsupported-membership-test)

--------------------------------------------------------------------
Your code has been rated at -1.54/10 (previous run: -1.54/10, +0.00)

Expected behavior

It should accept that the function will always return a list of strings:

python  ~/src/wtf.py
True
False
False
Traceback (most recent call last):
  File "/Users/ash/src/wtf.py", line 29, in <module>
    test(42)  # Raises correctly
  File "/Users/ash/src/wtf.py", line 17, in test
    raise ValueError("WTF?")
ValueError: WTF?

Pylint version

pylint 2.12.2
astroid 2.9.3
Python 3.10.3 (main, Mar 21 2022, 18:14:33) [Clang 12.0.5 (clang-1205.0.22.9)]

OS / Environment

Python 3.10.3 via pyenv on a Mac.

@dragonpaw dragonpaw added the Needs triage 📥 Just created, needs acknowledgment, triage, and proper labelling label Mar 25, 2022
@jacobtylerwalls
Copy link
Member

Thanks for the report. pylint relies on astroid to infer values of variables, and astroid doesn't understand control-flow from isinstance() checks or type annotations, either of which would help solve this problem. Also, it doesn't understand that the catch-all case at the end raises an exception. So astroid just infers that test("foo") returns None (from the function's implicit return).

Related:
control-flow for isinstance, but not in a match context: #1498, #1162

@jacobtylerwalls jacobtylerwalls added Enhancement ✨ Improvement to a component Astroid Related to astroid Control flow Requires control flow understanding False Positive 🦟 A message is emitted but nothing is wrong with the code inference Bug 🪲 and removed Needs triage 📥 Just created, needs acknowledgment, triage, and proper labelling Enhancement ✨ Improvement to a component labels Mar 25, 2022
@Pierre-Sassoulas Pierre-Sassoulas added Needs PR This issue is accepted, sufficiently specified and now needs an implementation and removed Bug 🪲 labels Jul 13, 2022
@sinisarudan
Copy link

confirming this too.
It prevents us from deploying the regularly working 3.10 code with match - case :(

@sinisarudan
Copy link

is there a workaround to disable this false syntax-error?

@Pierre-Sassoulas
Copy link
Member

Pierre-Sassoulas commented Aug 25, 2022

You can use message control ( # pylint: disable=message-name) see https://pylint.pycqa.org/en/latest/user_guide/messages/message_control.html

@jacobtylerwalls
Copy link
Member

Duplicate of #5288

@jacobtylerwalls jacobtylerwalls marked this as a duplicate of #5288 Feb 13, 2023
@jacobtylerwalls jacobtylerwalls closed this as not planned Won't fix, can't repro, duplicate, stale Feb 13, 2023
@jacobtylerwalls jacobtylerwalls added Duplicate 🐫 Duplicate of an already existing issue and removed Needs PR This issue is accepted, sufficiently specified and now needs an implementation labels Feb 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Astroid Related to astroid Control flow Requires control flow understanding Duplicate 🐫 Duplicate of an already existing issue False Positive 🦟 A message is emitted but nothing is wrong with the code inference Match case python 3.10
Projects
None yet
Development

No branches or pull requests

5 participants