41

In Python 3, I would like to check whether value is either string or None.

One way to do this is

assert type(value) in { str, NoneType }

But where is NoneType located in Python?

Without any import, using NoneType produces NameError: name 'NoneType' is not defined.

martineau
  • 119,623
  • 25
  • 170
  • 301
Tregoreg
  • 18,872
  • 15
  • 48
  • 69
  • 2
    You should also use `isinstance`. It can take a tuple of types to check. `isinstance(value, (str, type(None)))` – Silas Ray Feb 11 '14 at 15:54
  • 1
    If this is not for unit testing, one could argue that you usually shouldn't type check at all. – Brave Sir Robin Feb 11 '14 at 15:57
  • @rmartinjak: some programmers still like to validate their coding assumptions with an `assert` statement. The support is there. *I* wouldn't use assertions and would use unit testing too, but if you are using `assert` anyway.. – Martijn Pieters Feb 11 '14 at 16:00
  • Sorry if my question was put wrong, I know about `isinstance(object, class-or-type-or-tuple)`, I just wanted to focus on the problem of `NoneType`'s location. – Tregoreg Feb 11 '14 at 16:00

3 Answers3

54

You can use type(None) to get the type object, but you want to use isinstance() here, not type() in {...}:

assert isinstance(value, (str, type(None)))

The NoneType object is not otherwise exposed anywhere in Python versions older than 3.10*.

I'd not use type checking for that at all really, I'd use:

assert value is None or isinstance(value, str)

as None is a singleton (very much on purpose) and NoneType explicitly forbids subclassing anyway:

>>> type(None)() is None
True
>>> class NoneSubclass(type(None)):
...     pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: type 'NoneType' is not an acceptable base type

* As of Python 3.10, you could use types.NoneType, to be consistent with the other singleton types being added to the types module.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
10

types.NoneType is being reintroduced in Python 3.10.

What’s New In Python 3.10

Improved Modules

types

Reintroduced the types.EllipsisType, types.NoneType and types.NotImplementedType classes, providing a new set of types readily interpretable by type checkers. (Contributed by Bas van Beek in bpo-41810.)

The discussion about the change was motivated by a need for types.EllipsisType, leading to types.NoneType also being added for consistency.

bad_coder
  • 11,289
  • 20
  • 44
  • 72
0

Please use type(None). You can use python shell to check like in the below function in which I use type(None) in order to change from None to NoneType.

def to_unicode(value):
'''change value to unicode'''
try:
    if isinstance(value, (str,type(None))):
        return value
    if not isinstance(value, bytes):
        raise TypeError("Expected bytes, unicode, or None; got %r" % type(value))
    return value.decode("utf-8")
except UnicodeDecodeError:
    return repr(value)
vss
  • 1,093
  • 1
  • 20
  • 33
ZosionLee
  • 41
  • 1
  • 2