-1

I have a function which should check if the incoming object is allowed or not.

Why this Function Failing For None Type.

def is_valid_object(obj):
    allowed_types = [int, bool, None]
    return type(obj) in allowed_types

Working for:

is_valid_object('i am string') Expected False => Returns False

is_valid_object(10) Expected True => Returns True

is_valid_object(False) Expected True => Returns True


Why This Fails:

is_valid_object(None) Expected True => Returns False

Peter Pitt
  • 35
  • 4

3 Answers3

6

None is not a type, it's the single value of the NoneType type. Use type(None) to access that type to put it in your allowed types list:

allowed_types = [int, bool, type(None)]

In my view is is better to just explicitly test for the None singleton with obj is None, as that's much clearer in intent:

allowed_types = [int, bool]
return obj is None or type(obj) in allowed_types

Instead of using type(obj) in allowed_types, consider using isinstance() with a tuple second argument:

def is_valid_object(obj):
    return obj is None or isinstance(obj, (int, bool))

which can be simplified to:

def is_valid_object(obj):
    return obj is None or isinstance(obj, int)

because bool is a subclass of int.

Demo:

>>> def is_valid_object(obj):
...     return obj is None or isinstance(obj, int)
...
>>> is_valid_object(42)
True
>>> is_valid_object(False)
True
>>> is_valid_object(None)
True
>>> is_valid_object('Hello world!')
False
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
2

Unlike the int and bool, type(None) is not equal to None

print(type(None))

NoneType

To workaround you can do:

def is_valid_object(obj):
    allowed_types = [int, bool, type(None)]
    return type(obj) in allowed_types

Output:

print(is_valid_object(None))

True

Rajan
  • 1,463
  • 12
  • 26
0

None is a value, not a type. There is no built-in name for the type of None. Use either

def is_valid_object(obj):
    allowed_types = [int, bool, type(None)]
    return type(obj) in allowed_types

or (Python 2 only)

from types import NoneType

def is_valid_object(obj):
    allowed_types = [int, bool, NoneType]
    return type(obj) in allowed_types

Either way, your function can be simplified (and made more correct) by using isinstance rather than type comparison.

def is_vali_object(obj):
    return isinstance(obj, (int, bool, type(None)))

(Since None is the only value of its type, though, it's easier to check obj is None directly as Martijn Pieters shows.)

chepner
  • 497,756
  • 71
  • 530
  • 681