DetachHead / basedpyright

pyright fork with various type checking improvements, improved vscode support and pylance features built into the language server
http://docs.basedpyright.com/
Other
613 stars 13 forks source link

don't report `reportUnknownMemberType` on attribute access to a method when the method is not being called #409

Open vikigenius opened 3 weeks ago

vikigenius commented 3 weeks ago
import boto3
from typing import Literal

class MyService(object):
    """My Service."""

    def __init__(self, env: Literal["prod", "dev", "stg"] = "stg", country: Literal["us", "ca"] = "us") -> None:
        super().__init__()

    def _get_api_url_and_key(self, stack: str):
        """Get the API URL and KEY"""
        session = boto3.Session(region_name="eu-west-1")

        cf = session.client("cloudformation")  # basedpyright complains about partially unknown client

I installed type stubs from https://pypi.org/project/boto3-stubs/#usage

Like this: pip install boto3-stubs[essential] and pyright no longer complains about partially unknown client but basedpyright still does.

KotlinIsland commented 3 weeks ago

This looks like a defect in boto3-stubs, the type mypy_boto3_clouddirectory.client.CloudDirectoryClient is imported within boto3.session, but there is no module mypy_boto3_clouddirectory included in boto3-stubs[essential]

Why does pyright not report this error? I'm not sure sorry, maybe @DetachHead Could answer that.

KotlinIsland commented 3 weeks ago

Here is the minification:

from typing import overload

from sus import sus

class A:
    @overload
    def f(self, x: int) -> sus: ...

    @overload
    def f(self, x: str) -> int: ...

    def f(self, x: object) -> object: ...

b = A().f("asdf")  # type of "f" is partially unknown

Which does actually show in pyright if you enable strict mode

DetachHead commented 3 weeks ago

this is just because basedpyright enables all rules by default. (specifically this rule is reportUnknownMemberType). you can disable that rule if you want:

[tool.basedpyright]
reportUnknownMemberType = false

or if you want to set basedpyright's defaults to be the same as pyright's:

[tool.basedpyright]
typeCheckingMode = 'standard'
vikigenius commented 3 weeks ago

Huh that seems to have fixed the discrepancy. Although it's weird that it complains about partially unknown type.

Looks like it's a known issue with pyright: https://github.com/youtype/mypy_boto3_builder/issues/202

pyright complains about partially unknown types if not all overloads can be resolved.

I am not sure if this is desired behavior. Disabling reportUnknownMemberType seems to affect a lot more than this.

DetachHead commented 3 weeks ago

the issue is that reportUnknownMemberType gets reported on attribute access, rather than when the method actually gets called:

b = A().f  # type of "f" is partially unknown

this is why it doesn't care which overload is being matched. it's reporting the error before it even checks the call