Search code examples
pythonpython-typingpep8

Python Annotate Two Exact Strings for Function Parameter


Say I have a function foo, that takes in a parameter a. I would like to annotate the function to indicate that a should only accept 2 strings - 'string1' and 'string2'

What I currently have is (python<3.10):

from typing import Union

def foo(a: Union['string1', 'string2']):
    pass

Also, is there a way to indicate that a function returns a tuple of 2 sets of 2 data types?
i.e. foo would return a tuple of 2 strings and 2 ints, at the exact same position every time

from typing import Tuple

def foo() -> Tuple[int, str, int, str]:
    return 1, 's1', 2, 's2'

I would not like to go with Tuple[int, str] as the order should be annotated


Solution

  • Your first question (side note: please don't ask two separate question in one, it's more difficult to answer and search) is about Literal type. It will be

    import sys
    if sys.version_info < (3, 8):
        from typing_extensions import Literal
    else:
        from typing import Literal
    
    def foo(a: Literal['string1', 'string2']) -> None:
        pass
    

    Your second question is a bit odd, because the code you show is exactly what you need. Tuple accepts arbitrary number of type arguments (including () to specify empty tuple). Tuple[int, str, int] is a tuple of exactly 3 elements of types int, str, int in this specific order. Special case: Tuple[int, ...] (note literal ellipsis - it's part of syntax) represents tuple of arbitrary length containing only int's. Tuple that contains any number of int's or str's will be Tuple[Union[str, int], ...]. Fixed-length tuple (without ellipsis) may contain any types. You can read more in docs.