From your example:

def foo(
        hello: str='world', bar: str=None,
        another_string_or_None: str|????=None):
    ...

I've noticed that your use case is "something or None".

Since version 3.5, Python supports type annotations via typing module. And in your case, the recommended way of annotating is by using typing.Optional[something] hint. This has exact meaning you're looking for.

Therefore the hint for another_string_or_None would be:

import typing

def foo(
        hello: str='world', bar: str=None,
        another_string_or_None: typing.Optional[str]=None):
    ...
Answer from mbdevpl on Stack Overflow
๐ŸŒ
Python documentation
docs.python.org โ€บ 3 โ€บ library โ€บ typing.html
typing โ€” Support for type hints
An optional argument with a default does not require the Optional qualifier on its type annotation just because it is optional. For example: ... On the other hand, if an explicit value of None is allowed, the use of Optional is appropriate, whether the argument is optional or not.
๐ŸŒ
Reddit
reddit.com โ€บ r/python โ€บ do you like `def call() -> none: ...`
r/Python on Reddit: Do you like `def call() -> None: ...`
March 21, 2024 -

So, I wanted to get a general idea about how people feel about giving return type hint of None for a function that doesn't return anything.

With the introduction of PEP 484, type hints were introduced and we all rejoiced. Lot of my coworkers just don't get the importance of type hints and I worked way too hard to get everyone onboarded so they can see how incredibly useful it is! After some time I met a coworker who is a fan of typing and use it well... except they write -> None everywhere!

Now this might be my personal opinion, but I hate this because it's redundant and not to mention ugly (at least to me). It is implicit and by default, functions return None in python, and I just don't see why -> None should be used. We have been arguing a lot over this since we are building a style guide for the team and I wanted to understand what the general consensus is about this. Even in PEP 484, they have mentioned that -> None should be used for __init__ functions and I just find that crazy.

Am I in the wrong here? Is this fight pointless? What are your opinions on the matter?

๐ŸŒ
Python.org
discuss.python.org โ€บ python help
Type hint for "Any But Not None" - Python Help - Discussions on Python.org
March 2, 2021 - Is there a way to specify that a certain parameter can be anything except None? Better still if we can specify a โ€œNot one of these typesโ€ annotation.
๐ŸŒ
Mypy
mypy.readthedocs.io โ€บ en โ€บ stable โ€บ cheat_sheet_py3.html
Type hints cheat sheet - mypy 1.19.1 documentation
from typing import Union, Any, Optional, TYPE_CHECKING, cast # To find out what type mypy infers for an expression anywhere in # your program, wrap it in reveal_type(). Mypy will print an error # message with the type; remove it again before running the code. reveal_type(1) # Revealed type is "builtins.int" # If you initialize a variable with an empty container or "None" # you may have to help mypy a bit by providing an explicit type annotation x: list[str] = [] x: str | None = None # Use Any if you don't know the type of something or it's too # dynamic to write a type for x: Any = mystery_function() # Mypy will let you do anything with x!
๐ŸŒ
Reddit
reddit.com โ€บ r/learnpython โ€บ type hinting weirdness with "none" as default value when i need to default to class' initial value or get a value from user
r/learnpython on Reddit: Type hinting weirdness with "None" as default value when I need to default to class' initial value or get a value from user
March 29, 2023 -

Sorry for the confusing title.

I have been adding some type hinting into my code and noticed that if I have something like:

def create(self, a: int = None) -> None
a = a or self.a

Where I would like to have the user either give a as an int or just skip it and the function will default to the class' initial value for a. This works just fine but this shows in the IDE as create(self, a: int | None = None) -> None which looks like None is a valid value for a, even though that is not what I am looking for.

Then if I have an artificial case like:

def create(self, a: int = 'test') -> None
...

Which then shows up as create(self, a: int = 'test') -> None which looks weird but at least it doesn't explicitly imply that str is a valid parameter.

So I guess two questions: what makes None special? And, is this the way to use type hinting when I need to default to class' initial value or get an argument from user?

