Is it possible to put negative constraints on a TypeVar?

Is this possible?

T = TypeVar("T") # T must not be a subtype of list

I want to do something like this:

class A(Generic[T]):
    def __init__(self, value: T | list[T]):
        if isinstance(value, list):
            "do something"
        else:
            "do something else"

If T can be a subtype of list, this logic wouldn’t work.

If negative type constraint is not possible, what are ways to work around this?

It is not.

But what do you want to do with value when it’s not a list that you can’t do with

def __init__(self, value: list[T]):
    if len(value) == 1:
        "do something with value[0]"
    else:
        "do something with value"
1 Like

I see, thanks.

I mean, if you have code like

def __init__(self, value: T | list[T]):
    if not isinstance(value, list[T]):
        value = [value]
    for t in value:
        # do something with t

then it’s usually better to just make the caller wrap a singleton value in a list, rather than making __init__ figure out what value is. But if you have a different use case, there may be a better work around available.

2 Likes

I have code like

def __init__(self, value: T | list[T]):
    def foo(arg: T):
        "return something"

    if isinstance(value, list):
        self.value = list(map(foo, value))
    else:
        self.value = foo(value)

On second thought this is probably not a good way to organize the logic, I’ll try to refactor it.

maybe something like this?

from typing import Generic, TypeVar

T = TypeVar("T")


class A(Generic[T]):
    def __init__(self, *args: T):
        def foo(arg: T):
            "return something"

        self.value = list(map(foo, args))


a1 = A(1)

my_list = [1, 2, 3]

a2 = A(*my_list)

A lot of code out there tries to do what the client code wants and make the interface magically do the right thing according to the type of whatever is passed in. I have consistently found that in the long run, elegant, symmetrical designs are way less of a headache, even if they force the client to do some wrapping.

“Special cases aren’t special enough to break the rules.”

3 Likes