0

Let's say I have a function that is able to compare fruits, I could explicitly mention this in type annotations like this:

def compare_fruits(one: Fruit, other: Fruit) -> bool:
    assert type(one) is type(other)  #  <-- type hint for this
    ...

This implies it would be a valid operation to compare an Apple and Pear objects as subclasses, but it's not for my program. I'd like to find a way to type-annotate the function's arguments with an generic of "same-type". I think I know how to do that in abstract classes with user-defined Generic types, but it's not clear to me how to do this for plain functions.

I tried this the naive way:

FruitType = TypeVar("FruitType")


def compare_fruits(one: Generic[FruitType], other: Generic[FruitType]) -> bool:
    ...

yields error: Variable "typing.Generic" is not valid as a type in mypy, which makes sense.

Then I tried this:

FruitType = TypeVar("FruitType")


class MyFruitModule(Generic[FruitType]):

    @staticmethod
    def compare(one: FruitType, other: FruitType) -> bool:
        ...


compare_apples = MyFruitModule[Apple].compare  # still not implicit same-type

Any ideas or a source about that this is simply impossible as of the moment?

gertvdijk
  • 24,056
  • 6
  • 41
  • 67
  • Does this answer your question? [Python type hinting: how to tell X is a subclass for Foo?](https://stackoverflow.com/questions/32205960/python-type-hinting-how-to-tell-x-is-a-subclass-for-foo) – Random Davis Nov 15 '21 at 22:19
  • 1
    Why do you keep using `Generic`, that isn't what it is for – juanpa.arrivillaga Nov 15 '21 at 22:33
  • 1
    You just mean something like `FruitType = TypeVar("FruitType", bound=Fruit)`? Then annotate it with `FruitType` Note, if you mean *any* type, then `FruitType = TypeVar("FruitType")` would already do that. You would just have to annotate it with `def compare_fruits(one: FruitType, other: FruitType) -> bool:` which to me seems to be the naive way (again, not sure why you are involving `Generic` at all) – juanpa.arrivillaga Nov 15 '21 at 22:34
  • No I don't want any subclass to match. Like I explained, comparing an Apple and a Pear does not make sense in my use case. I'd like to type-hint same-type arguments, ie. `assert type(one) is type(other)`-safe. – gertvdijk Nov 15 '21 at 23:16
  • 1
    In principle, a regular function with invariant TypeVar like ``compare(a: FruitType, b: FruitType)`` should do... but [mypy seems not to enforce that](https://mypy-play.net/?mypy=latest&python=3.10&gist=d11875a01588d249985a6807ade250bd&flags=strict) and even happily accept variance for in/out types. – MisterMiyagi Nov 16 '21 at 15:23

0 Answers0