Python 3.13.1 interpreter accepts y = set[x] as correct syntax - Stack Overflow

admin2025-04-17  2

Just noticed my Python 3.13 interpreter accepts the following syntax:

>>> x
(1, 2, 3)
>>> y = set[x]
>>> y
set[1, 2, 3]
>>> y = set[1,2,3]
>>> y
set[1, 2, 3]
>>> d = dict[1,2,3]
>>> d
dict[1, 2, 3]
>>> type(d)
<class 'types.GenericAlias'>

I am wondering if this a valid syntax, and if so, then what is the use and interpretation of it?

Just noticed my Python 3.13 interpreter accepts the following syntax:

>>> x
(1, 2, 3)
>>> y = set[x]
>>> y
set[1, 2, 3]
>>> y = set[1,2,3]
>>> y
set[1, 2, 3]
>>> d = dict[1,2,3]
>>> d
dict[1, 2, 3]
>>> type(d)
<class 'types.GenericAlias'>

I am wondering if this a valid syntax, and if so, then what is the use and interpretation of it?

Share Improve this question edited Jan 31 at 22:13 TylerH 21.1k79 gold badges79 silver badges114 bronze badges asked Jan 31 at 22:07 haghhagh 5771 gold badge5 silver badges16 bronze badges 4
  • @Barmar I thought type annotations were supposed to reduce the chances of bugs. – Mark Ransom Commented Jan 31 at 22:45
  • I think most people would agree that turning a former syntax error into something that can help eliminate large classes of type errors a reasonable tradeoff. – chepner Commented Jan 31 at 22:49
  • 3 (By the way, this syntax has been supported since Python 3.9; it's not new to 3.13.) – chepner Commented Jan 31 at 22:50
  • I don't think that would ever have been a syntax error anyway. An attribute error perhaps. – mkrieger1 Commented Jan 31 at 23:35
Add a comment  | 

2 Answers 2

Reset to default 3

Types that define the __class_getitem__ method can be "indexed" to support generic types; the method itself returns an instance of types.GenericAlias which at runtime can be treated the same as the type itself (as generic typing is only of interest to static type checkers). Some examples:

>>> s = set[3]
>>> type(s)
<class 'types.GenericAlias'>
>>> s([1,2,3])
{1, 2, 3}

This works because the GenericAlias remembers both the type used to create it and the arguments passed to __class_getitem__:

>>> s.__origin__
<class 'set'>
>>> s.__args__
(3,)

This ability comes from the syntax used for type annotations. Collection type names can be subscripted to specify the types of the elements of a collection, e.g.

set_of_ints = set[int]

myset: set_of_ints = {1, 2, 3}

Your use doesn't actually make sense because x is not a type name. But the Python runtime doesn't do any type validation, so it doesn't care. It just checks the syntax, and syntactically set[x] is analogous to set[int]. You'd probably get an error if you tried to validate your code with a type checker like mypy.

转载请注明原文地址:http://anycun.com/QandA/1744844840a88416.html