Go the other way around, and build VALID_ARGUMENTS from Argument:

Argument = typing.Literal['foo', 'bar']
VALID_ARGUMENTS: typing.Tuple[Argument, ...] = typing.get_args(Argument)

I've used a tuple for VALID_ARGUMENTS here, but if for some reason you really prefer a list, you can get one:

VALID_ARGUMENTS: typing.List[Argument] = list(typing.get_args(Argument))

It's possible at runtime to build Argument from VALID_ARGUMENTS, but doing so is incompatible with static analysis, which is the primary use case of type annotations.

Doing so is also considered semantically invalid - the spec forbids parameterizing Literal with dynamically computed parameters. The runtime implementation simply doesn't have the information it would need to validate this. Building VALID_ARGUMENTS from Argument is the way to go.

Answer from user2357112 on Stack Overflow
🌐
Python
typing.python.org › en › latest › spec › literal.html
Literals — typing documentation
variable_annotation: LiteralString def my_function(literal_string: LiteralString) -> LiteralString: ... class Foo: my_attribute: LiteralString type_argument: List[LiteralString] def enforce_literal[T: LiteralString](value: T) -> T: return value
Discussions

Is using list() preferred over []?
They're for different things. list() is a basic constructor which takes an iterable (like a set, or a dict, or a generator) and returns a list with the same elements. [] is an additional constructor which takes a number of arguments and makes a list where each argument is an item of the list. [] is also the wrapping of a list comprehension. For example: st = {1,2,3} lst1 = list(st) # returns [1, 2, 3] (or whatever order), a list of length 3 lst2 = [st] # returns [{1,2,3}], a list of length 1 If you're creating an empty object (which is, I think, what you're talking about here), then think about distinguishing the difference between literals [0,1,2], comprehensions [i for i in range(3)] and the basic constructors list(range(3)). list() is marginally slower than [], because it's expecting an input to iterate over. However, in the case of dicts and sets, which both use curly braces in their literals and comprehensions, I find it's more explicit to use dict() and set() if you're making an empty one. And explicit is better than implicit. More on reddit.com
🌐 r/learnpython
30
31
June 3, 2015
Introduce a "bareword" list/dict literal - Ideas - Discussions on Python.org
One of the annoyances when I jumped from Perl to Python many years ago was the lack of a qw-equivalent operator/literal that would make a common pattern of defining a long list of words/identifiers clean and easy, where the Perl expression: qw(foo bar baz) is semantically equivalent to the ... More on discuss.python.org
🌐 discuss.python.org
2
December 25, 2023
python - Why do the list function and list literals act differently? - Stack Overflow
I was trying to create a list with n empty lists inside of it, but faced an interesting situation. Firstly I tried the following: >>> n = 3 >>> list([]) * n [] It creates an empt... More on stackoverflow.com
🌐 stackoverflow.com
coding style - Literals versus instantiating by name lists and dicts in Python? - Software Engineering Stack Exchange
Once I'm using the named constructors ... even though the empty list literal [] looks decently and I'm not aware of any bad surprises that its usage might cause. ... Unless you're doing it in a tight loop there's not much difference, but any Python programmer should be able to ... More on softwareengineering.stackexchange.com
🌐 softwareengineering.stackexchange.com
May 26, 2016
🌐
Mypy
mypy.readthedocs.io › en › stable › literal_types.html
Literal types and Enums - mypy 1.20.0 documentation
list_of_ints = [] list_of_ints.append(a) reveal_type(list_of_ints) # Revealed type is "list[int]" # But if the variable you're appending is an explicit Literal, mypy # will infer list[Literal[19]]. list_of_lits = [] list_of_lits.append(b) reveal_type(list_of_lits) # Revealed type is "list[Literal[19]]" We can use Literal types to more precisely index into structured heterogeneous types such as tuples, NamedTuples, and TypedDicts. This feature is known as intelligent indexing. For example, when we index into a tuple using some int, the inferred type is normally the union of the tuple item types
🌐
GeeksforGeeks
geeksforgeeks.org › python › literals-in-python
Literals in Python - GeeksforGeeks
July 15, 2025 - Literals in Python are fixed values written directly in the code that represent constant data. They provide a way to store numbers, text, or other essential information that does not change during program execution. Python supports different types of literals, such as numeric literals, string literals, Boolean literals, and special values like None.
🌐
Python
peps.python.org › pep-0586
PEP 586 – Literal Types - Python Enhancement Proposals
March 14, 2019 - Literal types indicate that some expression has literally a specific value. For example, the following function will accept only expressions that have literally the value “4”: from typing import Literal def accepts_only_four(x: Literal[4]) -> None: pass accepts_only_four(4) # OK accepts_only_four(19) # Rejected
🌐
Codereview
codereview.doctor › features › python › best-practice › use-list-set-dict-literals
Use literals instead of calling list/set/dict best practice | codereview.doctor
Using list/set/dict literal syntax is simpler and computationally quicker than calling list(), set(), or dict(). A literal is a terse and easily understood way to write a value without having to call the Python builtin function. A literal is syntax that the parser recognises as writing an object ...
🌐
Google
developers.google.com › google for education › python › python lists
Python Lists | Python Education | Google for Developers
January 23, 2026 - Python has a great built-in list type named "list". List literals are written within square brackets [ ]. Lists work similarly to strings -- use the len() function and square brackets [ ] to access data, with the first element at index 0.
Find elsewhere
🌐
Tutorialspoint
tutorialspoint.com › python › python_literals.htm
Python - Literals
Individual object in the collection is accessed by index starting with zero. Literal representation of a list object is done with one or more items which are separated by comma and enclosed in square brackets [].
🌐
Reddit
reddit.com › r/learnpython › is using list() preferred over []?
r/learnpython on Reddit: Is using list() preferred over []?
June 3, 2015 -

I've been using PyCharm as my IDE, and it always asks me to switch over all my []s and {}s to list() and dict() respectively. So is using list() and dict() preferred over using [] and {}?

Also, I always thought that [] was the literal notation, but PyCharm says that list() is. I got that idea from JSON, btw. So is list() the literal notation? If yes, what is [] called?

Top answer
1 of 4
21
They're for different things. list() is a basic constructor which takes an iterable (like a set, or a dict, or a generator) and returns a list with the same elements. [] is an additional constructor which takes a number of arguments and makes a list where each argument is an item of the list. [] is also the wrapping of a list comprehension. For example: st = {1,2,3} lst1 = list(st) # returns [1, 2, 3] (or whatever order), a list of length 3 lst2 = [st] # returns [{1,2,3}], a list of length 1 If you're creating an empty object (which is, I think, what you're talking about here), then think about distinguishing the difference between literals [0,1,2], comprehensions [i for i in range(3)] and the basic constructors list(range(3)). list() is marginally slower than [], because it's expecting an input to iterate over. However, in the case of dicts and sets, which both use curly braces in their literals and comprehensions, I find it's more explicit to use dict() and set() if you're making an empty one. And explicit is better than implicit.
2 of 4
5
PyCharm hasn't done that to me, as far as I have noticed. Anyway it certainly is wrong. Literals are much preferred. Also faster because they compile directly to bytecode, while list() turns into a load of global name ("list"), and then a function call on that value. I might add that just because a yellow lamp appears to the left of an line does not mean PyCharm wants you to change that line, it only means that it has automatic helpers to do it for you. Of course warning do also appear under the lamp. Alt-enter brings up the lamp menu, so if you ever have a reason to change from literal to function call it's there for easy access. Consider: a = dict(x=4, y=2$) # the $ denotes your cursor Press Alt-Enter + Enter, and it turns to: a = {'x'=4, 'y'=2}
🌐
Python Forum
python-forum.io › thread-29843.html
What Are Python Literals?
September 22, 2020 - What Are Python Literals? I have been doing a lot of research and keep coming across vague and conflicting definitions of what literals are in Python. The most common vague description is a literal is literally the value you are wanting to assign t...
🌐
Scaler
scaler.com › home › topics › python › literals in python
Literals in Python - What are Python Literals? | Scaler Topics
June 27, 2024 - Python literals have one special literal known as None. This literal in Python is used to signify that a particular field is not created. Python will print None as output when we print the variable with no value assigned to it. None is also used for end of lists in Python.
🌐
Medium
medium.com › @nekadiraju › python-list-explained-093ce330ece0
Python List Explained. Python list is built in data type in… | by Raju Nekadi | Medium
February 13, 2024 - The most popular way to create a list object in Python is through list literal. These literals are fairly straightforward.
🌐
Python.org
discuss.python.org › ideas
Introduce a "bareword" list/dict literal - Ideas - Discussions on Python.org
December 25, 2023 - One of the annoyances when I jumped from Perl to Python many years ago was the lack of a qw-equivalent operator/literal that would make a common pattern of defining a long list of words/identifiers clean and easy, where the Perl expression: qw(foo bar baz) is semantically equivalent to the list: "foo", "bar", "baz" Wouldn’t it be nice if we can take advantage of one of the currently meaningless pairs of symbols, say , to denote a list literal where barewords are parsed not as names bu...
🌐
WsCube Tech
wscubetech.com › resources › python › literals
Literals in Python: All Types With Examples
November 5, 2025 - Understand Python literals, their types, benefits, and examples. Learn how to use Python literals effectively in programming for better code readability.
🌐
GitHub
github.com › microsoft › pyright › issues › 5366
Automatically typed Literal strings in tuples in lists cause invariance errors · Issue #5366 · microsoft/pyright
June 22, 2023 - Describe the bug When the type of a string, within a tuple, within a list is automatically determined, it is regarded as a Literal. list[tuple[Literal["whatever"]]] This can then not be assigned to a list[tuple[str]] To Reproduce run pyright ...
Author   Vegemash
🌐
Reddit
reddit.com › r/learnpython › unpacking container values to literal type
r/learnpython on Reddit: Unpacking container values to Literal type
April 24, 2025 -

I want to create a type alias for a Literal type from the values of a container (list, tuple, members of an Enum, whatever). This would be nice and DRY as the type could inherit the values of the container as my developing API evolves.

My only issue is that MyPy doesn't appreciate it (Invalid type alias: expression is not a valid type [valid-type]). But I'm inclined to say yeet and go with it. Thoughts?

from typing import Literal

modes = ("r", "w", "a")

# The WET (write everything twice) way
type ModeVals1 = Literal["r", "w", "a"]

# The DRY (don't repeat yourself) way
type ModeVals2 = Literal[*modes]
# functionally equivalent right?


# In use
def my_func(mode: ModeVals2, ...):
    ...
🌐
Pylint
pylint.readthedocs.io › en › latest › user_guide › messages › refactor › use-list-literal.html
use-list-literal / R1734 - Pylint 4.1.0-dev0 documentation
May 23, 2023 - Emitted when using list() to create an empty list instead of the literal []. The literal is faster as it avoids an additional function call.
🌐
GeeksforGeeks
geeksforgeeks.org › python › dynamic-testing-of-values-against-python-literal-types
Dynamic Testing of Values Against Python Literal Types - GeeksforGeeks
July 23, 2025 - # code from typing import Literal def get_fruit(fruit: Literal['apple', 'banana', 'cherry']) -> str: return fruit · This function will only accept 'apple', 'banana', or 'cherry' as valid arguments. Any other value will result in a type error if checked by a type checker like mypy. To dynamically test if a value conforms to a Python Literal type, you can use the typing_extensions module, which provides compatibility with older versions of Python (prior to 3.8) and allows you to define and check for literal types using Literal.