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 too-few-public-methods when inheriting from a Generic class #2607

Closed
jindrahelcl opened this issue Nov 25, 2018 · 7 comments
Closed

Comments

@jindrahelcl
Copy link

Hi there, here's a bug in handling generics I discovered. (Somewhat related to #2568.)
When I try to inherit from a generic class (while fixing the type parameter), Pylint does not seem
to find the inherited methods. In the following example, if you remove the [int] part in the World class definition, it works as expected.

Steps to reproduce

# pylint: disable=no-self-use
from typing import Generic, TypeVar

MyGenericType = TypeVar("MyGenericType")

class Hello(Generic[MyGenericType]):

    def method1(self):
        return "hello"

    def method2(self):
        return "there"

    def method3(self):
        return "I have plenty of public methods"


class World(Hello[int]):
    def sole_method(self):
        return "I have methods from Hello also!"

Current behavior

Pylint reports:
test.py:17:0: R0903: Too few public methods (1/2) (too-few-public-methods)

Expected behavior

No error

pylint --version output

pylint 2.1.1
astroid 2.0.4
Python 3.6.6 (default, Sep 12 2018, 18:26:19) 
[GCC 8.0.1 20180414 (experimental) [trunk revision 259383]]
@PCManticore
Copy link
Contributor

Thanks for the report! pylint doesn't care too much about generics of typing constructs just yet, but we'll get there at some point.

@wshanks
Copy link

wshanks commented Mar 3, 2021

I think this may have been fixed. I don't reproduce it with the latest releases:

pylint 2.7.2
astroid 2.5.1
Python 3.9.2

@cdce8p
Copy link
Member

cdce8p commented Oct 17, 2021

I can't reproduce it either. We improved the handling of the typing module quite a bit in recent versions so I would assume this has been fixed. Going to close the issue.

If you still experience any problems, please report back and I'll reopen it.

@cdce8p cdce8p closed this as completed Oct 17, 2021
@rkr87
Copy link

rkr87 commented Sep 22, 2022

I'm seeing this issue when working with Pydantic, however, I'm not sure if it's a PyLint or a Pydantic issue.

I've have the classes below;

import re
from pathlib import Path
from typing import Generic, Iterator, Tuple, TypeVar
from pydantic import BaseModel, ConstrainedStr, Field
from pydantic.generics import GenericModel
from pydantic.types import NegativeInt

_KT = TypeVar('_KT', str, ConstrainedStr)
_VT = TypeVar('_VT')

class RootDictModel(GenericModel, Generic[_KT, _VT]):
    __root__: dict[_KT, _VT] = {}
    def __getitem__(self, key: _KT) -> _VT:
        return self.__root__[key]
    def __iter__(self) -> Iterator[_KT]:  # type: ignore
        return iter(self.__root__)
    def keys(self) -> list[_KT]:
        return list(self.__root__.keys())
    def values(self) -> list[_VT]:
        return list(self.__root__.values())
    def items(self) -> list[Tuple[_KT, _VT]]:
        return list(self.__root__.items())

class TagKey(ConstrainedStr):
    regex: re.Pattern[str] = re.compile(r'^\d*$')

class Tags(RootDictModel[TagKey, str]):
    ...

class Shortcut(BaseModel, extra='allow'):
    id: NegativeInt = Field(alias="appid")
    name: str = Field(alias="appname")
    exe: str = Field(alias="exe")
    dir: Path = Field(alias="StartDir")
    launch: str = Field("", alias="LaunchOptions")
    tags: Tags = Tags()

class Shortcuts(RootDictModel[str, Shortcut]):
    ...

class ShortcutsVDF(BaseModel):
    shortcuts: Shortcuts

Both Tags and Shortcuts result in Pylint giving a Too few public methods (0/2) pylint(too-few-public-methods) warning, despite the fact that there's three public methods in RootDictModel.

@Pierre-Sassoulas
Copy link
Member

Can you try using pylint-pydantic to see if it fixes the issue ? If you find a reproducer without using pydantic it would help tremendously to troubleshoot this in pylint directly :)

@rkr87
Copy link

rkr87 commented Sep 23, 2022

I've tried the pylint-pydantic plugin, which didn't help unfortunately. For now I've just disabled the pylint error in the lines affected.

I have tried a couple of different things to replicate the issue without using any pydantic models but haven't been able to, suggesting it probably is an interaction issue between pydantic and pylint.

@Pierre-Sassoulas
Copy link
Member

I think opening an issue in pylint-pydantic is the thing to do at this point. We're relying on external plugin to handle libraries specificity now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants