Код: Выделить всё
from abc import ABC
class Base(ABC): ...
class A(Base): ...
class B(Base): ...
class C(Base): ...
# ...
class Z(Base): ...
Код: Выделить всё
MixedProduct
Код: Выделить всё
ZProduct
Код: Выделить всё
from abc import ABC, abstractmethod
from dataclasses import dataclass
class Product(ABC):
@property
@abstractmethod
def items(self) -> frozenset[Base]: ...
@dataclass(frozen=True)
class MixedProduct(Product):
items: frozenset[Base]
@dataclass(frozen=True)
class ZProduct(Product):
items: frozenset[Z]
Код: Выделить всё
from collections.abc import Iterable
from typing_extensions import TypeGuard
def check_all_z(items: tuple[Base, ...]) -> TypeGuard[tuple[Z, ...]]:
return all([isinstance(item, Z) for item in items])
def make_product(*items: Base) -> MixedProduct | ZProduct:
# `items` is a tuple[Base, ...]
if check_all_z(items): # the TypeGuard tells MyPy that items: tuple[Z, ...] in this clause
return ZProduct(frozenset(items))
return MixedProduct(frozenset(items))
Код: Выделить всё
reveal_type(make_product(Z())) # note: Revealed type is "ZProduct"
reveal_type(make_product(A())) # note: Revealed type is "MixedProduct"
reveal_type(make_product(Z(), Z())) # note: Revealed type is "ZProduct"
reveal_type(make_product(B(), A())) # note: Revealed type is "MixedProduct"
reveal_type(make_product(B(), Z())) # note: Revealed type is "MixedProduct" # also contains one Z!!
Код: Выделить всё
from typing import overload
@overload
def make_product(*items: Base) -> MixedProduct: ...
@overload
def make_product(*items: Z) -> ZProduct: ...
def make_product(*items):
if check_all_z(
items
): # the TypeGuard tells MyPy that items: tuple[Z, ...] in this clause
return ZProduct(frozenset(items))
return MixedProduct(frozenset(items))
Код: Выделить всё
error: Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader [misc]
Как еще бы я мог уметь различать однородные и гетерогенные кортежи с помощью аннотаций типов, чтобы зафиксировать правильные отношения типа ввода-возврата в моем случае?
Чтобы внести ясность: фактический код времени выполнения делает то, что я намереваюсь, я просто не могу правильно подобрать аннотации типов.
Подробнее здесь: https://stackoverflow.com/questions/788 ... -overloads