How should I use the Optional type hint in Python?

How should I use the Optional type hint in Python?

I am trying to understand how to use the Optional type hint. According to PEP-484, I know that Optional can be used for a function like def test(a: int = None), which is equivalent to def test(a: Union[int, None]) or def test(a: Optional[int]).

But how should I handle cases like the following examples?

def test(a: dict = None):
    #print(a) ==> {'a': 1234}
    #or
    #print(a) ==> None

def test(a: list = None):
    #print(a) ==> [1, 2, 3, 4, 'a', 'b']
    #or
    #print(a) ==> None

Since Optional[type] seems to mean the same thing as Union[type, None], why should I use Optional[] at all? How does Python optional differ from using Union in these cases?

Understanding Optional as a shorthand for Union: The Optional[type] is just a shorthand for Union[type, None].

While both indicate that a value could either be of the specified type or None, Optional is preferred for readability and clarity. In the case of functions like def test(a: dict = None) or def test(a: list = None), you could explicitly write them as def test(a: Optional[dict] = None) or def test(a: Optional[list] = None).

This makes the intention clear: a could either be a dict/list or None.

If you expect the parameter to always be a specific type and None is not intended as a valid value (other than for default initialization), avoid using Optional.

For example, def test(a: dict) (without Optional) is better when a must be a dictionary and can be None, whereas def test(a: Optional[dict] = None) is suitable if None is a valid default or expected value.

When a function has default None values, and you want to indicate that a parameter could be of a specific type or None, Optional is appropriate.

For instance, def test(a: Optional[dict] = None) is more explicit and communicates that a can be a dictionary or None, which matches the default behavior of using None as a placeholder. This provides clarity over using Union directly.