У меня есть следующий код
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)?