Variable value verified with a tuple and not a set or a list #9810
-
Hey there, I don't think the title is self explanatory enough, so I'll just paste the code here. from typing import Literal
def greet(string: Literal['Hello', 'Bonjour', 'Hola']):
...
def function(string: str):
if string == 'Hello' or string == 'Bonjour' or string == 'Hola':
greet(string)
if string in ['Hello', 'Bonjour', 'Hola']: # error: Argument of type "str" cannot be assigned to parameter "string" of type "Literal['Hello', 'Bonjour', 'Hola']" in function "greet"
greet(string)
if string in {'Hello', 'Bonjour', 'Hola'}: # error: Argument of type "str" cannot be assigned to parameter "string" of type "Literal['Hello', 'Bonjour', 'Hola']" in function "greet"
greet(string)
if string in ('Hello', 'Bonjour', 'Hola'): # no error
greet(string) Why does pyright understands that the variable is a Literal['Hello', ...] when comparing with a tuple, but not a list or a set ? Any help is appreciated, thank you :) |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
This behavior is intended. Literal values are retained when inferring the type of a tuple expression but are not when inferring the type of a list, dict or set expression. This is because list, dict and set objects are mutable. If literals were retained when inferring their types, it would be very inconvenient. For example, if you had the statement |
Beta Was this translation helpful? Give feedback.
This behavior is intended. Literal values are retained when inferring the type of a tuple expression but are not when inferring the type of a list, dict or set expression. This is because list, dict and set objects are mutable. If literals were retained when inferring their types, it would be very inconvenient. For example, if you had the statement
x = [1]
, you probably wouldn't want the type ofx
to be inferred aslist[Literal[1]]
. For more details about pyright's inference behaviors for container expressions, refer to this documentation.