Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to create a falsy sentinel object in Python?

I have a function which is designed to be called by passing in one of to keyword arguments. I’m using a sentinel object as default value, so that I can make sure no one just calls func() without any arguments, which is a clear logical error. It is ok to call the function by passing None as a value for one of the arguments, in those cases it just doesn’t do any processing.

NO_VALUE = object()


def func(*, arg1 = NO_VALUE, arg2 = NO_VALUE):
    if arg1 is NO_VALUE and arg2 is NO_VALUE:
        raise ValueError("Pass in one of `arg1` or arg2`.")

    if arg1 is not NO_VALUE and arg1:
        # Do something with a truthy `arg1` value.
    if arg2 is not NO_VALUE and arg2:
        # Do something with a truthy `arg2` value.

Could I somehow easily make NO_VALUE be falsy, so that I could simplify the if arg1 is not NO_VALUE and arg1 and if arg2 is not NO_VALUE and arg2 to just if arg1 and if arg2 respectively?

I tried making NO_VALUE an empty tuple () but it seems that the id() of an empty tuple is always(?) same as the id() of any other empty tuple. I also don’t want to make NO_VALUE e.g. an empty list object, since then I’d get linter warnings about using a mutable default value.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

In any case: for a Python object to be "Falsy" it can be an instance of a class which implements __bool__ and returns False when that is called:

class FalsySentinel:
    def  __bool__(self):
        return False


NO_VALUE = FalsySentinel()


def func(*, arg1 = NO_VALUE, arg2 = NO_VALUE):
    if arg1 is NO_VALUE and arg2 is NO_VALUE:
        raise ValueError("Pass in one of `arg1` or arg2`.")

    if arg1:
        # Do something with a truthy `arg1` value.
    if arg2:
        # Do something with a truthy `arg2` value.

There are other ways to produce falsy objects, like objects that implement __len__ and return 0 on it – but this is the most explicit and straightforward way.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading