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

False positive when combining walrus operator and regex #8260

Closed
coiax opened this issue Jan 8, 2020 · 3 comments
Closed

False positive when combining walrus operator and regex #8260

coiax opened this issue Jan 8, 2020 · 3 comments
Labels
topic-pep-572 PEP 572 (walrus operator)

Comments

@coiax
Copy link

coiax commented Jan 8, 2020

I think I've discovered the following bug, involving the walrus operator, and regular expressions, although I'm sure it's not exclusive to regex.

import re


def foo1(bar: str):
    if match := re.match(r'a(.*)', bar):
        group1 = match.group(1)

def foo2(bar: str):
    if (match := re.match(r'b(.*)', bar)) is not None:
        group2 = match.group(1)

def foo3(bar: str):
    if match := re.match(r'c(.*)', bar) and match is not None:
        group3 = match.group(1)

def foo4(bar: str):
    if match := re.match(r'd(.*)', bar):
        if match is not None:
            group4 = match.group(1)

def foo5(bar: str):
    if match := re.match(r'e(.*)', bar):
        if match:
            group5 = match.group(1)
  • What is the actual behavior/output?
bad.py:6: error: Item "None" of "Optional[Match[str]]" has no attribute "group"  [union-attr]
bad.py:10: error: Item "None" of "Optional[Match[str]]" has no attribute "group"  [union-attr]
bad.py:13: error: Cannot determine type of 'match'  [has-type]
bad.py:14: error: Item "None" of "Union[Match[str], None, bool]" has no attribute "group"  [union-attr]
bad.py:14: error: Item "bool" of "Union[Match[str], None, bool]" has no attribute "group"  [union-attr]
Found 5 errors in 1 file (checked 1 source file)
  • What is the behavior/output you expect?
    I expect all functions to pass type checking.
    All MatchObjects are always true, so all of the if blocks will only be entered if a match is found, but mypy complains about foo1, foo2, and foo3. foo4 and foo5 pass.

  • What are the versions of mypy and Python you are using?
    Python 3.8.1
    mypy 0.761

  • Do you see the same issue after installing mypy from Git master?
    Yes. git master version was mypy 0.770+dev.35b50397cabd36066d2dd92b979794b94f1741d3

  • What are the mypy flags you are using? (For example --strict-optional)
    No flags.

@coiax
Copy link
Author

coiax commented Jan 8, 2020

This isn't regex specific, I think it's likely to occur in any Optional[AlwaysTrue] when used in a walrus operator?

import random
from typing import Optional

class Truth:
    heart = '💖'
    def __bool__(self):
        return True

def seek() -> Optional[Truth]:
    if random.random() < 0.5:
        return None
    else:
        return Truth()

if discovery := seek():
    print(discovery.heart)
ugly_truth.py:16: error: Item "None" of "Optional[Truth]" has no attribute "heart"
Found 1 error in 1 file (checked 1 source file)

@JelleZijlstra JelleZijlstra added the topic-pep-572 PEP 572 (walrus operator) label Jan 8, 2020
@JelleZijlstra
Copy link
Member

This is #7316.

@coiax
Copy link
Author

coiax commented Jan 8, 2020

Apologies, I did search for "walrus" before hand, but didn't find anything.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic-pep-572 PEP 572 (walrus operator)
Projects
None yet
Development

No branches or pull requests

2 participants