Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    TDV Alinsa
    @alinsavix
    Yeah, found that, just ... not much helpful. Drat.
    Priyatham
    @Priyatham10

    I recently joined a team where we have an extension module based Python package say: mypackage.so, mypackage.pyd files are loaded as the sole package. So, now I'm taking responsibility to add the stubs for type hints for IDEs. I have tried the two famous automatic stub generation tools - mypy stubgen, pybind11-stubgen. Two of those stub generation tools expose only the top level class symbols but there are enormous other symbols that serve as properties to the classes and other stuff. All of them are not getting generated in the .pyi stub files. Could anyone please provide me a solution for this?

    Could anyone please give some ideas or pointers for this to me?

    Gabriele N. Tornetta
    @P403n1x87
    Is it possible to analyse an UnboundType from a callback that takes a TypeChecker for context API (e.g. get_method_hook)? I've seen that attrs does this with the anal_type method, but TypeChecker doesn't have that. Is it possible to get the semantic analyser at least and perhaps use that to analyse the UnboundType?
    dmr
    @dmrobertson:matrix.org
    [m]
    quick question: is there a way to print or log from a mypy plugin?
    dmr
    @dmrobertson:matrix.org
    [m]
    Hmm. I might have been barking up the wrong tree. plain print works fine; I think that changes to the plugin I was tweaking weren't actually being ran by mypy.
    dmr
    @dmrobertson:matrix.org
    [m]
    Got it: another plugin was returning a non-None hook, which meant that the plugin I was interested in didn't get to do anything.
    mahmoudajawad
    @mahmoudajawad:matrix.org
    [m]
    1 reply
    Iow, does current specs for typed-dict allow such a thing?
    jack-burridge-cfh
    @jack-burridge-cfh

    I'm really struggling to understand an error

    class Parent:
        value: int | None = None
    
    
    class Child(Parent):
        def __init__(self, input: int) -> None:
            self.input = input
    
        @property
        def value(self) -> int | None:
            return self.input * 2

    I'm getting: Signature of "value" incompatible with supertype "Parent"
    I can fix it with another property but it seems like overkill

    class Parent:
        @property
        def value(self) -> int | None:
            return None
    
    
    class Child(Parent):
        def __init__(self, input: int) -> None:
            self.input = input
    
        @property
        def value(self) -> int | None:
            return self.input * 2
    2 replies
    Justin Bull
    @f3ndot

    Hey cool cats. Maintainer of Flask recommended that this is a bug with mypy. Wanted a sanity check here before I open an issue. What do people think? pallets/flask#4600

    TLDR: mypy appears to not consider this to be valid because of the name "bar" as the arg

    def foo(bar: SomeType): -> SomeType
        return bar
    
    MyCallable = typing.Callable[[SomeType], SomeType]
    def my_callback(foo: MyCallable)
        foo("something")
    error: Argument 1 to "foo" of "MyCallable" has incompatible type "Callable[[Arg(SomeType, 'bar')], SomeType]"; expected "Callable[[SomeType], SomeType]"
    6 replies

    From the maintainer:

    Please open this against MyPy first. It looks like they're treating your function as a named argument callable and not matching that to the basic callable in Flask's annotation.

    Joshua Oreman
    @oremanj
    @jack-burridge-cfh Child is not a subtype of Parent because Parent.value is writable while Child.value is not. Either add a setter to Child.value, or make Parent.value read-only (such as by making it a property or Final).
    David Tucker
    @tucked:matrix.org
    [m]
    How do I annotate a classmethod on an Enum? The way I usually annotate classmethods doesn't seem to work:
    from enum import Enum
    from typing import Set, Type, TypeVar
    
    _Status = TypeVar("_Status", bound="Status")
    
    
    class Status(Enum):
        A = 1
        B = 2
        C = 3
    
        @classmethod
        def subset(cls: Type[_Status]) -> Set[_Status]:
            return {cls.A, cls.B}
    sscce.py:14: error: Argument 1 to <set> has incompatible type "Status"; expected "_Status"
    sscce.py:14: error: Argument 2 to <set> has incompatible type "Status"; expected "_Status"
    Found 2 errors in 1 file (checked 1 source file)
    1 reply
    David Tucker
    @tucked:matrix.org
    [m]

    So, this seems to work:

    from enum import Enum
    from typing import Set
    
    
    class Status(Enum):
        A = 1
        B = 2
        C = 3
    
        @classmethod
        def subset(cls) -> Set["Status"]:
            return {cls.A, cls.B}

    However, cls wouldn't be Status in a subclass, right? (Not that that's allowed haha)

    1 reply
    David Tucker
    @tucked:matrix.org
    [m]
    Fair enough, but just for my curiosity, why doesn't the TypeVar method work here?
    Callek
    @jwood:mozilla.org
    [m]
    I'm not a mypy Dev, and as far as I know it should have worked, I tested on https://mypy-play.net/?mypy=latest&python=3.10 and see the same behavior
    Christoph Blessing
    @cblessing24

    Hi, I have the following code:

    from typing import Generic, TypeVar
    from abc import ABC
    
    R = TypeVar("R", bound="AbstractRepository")
    T = TypeVar("T", bound="AbstractUnitOfWork")
    
    
    class AbstractRepository(ABC):
        pass
    
    
    class ConcreteRepository(AbstractRepository):
        pass
    
    
    class AbstractUnitOfWork(ABC, Generic[R]):
        repo: R
    
        def commit(self: T) -> T:
            return self
    
    
    class ConcreteUnitOfWork(AbstractUnitOfWork[ConcreteRepository]):
        def commit(self) -> "ConcreteUnitOfWork":
            return super().commit()

    When running with the strict flag mypy complains that AbstractUnitOfWork in the definition of T is missing a type parameter.
    I am not sure what the correct type parameter is here. I tried R and AbstractRepository but that just produces other errors. Does someone know what the correct parameter would be?

    7 replies
    Alex Grönholm
    @agronholm
    what am I not understanding about typing.Concatenate? https://mypy-play.net/?mypy=latest&python=3.10&gist=ace3e59645b2dc98695cbc1e4c189792
    1 reply
    it tells me main.py:4: error: The first argument to Callable must be a list of types or "..."
    as if ParamSpec or Concatenate were not supported at all
    Alex Grönholm
    @agronholm
    forget Concatenate, it doesn't accept ParamSpec in Callable at all
    even Callable[P, Any] says error: The first argument to Callable must be a list of types or "...", and this is with mypy 0.950
    1 reply
    where it's supposedly supported
    Callek
    @jwood:mozilla.org
    [m]
    anyone know of a tool to pull out imports only used in type hints and stuff them behind an if TYPING or whatever ;-)
    Alex Grönholm
    @agronholm
    "pull out"?
    Callek
    @jwood:mozilla.org
    [m]

    @agronholm: Basically imagine:

    from typing import Dict, List
    
    def foo(bar: Dict) -> List:
        return []

    of course ignoring my lack of specifying types inside of dict/list but the from typing doesn't actually need to be imported for program runtime, so it could instead go like this:

    if TYPE_CHECKING:
        from typing import Dict, List
    Alex Grönholm
    @agronholm
    oh, you want a tool to hide those imports under if TYPE_CHECKING:?
    Callek
    @jwood:mozilla.org
    [m]
    yes, basically
    Alex Grönholm
    @agronholm
    yeah, I would like that too
    Callek
    @jwood:mozilla.org
    [m]
    and the ideal is that it auto-detects that they are only used as part of type hints
    mwchase
    @mwchase
    https://github.com/snok/flake8-type-checking is a flake8 plugin that tries to do that analysis. I ran into a few hiccups getting it set up, but nothing major.
    Alex Grönholm
    @agronholm
    I just realized this would wreak havoc in my apps
    3 replies
    Kyle Altendorf
    @altendky
    i'm trying to use concurrent.futures.Future with a Protocol and get main.py:23: error: Argument "x" to "f" has incompatible type "Future[C]"; expected "Future[P]" https://mypy-play.net/?mypy=latest&python=3.10&gist=dda72d0cfe1a433261a7a5493d57cb1e. C seems to satisfy P when used directly, without the Future layer. is this a variance issue? is there another thing i should be doing instead?
    1 reply
    i had written my own class that seemed to be working but realized it was just a custom minimal future so i figured i would use the existing tooling instead.
    jinsun
    @jinsun:matrix.org
    [m]
    I don't think there is a immutable variant of Future like thing that you can use, so I guess you'll have to make another protocol that has the methods of Future that you care about
    Kyle Altendorf
    @altendky
    alrighty, thanks. i'll take another pass at it in a bit to see how i want to handle this.
    Kyle Altendorf
    @altendky
    the use in this case really doesn't require a future, so coding myself isn't a big deal. i just want to have a way to provide an object while entering a context manager which will have a usable value only after the context. and i thought i could avoid is not None checks by providing a callable object that includes the None check. it is specifically a pair of context managers that time the body, one of them asserts a maximum time for testing.
    Daniele
    @dvarrazzo:matrix.org
    [m]
    Generics + TypeVar + overloaded method... Is it possible to fix this signature?
    Currently subclasses have the wrong signature. In order to fix, cls should be annotated with cls: Type[Conn] and return should be Conn. But conn is generic: it could be either Conn[Row] if a Row is in the parameters, or Conn[TupleRow] if it isn't
    Daniele
    @dvarrazzo:matrix.org
    [m]
    An attempt made:
    diff --git a/psycopg/psycopg/connection.py b/psycopg/psycopg/connection.py
    index abf6bb0f..54b0e446 100644
    --- a/psycopg/psycopg/connection.py
    +++ b/psycopg/psycopg/connection.py
    @ -665,6 +665,9 @@ class Connection(BaseConnection[Row]):
    
         _pipeline: Optional[Pipeline]
    
    +    _SelfRow = TypeVar("_SelfRow", bound="Connection[Row]")
    +    _Self = TypeVar("_Self", bound="Connection[TupleRow]")
    +
         def __init__(
             self,
             pgconn: "PGconn",
    @@ -679,7 +682,7 @@ class Connection(BaseConnection[Row]):
         @overload
         @classmethod
         def connect(
    -        cls,
    +        cls: Type[_SelfRow],
             conninfo: str = "",
             *,
             autocommit: bool = False,
    @@ -688,13 +691,13 @@ class Connection(BaseConnection[Row]):
             cursor_factory: Optional[Type[Cursor[Row]]] = None,
             context: Optional[AdaptContext] = None,
             **kwargs: Union[None, int, str],
    -    ) -> "Connection[Row]":
    +    ) -> _SelfRow:
             ...
    
         @overload
         @classmethod
         def connect(
    -        cls,
    +        cls: Type[_Self],
             conninfo: str = "",
             *,
             autocommit: bool = False,
    @@ -702,7 +705,7 @@ class Connection(BaseConnection[Row]):
             cursor_factory: Optional[Type[Cursor[Any]]] = None,
             context: Optional[AdaptContext] = None,
             **kwargs: Union[None, int, str],
    -    ) -> "Connection[TupleRow]":
    +    ) -> _Self:
             ...
    
         @classmethod  # type: ignore[misc] # https://github.com/python/mypy/issues/11004
    This doesn't quite work as Connection.connect() returns a Connection[Any] instead of Connection[TupleRow]
    Daniele
    @dvarrazzo:matrix.org
    [m]
    This is the ideal, I believe, but doesn't work because _Self cannot be parametrized
    diff --git a/psycopg/psycopg/connection.py b/psycopg/psycopg/connection.py
    index abf6bb0f..964c777a 100644
    --- a/psycopg/psycopg/connection.py
    +++ b/psycopg/psycopg/connection.py
    @ -665,6 +665,8 @@ class Connection(BaseConnection[Row]):
    
         _pipeline: Optional[Pipeline]
    
    +    _Self = TypeVar("_Self", bound="Connection")
    +
         def __init__(
             self,
             pgconn: "PGconn",
    @ -679,7 +681,7 @@ class Connection(BaseConnection[Row]):
         @overload
         @classmethod
         def connect(
    -        cls,
    +        cls: Type[_Self],
             conninfo: str = "",
             *,
             autocommit: bool = False,
    @@ -688,13 +690,13 @@ class Connection(BaseConnection[Row]):
             cursor_factory: Optional[Type[Cursor[Row]]] = None,
             context: Optional[AdaptContext] = None,
             **kwargs: Union[None, int, str],
    -    ) -> "Connection[Row]":
    +    ) -> _Self[Row]:
             ...
    
         @overload
         @classmethod
         def connect(
    -        cls,
    +        cls: Type[_Self],
             conninfo: str = "",
             *,
             autocommit: bool = False,
    @@ -702,7 +704,7 @@ class Connection(BaseConnection[Row]):
             cursor_factory: Optional[Type[Cursor[Any]]] = None,
             context: Optional[AdaptContext] = None,
             **kwargs: Union[None, int, str],
    -    ) -> "Connection[TupleRow]":
    +    ) -> _Self[TupleRow]:
             ...
    
         @classmethod  # type: ignore[misc] # https://github.com/python/mypy/issues/11004
    Nash Taylor
    @ntaylorwss

    Hey everyone, I just found this community after reading up on creating mypy plugins. Our codebase uses mypy to check all code, and we use Pydantic in quite a few places to add some runtime validation as well. We're exploring adding Prefect to our stack, but I'm running into some issues around typing. Namely this: Prefect has chosen to primarily focus on supporting Pyright before Mypy, but Pydantic and Pyright have issues working together. Plus, Pydantic has a whole Mypy integration which offers a bunch of awesome features; they clearly prefer Mypy. Now, I want to continue using Pydantic and Mypy, but I also really want to start using Prefect.

    Is anyone else in a similar position to me, and is it possible that a Prefect 2.0 mypy plugin is already being developed? If not, I'm considering exploring this myself.

    Nash Taylor
    @ntaylorwss

    As an example of something in Prefect that works fine with Pyright, but doesn't work with Mypy: https://github.com/PrefectHQ/prefect/blob/orion/src/prefect/tasks.py#L231-L255

    These 3 overloads are defined on Task.__call__, where Task is meant to be a decorator on a function. When I use Task to decorate any of my functions, Mypy tells me that reveal_type(decorated_task) is a PrefectFuture[None, Literal[False]]. Essentially, it never matches the third overload, so it always falls back to the first overload. I cannot for the life of me figure out why this is the case, especially considering Pyright has no trouble here. I thought it might have something to do with PEP 612 support, but Mypy seems to nearly fully support PEP 612 at this point, and this doesn't feel like much of an edge case.

    So, hopefully you can see my dilemma here. Checking a Prefect task against Mypy fails on pretty much the most basic use case, but checking Pydantic-driven task functions against Pyright leaves out all of the great features of the mypy plugin. If anybody has seen Mr. Nobody, I feel like I'm the kid at the train having to decide which direction to go. And much like Jared Leto, I feel like I could fully explore both possibilities and return to the train station only to still be utterly confused as to which path to take.

    Nash Taylor
    @ntaylorwss
    Back at the end of the day with a much more specific issue now. I've managed to scope the issue all the way down to this truly puzzling behaviour: Mypy is unable to identify the correct overload only when the method is __call__. (working on a reproducible example)
    3 replies
    Daniele
    @dvarrazzo:matrix.org
    [m]
    Help! How to deal with a parametric generic self in the presence of overloads with default values for the generic type? See psycopg/psycopg#308 for a description of the issue. Thank you! :)
    David Tucker
    @tucked:matrix.org
    [m]
    Is this a bug, or am I missing something?
    from datetime import timedelta
    from time import sleep
    from typing import Callable, Optional, Union
    
    
    def _make_sleeper(
        seconds: Optional[Union[int, float, timedelta]] = 30,
    ) -> Callable[[], None]:
        if seconds is not None:
            if isinstance(seconds, timedelta):
                seconds = seconds.total_seconds()
            if seconds < 0:
                raise ValueError("seconds must be positive.")
    
        def _sleeper() -> None:
            if seconds:
                sleep(seconds)
    
        return _sleeper
    sscce.py:17: error: Argument 1 to "sleep" has incompatible type "Union[float, timedelta]"; expected "float"
    Found 1 error in 1 file (checked 1 source file)
    1 reply
    mwchase
    @mwchase

    I feel like I keep on running into situations where I'd like to be able to do something like

    TaggedStr = NewType("TaggedStr", str, Generic[T]) # I actually hadn't thought about the syntax. Just imagine it's taking the Generic as another base class, or something.
    
    str_tagged_with_int = TaggedStr[int]("my int-related string")

    Unless I've drastically misunderstood the typing documentation, I don't think there's a way to achieve this with baseline typing. If so, has anyone else run across this and made a plugin for it? I haven't had any luck searching for stuff like "parametric newtype python".

    1 reply
    Kyle Altendorf
    @altendky
    python/typeshed#7641 i'm not clear how to hint an sqlite3.Row now that it is generic. it seems that it was genericized against a single type, but many tables will not use the same type for all columns. also, i have setup to use the dict-like rows which would require typed-dict-like hinting i guess.