Home > Net >  How to annotate a list that may or MAY NOT have different types?
How to annotate a list that may or MAY NOT have different types?

Time:05-13

python version: 3.10.2

It was of my understanding that list[str|int] should allow three distinct types of values:

  1. List of only strings (list[str])
  2. List of only ints (list[int])
  3. List of both strings and ints (list[str|int])

Is this assumption right, or am I understanding it wrong ? because that's not what happens when I'm coding:

def test(x: list[str|int]):
    pass

# All fine
test([]); test(['a']); test([0]); test(['a', 0])

x: list[str] = []
y: list[int] = []
z: list[str|int] = []

test(x); test(y); test(z)

Pylance complaining that list[str] and list[int] are not compatible with list[str|int]

It accepts lists with only strings or only ints, but only if I don't specify that the list in question only accepts one of these values. x and y are explicitly declared as lists that only accepts one of this values (int or str), and because of that they are rejected. Is this really what is supposed to happen, or is it a bug ?

If I change the function annotation to accept a Sequence[str|int] instead of a list[str|int], then everything is fine. And same for Container[str|int], or even tuple[str|int, ...] [No errors displayed when parameter x of function test is declared to be Containerstr|int

CodePudding user response:

Here's the problem:

The type checker doesn't know or care what test does with the list. It only cares about what it might do to the list. One thing that would be legal is to add a str to the list: you said that (the parameter) x has type list[str|int]. That's fine if the list passed to test has type list[str|int] or list[str]; it's not fine if the list has type list[int].

That is, test does not accept lists that have either str or int values: it accepts lists that must be able to contain str or int values.

The problem goes away when you change the type of the parameter to Sequence[str|int], because a Sequence does not permit mutation. The type guarantees that if you provide a list[int] value, test won't try to add a str to the list.

  • Related