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

Wrong number of arguments for callable #8618

Closed
vikigenius opened this issue Apr 1, 2020 · 2 comments
Closed

Wrong number of arguments for callable #8618

vikigenius opened this issue Apr 1, 2020 · 2 comments

Comments

@vikigenius
Copy link

I posted a stackoverflow question about this, and then came to realize that this is a bug on mypy: https://stackoverflow.com/questions/60981471/python-function-object-as-a-class-attribute

Reproducing here for completeness

Consider two alternative definitions of the class Replace

import re
from dataclasses import dataclass
from typing import Callable, Match


@dataclass
class Replace1(object):
    """Dataclass that stores info about replacement protocol."""

    replstr: str = ''
    predicate: Callable[[str], bool] = lambda string: True

    def __call__(self, match: Match[str]) -> str:
        """Callable that returns the replacement given a match."""
        matched: str = match.group(0)
        return match.expand(self.replstr) if self.predicate(matched) else matched # This is a complaint in self.predicate(matched)

@dataclass
class Replace2(object):
    """Dataclass that stores info about replacement protocol."""

    replstr: str = ''
    predicate: Callable[['Replace2', str], bool] = lambda repl, string: True

    def __call__(self, match: Match[str]) -> str:
        """Callable that returns the replacement given a match."""
        matched: str = match.group(0)
        return match.expand(self.replstr) if self.predicate(matched) else matched

Both Replace1 and Replace2 seem to work the exact same way

r1 = Replace1(predicate=lambda x: len(x.split()) > 5)
r2 = Replace2(predicate=lambda x: len(x.split()) > 5) # This is a complaint in lambda


pattern = re.compile(r'(?:\w+\s*)+')

match1 = re.match(pattern, 'This will prevail')
match2 = re.match(pattern, 'This is too long and will be destroyed')

assert r1(match1) == 'This will prevail'
assert r2(match1) == 'This will prevail'
assert r1(match2) == ''
assert r2(match2) == ''

However mypy seems to complain about self.predicate(matched) having too many arguments in Replace1. And also seems to be complaining about Replace2(predicate=lambda x: len(x.split()) > 5) not having enough arguments.

What exactly is happening? How do I get the desired behavior and not have mypy complain ?

@JelleZijlstra
Copy link
Member

This sounds like a variant of #5485.

@msullivan
Copy link
Collaborator

I think I agree that this is #5485.

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

No branches or pull requests

3 participants