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:

class DEFAULT: pass

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

def spam(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 

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

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


class Sentinel(metaclass=SentinelMeta): pass

main.py

from sentinel import Sentinel

class DEFAULT(Sentinel): pass

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

def spam(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"