typing.Concatenate? https://mypy-play.net/?mypy=latest&python=3.10&gist=ace3e59645b2dc98695cbc1e4c189792
main.py:4: error: The first argument to Callable must be a list of types or "..."
Callable[P, Any] says error: The first argument to Callable must be a list of types or "...", and this is with mypy 0.950
if TYPING or whatever ;-)
@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
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?
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.
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
Connection[Any] instead of Connection[TupleRow]
_Self cannot be parametrizeddiff --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
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.
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.
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 _sleepersscce.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)
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".
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.
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?
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"
}
]
}];Hi everyone! How can I merge two 'pyi' files - i.e. auto-generated stubs and manually clarifying.
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)
Is there any tooling for merging (overriding) existing pyi files?
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
"""
$ 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:
...
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.
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].treeIt seems that I can extract this information from the mtree. But I couldn't find information about it