Skip to content Skip to sidebar Skip to footer

Type-hinting Parameters With A Sentinel Value As The Default

I currently use this strategy when I cannot assign default arguments in a function's signature and/or None already has meaning. from typing import Optional DEFAULT = object() #

Solution 1:

As I commented, this is an active area of development in Python. PEP 661 proposes to add a sentinel function that creates a sentinel object, but until that PEP is approved, you're on your own.

You can take inspiration from some of the proposed (or rejected) options in the PEP however. One very simple approach that plays reasonably well with type hinting is to make your sentinel value a class:

classDEFAULT: pass

Now you can type-hint your function as taking a union of types that includes type[DEFAULT]:

defspam(ham: list[str]|None|type[DEFAULT] = DEFAULT):

Solution 2:

Something I like to do — which is only a slight variation on @Blckknght's answer — is to use a metaclass to give my sentinel class a nicer repr and make it always-falsey.


sentinel.py

from typing import Literal 

classSentinelMeta(type):
    def __repr__(cls) -> str:
        return f'<{cls.__name__}>'

    def __bool__(cls) -> Literal[False]:
        return False


classSentinel(metaclass=SentinelMeta): pass

main.py

from sentinel import Sentinel

classDEFAULT(Sentinel): pass

You use it in type hints exactly in the same way @Blckknght suggests:

defspam(ham: list[str]|None|type[DEFAULT] = DEFAULT): ...

But you have the added advantages that your sentinel value is always falsey and has a nicer repr:

>>> DEFAULT
<DEFAULT>
>>> bool(DEFAULT)
False

Post a Comment for "Type-hinting Parameters With A Sentinel Value As The Default"