Unfortunately, mypy does not narrow the type of input_string to Literal["best"]. You can help it with a proper type annotation:

input_string: Literal["best"] = "best"
literal_func(string_input=input_string)

Perhaps worth mentioning that pyright works just fine with your example.


Alternatively, the same can be achieved by annotating the input_string as Final:

from typing import Final, Literal

...

input_string: Final = "best"
literal_func(string_input=input_string)
Answer from Paweł Rubin on Stack Overflow
🌐
Python
typing.python.org › en › latest › spec › literal.html
Literals — typing documentation
In-place addition: If s has type LiteralString and x has a type assignable to LiteralString, then s += x preserves s’s type as LiteralString. String formatting: An f-string has type LiteralString if and only if its constituent expressions are literal strings.
🌐
Mypy
mypy.readthedocs.io › en › stable › literal_types.html
Literal types and Enums - mypy 1.20.0 documentation
These types were added to typing in Python 3.8, but are also available for use in Python 3.4 - 3.7 via the typing_extensions package. Literal types may contain one or more literal bools, ints, strs, bytes, and enum values. However, literal types cannot contain arbitrary expressions: types like Literal[my_string.trim()], Literal[x > 3], or Literal[3j + 4] are all illegal.
Discussions

Python type hints: How to use Literal with strings to conform with mypy? - Stack Overflow
I want to restrict the possible input arguments by using typing.Literal. The following code works just fine, however, mypy is complaining. from typing import Literal def literal_func(string_input: More on stackoverflow.com
🌐 stackoverflow.com
python - What is the difference between string literals and string values? - Stack Overflow
A string literal is what you type into your source code. The string value is what gets output when you print it. ... A string literal is a piece of text you can write in your program's source code, beginning and ending with quotation marks, that tells Python to create a string with certain contents. More on stackoverflow.com
🌐 stackoverflow.com
The LiteralString in Python 3.11
I will never understand why people post on Medium. It offers few benefits and limits your audience. But I digress This is an interesting idea. My first thought was that it’s not needed because you can be careful about what you eval. It’s keeping you safe from yourself. But then when you think about, that’s all type annotations do anyway! More on reddit.com
🌐 r/Python
33
0
January 14, 2024
PEP 675 – Arbitrary Literal String Type - Typing - Discussions on Python.org
This includes other literal values and their conversion to string. The only example provided about other literal types is the next: Other literal types, such as literal integers, are not compatible with LiteralString : some_int: int expect_literal_string(some_int) # Error: Expected LiteralString, ... More on discuss.python.org
🌐 discuss.python.org
1
February 12, 2024
🌐
Python
peps.python.org › pep-0675
PEP 675 – Arbitrary Literal String Type | peps.python.org
November 30, 2021 - There is currently no way to specify, using type annotations, that a function parameter can be of any literal string type. We have to specify a precise literal string type, such as Literal["foo"]. This PEP introduces a supertype of literal string types: LiteralString.
🌐
Python
peps.python.org › pep-0586
PEP 586 – Literal Types - Python Enhancement Proposals
March 14, 2019 - In short, a Literal[...] type may be parameterized by one or more literal expressions, and nothing else. Literal may be parameterized with literal ints, byte and unicode strings, bools, Enum values and None.
🌐
Python documentation
docs.python.org › 3 › library › typing.html
typing — Support for type hints
February 24, 2026 - Any string literal is compatible with LiteralString, as is another LiteralString. However, an object typed as just str is not.
🌐
Towards Data Science
towardsdatascience.com › home › latest › python type hinting with literal
Python Type Hinting with Literal | Towards Data Science
January 22, 2025 - In this article, we’re exploring the creation of literal types, and I wouldn’t want to introduce confusion with this slightly different yet related tool. If you’re interested in learning more, visit the Appendix at the end of the article. However, let’s set this topic aside for now. The key takeaway is that typing.LiteralString is not a substitute for typing.Literal for strings.
Find elsewhere
🌐
Adam Johnson
adamj.eu › tech › 2021 › 07 › 09 › python-type-hints-how-to-use-typing-literal
Python type hints: how to use typing.Literal - Adam Johnson
September 7, 2021 - But when a variable can only contain a limited set of literal values, we can use typing.Literal for its type. This allows the type checker to make extra inferences, giving our code an increased level of safety.
Top answer
1 of 1
21

A string literal is a piece of text you can write in your program's source code, beginning and ending with quotation marks, that tells Python to create a string with certain contents. It looks like

'asdf'

or

'''
multiline
content
'''

or

'the thing at the end of this one is a line break\n'

In a string literal (except for raw string literals), special sequences of characters known as escape sequences in the string literal are replaced with different characters in the actual string. For example, the escape sequence \n in a string literal is replaced with a line feed character in the actual string. Escape sequences begin with a backslash.


A string is a Python object representing a text value. It can be built from a string literal, or it could be read from a file, or it could originate from many other sources.

Backslashes in a string have no special meaning, and backslashes in most possible sources of strings have no special meaning either. For example, if you have a file with backslashes in it, looking like this:

asdf\n

and you do

with open('that_file.txt') as f:
    text = f.read()

the \n in the file will not be replaced by a line break. Backslashes are special in string literals, but not in most other contexts.


When you ask for the repr representation of a string, either by calling repr or by displaying the string interactively:

>>> some_string = "asdf"
>>> some_string
'asdf'

Python will build a new string whose contents are a string literal that would evaluate to the original string. In this example, some_string does not have ' or " characters in it. The contents of the string are the four characters asdf, the characters displayed if you print the string:

>>> print(some_string)
asdf

However, the repr representation has ' characters in it, because 'asdf' is a string literal that would evaluate to the string. Note that 'asdf' is not the same string literal as the "asdf" we originally used - many different string literals can evaluate to equal strings.

🌐
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.
🌐
Turingtaco
turingtaco.com › exploring-the-impact-of-pep-675
The Promise of LiteralString in Python 3.11
December 7, 2024 - But with the addition of LiteralString, we can use it to limit the inputs to our function to strings explicitly written in the Python program, forbidding the use of strings not directly typed in a Python program.
🌐
LWN.net
lwn.net › Articles › 891082
A literal string type for Python [LWN.net]
April 13, 2022 - The type checker, surprisingly, does better than both because it has access to information not available in the runtime or static analysis approaches. Specifically, the type checker can tell us whether an expression has a literal string type, say Literal["foo"]. The type checker already propagates types across variable assignments or function calls. The Literal type has been present since Python 3.8.
🌐
Python.org
discuss.python.org › typing
PEP 675 – Arbitrary Literal String Type - Typing - Discussions on Python.org
February 12, 2024 - This PEP is already implemented in Python, however, I found some uncovered cases. This includes other literal values and their conversion to string. The only example provided about other literal types is the next: Other literal types, such as literal integers, are not compatible with LiteralString : some_int: int expect_literal_string(some_int) # Error: Expected LiteralString, got int. literal_one: Literal[1] = 1 expect_literal_string(literal_one) # Error: Expected LiteralString, got Lite...
🌐
TestDriven.io
testdriven.io › tips › c61d55d8-caa7-4ab4-b611-7356bddc0181
Tips and Tricks - Python type hints - typing.Literal | TestDriven.io
from typing import Literal STATUS = Literal["ACTIVE", "DISABLED"] class User: def __init__(self, username: str, status: STATUS): self.username = username self.status = status user = User("[email protected]", "CREATED") """ mypy example.py example.py:12: error: Argument 2 to "User" has incompatible type "Literal['CREATED']"; expected "Union[Literal['ACTIVE'], Literal['DISABLED']]" Found 1 error in 1 file (checked 1 source file) """
🌐
YouTube
youtube.com › watch
Python Has A "Literal" Type That I've NEVER Seen Before - YouTube
This import from the typing module is incredibly useful when you need to check value types. Sorry about the bad word play in the title.▶ Become job-ready wit...
Published   August 3, 2023
🌐
OpenAI Developer Community
community.openai.com › api
Using typing.Literal for choosing from a set of strings - API - OpenAI Developer Community
November 5, 2024 - I have defined the following class: from typing import List, Optional, Literal, Union from pydantic import BaseModel, EmailStr class Rating(BaseModel): type: Literal["rating"] name: str class Options(TypedDict): color: Literal["yellowBright", "orangeBright", "redBright", "pinkBright", "purpleBright", "blueBright", "cyanBright", "tealBright", "greenBright", "grayBright"] max: int options: Options I assumed that this ...