'Check if string is in string literal type
We use static type checking extensively, but we also need some simple runtime type checking. I'd love to use our static types for that runtime type checking. I've seen typeguard and the other libraries, but I'd prefer to have something simpler.
I've tried below, but assert value in expected_type
doesn't make sense. How do I create a simple function that will check if a string is in a Python string literal?
from typing_extensions import Literal
def check_str_in_literal(value: str, expected_type: Literal):
assert value in expected_type
Gender = Literal["Male", "Female", "Other"]
def print_gender(gender: Gender):
print(gender)
# Unknown string as it's been retrieved from elsewhere
strRetrievedFromDB = "Male" # type: ignore
check_str_in_literal(strRetrievedFromDB, Gender)
print_gender(strRetrievedFromDB)
Solution 1:[1]
Looking at the content of a Literal
, we can see that the values are inside the private attribute __args__
>>> from typing_extensions import Literal
>>> literal = Literal["a", "b", "c"]
>>> literal.__dict__
{'_inst': True,
'_name': None,
'__origin__': typing.Literal,
'__slots__': None,
'__args__': ('a', 'b', 'c'),
'__parameters__': (),
'__module__': 'typing'}
Therefore, one way if really need to use Literal
is to do as such:
def check_str_in_literal(value: str, expected_type: Literal):
assert value in expected_type.__args__
However, it's usually not a good idea to use private attributes.
As mentioned in comments, you could also used Enum
(or other type of enums from enum
module), as such:
import enum
from typing import Optional
class Gender(enum.Enum):
Male = enum.auto()
Female = enum.auto()
Other = enum.auto()
def get_gender(gender:str) -> Optional[Gender]:
"""Get an Enum Gender from its name (None if not valid)"""
try:
return Gender[gender]
except KeyError:
return None
def print_gender(gender:Gender) -> None:
"""Do something with a gender"""
print(gender.name)
gender_from_db = "Male"
gender = get_gender(gender_from_db)
if gender:
print_gender(gender)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Jean-Francois T. |