endolith
endolith

Reputation: 26804

How to create a return flag object

Currently a set of functions returns success=True or False.

We've discovered this isn't good enough, though, since False can convey both "valid result" or "invalid result", and we want behavior to differ in each case.

So I think they should be changed to instead return {True, False, InvalidResult}, where bool(InvalidResult) is false for backward compatibility, but can be tested for using if is InvalidResult.

I'm not sure what the terminology is, but I'm imagining something like the built-in NotImplemented that's returned by comparison functions. This is called a "special value" in the docs and is of type NotImplementedType.

How to create such an object and what methods/attributes should it have? I should create my own type like NotImplementedType also, or is there an existing type that conveys this "flag" concept? It's a similar kind of object to True, False, None, NotImplemented, etc.

Upvotes: 0

Views: 1865

Answers (2)

endolith
endolith

Reputation: 26804

Apparently this is called a "sentinel" and is a simple as this:

class InvalidResultType(object):
    """
    Indicates that minimization has failed and result is invalid (such as a
    boundary or constraint violation)
    """
    def __repr__(self):
        return 'InvalidResult'
    def __bool__(self):
        return False
    def __reduce__(self):
        return 'InvalidResult'

InvalidResult = InvalidResultType()


success = InvalidResult

assert success == InvalidResult
assert success is InvalidResult
assert not bool(InvalidResult)
assert InvalidResult != True
assert InvalidResult != False  # Not sure about this yet
assert InvalidResult != None

Now of course I find the similar questions:

Defining my own None-like Python constant

and the __reduce__ might be overkill; I'm not sure if pickling or copying will ever matter

How to create a second None in Python? Making a singleton object where the id is always the same

Upvotes: 1

Matthias Fripp
Matthias Fripp

Reputation: 18625

You could just use None or 0 as the InvalidResult value, e.g. in my_mod, define InvalidResult = None, then elsewhere you can test if result is my_mod.InvalidResult. See here for some more info on the "truthfulness" of None: False or None vs. None or False

Or you could define an object with suitable methods for Boolean conversion; hopefully others will chime in with those details.

Note that whichever way you go, you'll have to be careful if you have multipart Boolean expressions: InvalidResult and False will give InvalidResult but False and InvalidResult will give False.

Upvotes: 1

Related Questions