У меня есть следующий код
from typing import TypeVar, Type, overload
T = TypeVar('T')
@overload
def foo(bar: Type[T]) -> T:
...
@overload
def foo(bar: Type[T] | None) -> T | None:
...
def foo(bar: Type[T] | None) -> T | None:
# implementation goes here
...
class Bar:
...
bar = foo(Bar)
bar2 = foo(Bar | None) # No overload variant of "foo" matches argument type "UnionType"
Как правильно набрать регистр подсказок для bar2
?
Я попробовал некоторые другие:
Type[T | None]
, говорит мойпи Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader
удаление 2-й перегрузки (в результате разрешено только Type[T]
), mypy говорит No overload variant of "foo" matches argument type "UnionType"
(это означает, что 2-я перегрузка в любом случае неверна для этого случая)
@deceze Я хочу проанализировать некоторый необязательный результат (я передаю тип непосредственно в pydantic.TypeAdapter) внутри foo
, поэтому он возвращает T | Никто. Это работает нормально, но я, к сожалению, не могу печатать аннотации. Думаю, тогда я остановлюсь на optional=False
кварге:/
type[T] подразумевает что-то, что можно вызвать для получения экземпляра типа T
. type[T] | None
означает такое, или None
; таким образом, bar
может быть вызвано.
def foo(bar: type[T] | None) -> None:
if bar is not None:
reveal_type(bar) # type[T]
instance = bar() # fine
Однако Bar | None
возвращает экземпляр UnionType
во время выполнения, и объекты такого типа нельзя вызывать.
foo(Bar | None) # (Bar | None) is not None
# bar() => error
Кажется, вам нужна предлагаемая TypeForm, которая пока существует только в черновике PEP:
@overload
def foo[T](bar: TypeForm[T]) -> T:
...
@overload
def foo[T](bar: TypeForm[T | None]) -> T | None:
...
def foo[T](bar: TypeForm[T | None]) -> T | None:
...
Цитирую проект:
И TypeForm[], и type[] можно использовать для ограничения переменной одного и того же типа в одном определении функции:
def as_instance[T](form: TypeForm[T]) -> T | None: return form() if isinstance(form, type) else None
Да, это было то, чего я хотел. Жаль, что это только черновик :(
Я не уверен, что именно вы пытаетесь здесь сделать.
Type[T] | None
— это подсказка типа.Bar | None
также является подсказкой типа. Почему вы пытаетесь передать подсказку типа в качестве аргумента функции? Подсказка типаType[T] | None
означает, что может быть передан либо тип, либо значениеNone
, поэтому допустимыми вызовами будутfoo(Bar)
иfoo(None)
. Чего вы пытаетесь достичь с помощьюfoo(Bar | None)
?