Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    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.
    Arun Vasudevan
    @arunvasudevan
    Hello All..This is my first message in the community. I am facing issues in reading a python message that has custom options added to a field. I am getting the error: Option "(confluent.field_meta)" unknown. Ensure that your proto definition file imports the proto which defines the option. int32 challenge_type = 25 [(confluent.field_meta) = { params: [ { value: "int16", key: "connect.type" } ] }]; Would you be able to help me in understanding if types-protobuf lib supports custom field options?
    Arun Vasudevan
    @arun_vasudevan_pelo:matrix.org
    [m]
    I am facing issues in reading a python message that has custom options added to a field.
    I am getting the error: Option "(confluent.field_meta)" unknown. Ensure that your proto definition file imports the proto which defines the option.
    int32 challenge_type = 25 [(confluent.field_meta) = { params: [ { value: "int16", key: "connect.type" } ] }];
    Would you be able to help me in understanding if types-protobuf lib supports custom field options?
    Mr Keuz
    @mrkeuz

    Hi everyone! How can I merge two 'pyi' files - i.e. auto-generated stubs and manually clarifying.

    Use case

    I want to merge two pyi files. Purpose is generating stubs for code i.e. via mypy.stubgen and next apply some clarifications for types from external file. Add doc strings, clarify return parameters manually and so on.

    My use case is support stub package for some external lib. And when API is changed during release just regenerate stubs, but save all previously collected type knowledge. In this case we can automate entire process of generating and testing stubs correctness (i.e. via mypy.stubtest).

    (pytype merge_pyi not supported such feature, I've tried)

    Question

    Is there any tooling for merging (overriding) existing pyi files?

    Callek
    @jwood:mozilla.org
    [m]

    I might suggest using git branches + git merge tooling.

    Basically "here's a patch ontop of the last auto-generated typing"

    I'm not sure if that's useless to you in your setup though

    2 replies
    Spencer Baugh
    @catern
    if I want to define something like Result[T] which behaves exactly like Union[str, T], how would I do that?
    2 replies
    xvbcfj
    @xvbcfj
    https://mypy-play.net/?mypy=latest&python=3.10&gist=7316d899d9d5546e0e6c241eb2716788
    Why does the type not get narrowed to remove the None here? Is this just something that has not been implemented and will be supported in the future or is this by design?
    5 replies
    bruno messias
    @devmessias
    Hi all. I found a issue regarding @overload and abstract classes
    I couldn't figure out how to proceed with that
    """
    $ mypy test.py --strict
    test.py:42: error: Function is missing a type annotation for one or more arguments
    test.py:42: error: Overloaded function implementation does not accept all possible arguments of signature 1
    test.py:42: error: Overloaded function implementation does not accept all possible arguments of signature 2
    """
    
    from abc import ABC
    from typing import List, Tuple, Type, Union, overload
    
    
    class State(ABC):
        def __init__(self) -> None:
            ...
    
    
    class StateInterface(State):
        def __init__(self, title: str = "", help_text: str = "") -> None:
            ...
    
        @staticmethod
        def poptions(items: List[Tuple[str, str]]) -> None:
            ...
    
    
    class Context:
        def __init__(
                self, initial_state: Type[State]) -> None:
            ...
            self.set_state(initial_state)
    
        @overload
        def set_state(
                self, state: Type["InterfaceFile"],
                file: str = "", title: str = "", help_text: str = "") -> None:
            ...
    
        @overload
        def set_state(
                self, state: Type[StateInterface],
                title: str = "", help_text: str = "") -> None:
            ...
    
        @overload
        def set_state(
                self, state: Type[State]) -> None:
            ...
    
        def set_state(
                self,
                state: Union[Type[State], Type[StateInterface]], Type["InterfaceFile"],
                **kwargs) -> None:
            state.context = self  # type: ignore
            self._state = state(**kwargs)
    
    
    class InterfaceFile(StateInterface):
        def __init__(self, file: str = "", title: str = "", help_text: str = "") -> None:
            ...
    hfcredidio
    @hfcredidio

    Hey, would it be possible to write a mypy plugin that work like this?

    import enum
    import typing as t
    
    E = t.TypeVar("E", bound=enum.Enum)
    V = t.TypeVar("V")
    
    def EnumMap(t.Dict[E, V]): pass
    
    def MyEnum(enum.Enum):
        a = enum.auto()
        b = enum.auto()
        c = enum.auto()
    
    # the below should error
    # it's missing an entry for MyEnum.c
    data: EnumDict[MyEnum, int] = {
        MyEnum.a: 1,
        MyEnum.b: 2,
    }
    
    
    # should be ok
    data2: EnumDict[MyEnum, int] = {
        MyEnum.a: 1,
        MyEnum.b: 2,
        MyEnum.c: 3,
    }

    I've been trying to figure out the mypy plugin api, but can't seem to find a hook that covers what I'm trying to do, as get_type_analyze_hook doesn't seem to have accesss to the rvalue in the assignment (I can be wrong).

    I did manage to write plugin that works around like

    import enum
    import typing as t
    
    E = t.TypeVar("E", bound=enum.Enum)
    
    def mapping(cls: t.Type[E]) -> t.Type[E]:
        """
        Generate a class method `mapping` to `cls` with signarture
        def mapping(cls: Type[E], *, field1: T, field2: T, ...) -> Dict[E, T]:
        """
        ...
    
    @mapping
    def MyEnum(enum.Enum):
        a = enum.auto()
        b = enum.auto()
        c = enum.auto()
    
    # mypy throws an error, missing argument `c`
    data: t.Dict[MyEnum, int] = MyEnum.mapping(a=1, b=2)
    
    # passes
    data2: t.Dict[MyEnum, int] = MyEnum.mapping(a=1, b=2, c=3)

    But I'm not super satified with it, as I'd prefer to just use reguar dict literals instead of dynamically generated classmethods. Any help is much appreciated.

    hfcredidio
    @hfcredidio
    I thought that should be possible, as it's essentially how a a typeddict works, but again typeddicts are not implemented using plugins so I'm not sure is it's even possible to translate that part of the codebase.
    1 reply
    bruno messias
    @devmessias
    Hi all, I'm trying to annotate the python ast with mypy
    I saw this discussion on mypy python/mypy#4868 but it seems that are not so much progress in that
    image.png
    bruno messias
    @devmessias
    I was able to do this using pyre query . For each ast node I extract the linenos, and cols _offsets and look into the pyre output. But probably there is a better way to do this just with mypy
    import mypy.main as MAIN
    import mypy.build as BUILD
    
    py_file = "src/mod/test"
    
    mod = py_file.replace("/", ".")
    files, opt = MAIN.process_options([f"{py_file}.py"])
    opt.preserve_asts = True
    #opt.fine_grained_incremental = True
    result = BUILD.build(files, options=opt)
    result.graph[mod].load_tree()
    mtree =result.graph[mod].tree
    It seems that I can extract this information from the mtree. But I couldn't find information about it