๐ŸŒ
FastAPI
fastapi.tiangolo.com โ€บ python-types
Python Types Intro - FastAPI
Python has support for optional "type hints" (also called "type annotations"). These "type hints" or annotations are a special syntax that allow declaring the type of a variable.
๐ŸŒ
Dagster
dagster.io โ€บ blog โ€บ python-type-hinting
Using Type Hinting in Python Projects
The Optional type hint can be used to indicate that a variable can be either a specific type or None.
Find elsewhere
๐ŸŒ
Pybites
pybit.es โ€บ articles โ€บ code-better-with-type-hints-part-3
Code Better With Type Hints โ€“ Part 3 - Pybites
September 20, 2022 - Each example will cover a certain topic and look at type hints from a slightly different perspective. Most examples will end with a tip or best practice to help you improve your type hint skills! A variable might be initialized as an empty container or None because its actual content is assigned later in the code.
๐ŸŒ
Python
peps.python.org โ€บ pep-0484
PEP 484 โ€“ Type Hints | peps.python.org
All newly introduced names used to support features described in following sections (such as Any and Union) are available in the typing module. When used in a type hint, the expression None is considered equivalent to type(None).
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ python โ€บ type-hints-in-python
Type Hints in Python - GeeksforGeeks
May 3, 2025 - Type hints are not enforced by the Python interpreter; they are purely for static analysis by external tools like mypy. So, even with type hints, the code will still run with errors unless a static type checker is used.
๐ŸŒ
Python
docs.python.org โ€บ 3.8 โ€บ library โ€บ typing.html
typing โ€” Support for type hints โ€” Python 3.8.20 documentation
Provide basic introspection for generic types and special typing forms. For a typing object of the form X[Y, Z, ...] these functions return X and (Y, Z, ...). If X is a generic alias for a builtin or collections class, it gets normalized to the original class. For unsupported objects return None and () correspondingly.
๐ŸŒ
Open Water Foundation
learn.openwaterfoundation.org โ€บ owf-learn-python โ€บ lessons โ€บ type-hints โ€บ type-hints
Type Hints - OWF Learn Python
Python functions can accept optional parameters. An Optional type hint can be used to indicate that a function parameter is optionally None, as in the following example that accepts a list of str or None as input:
๐ŸŒ
Reddit
reddit.com โ€บ r/python โ€บ python type hints and why you should use them.
r/Python on Reddit: Python Type Hints and why you should use them.
February 17, 2025 -

https://blog.jonathanchun.com/2025/02/16/to-type-or-not-to-type/

I wrote this blog post as I've seen a lot of newer developers complain about Type hints and how they seem unnecessary. I tried to copy-paste a short excerpt from the blog post here but it kept detecting it as a question which is not allowed, so decided to leave it out.

I know there's plenty of content on this topic, but IMO there's still way too much untyped Python code!

๐ŸŒ
Reddit
reddit.com โ€บ r/python โ€บ union[str, none] vs optional[str]
r/Python on Reddit: Union[str, None] vs Optional[str]
December 9, 2020 -

Recently, one of my coworkers and I had a long debate on using Union[str, None] vs Optional[str]. I wrote a function that was supposed to return either a string or None. Based on the returned value my program was supposed to trigger some action. In my opinion, since None was a deciding factor it would be a better choice to use Union[str, None] for the sake of clarity. However, according to his opinion, Optional is a better choice in terms of simplicity/cleaner look. We both understand clearly that Optional is nothing but a shorthand of Union[..., None]. After a few searches, we figured people use both and both teams have their logic. In fact, the creator of Fast API, u/tiangolo also supports using Union (According to one of his recent tweets). My question is, what do you use and why?

๐ŸŒ
Better Stack
betterstack.com โ€บ community โ€บ guides โ€บ scaling-python โ€บ python-type-hints
A Complete Guide to Python Type Hints | Better Stack Community
Python's type system provides elegant ways to express variables that can have multiple types or be absent. This is especially useful when dealing with optional return values or inputs that can vary in type. ... from typing import Optional, Union # Can return a string or None def find_user(user_id: int) -> Optional[str]: user_database = {1: "John", 2: "Jane"} return user_database.get(user_id) # Can accept either string or bytes def process_input(data: Union[str, bytes]) -> str: if isinstance(data, bytes): return data.decode('utf-8') return data
๐ŸŒ
Nelson
nelson.cloud โ€บ posts โ€บ optional type hints in python
Optional Type Hints in Python | Nelson Figueroa
January 16, 2024 - Python lets you write optional type hints where you can return either a specified type or None.
๐ŸŒ
Medium
medium.com โ€บ @laurentkubaski โ€บ python-type-hints-how-many-ways-can-you-say-optional-a940f7ef03e2
Python Type Hints: How Many Ways Can You Say โ€˜Optionalโ€™? | by Laurent Kubaski | Medium
September 2, 2025 - Union[str, None] # This means the parameter doesn't have to be sent Optional[str] # this means the parameter should be sent, but can be None ยท Yes, this is incorrect: those 2 type hints actually mean the same thing (ie: โ€œThe parameter can ...
๐ŸŒ
Real Python
realpython.com โ€บ python-type-hints-multiple-types
How to Use Type Hints for Multiple Return Types in Python โ€“ Real Python
March 8, 2024 - Then, a pipe operator (|) followed by None indicates that the return value could be either a two-string tuple or None, depending on the input value. To implement the same function in Python earlier than 3.10, use the Tuple and Union types from ...