Why am I getting an error message in Python 'cannot import name NoneType'?
Asked Answered
G

5

31

I'm trying to convert some code from 2 to 3 and the following simple script

import types
from types import NoneType

Results in

ImportError: cannot import name NoneType

How can I convert the above from 2 to 3?

Gaitskell answered 5/4, 2013 at 22:34 Comment(2)
As there is only ever one instance of NoneType, x is None is exactly equal to isinstance(x, NoneType). If you are checking type against None, something is wrong.Foursome
@GarethLatty It's useful for the tuple use case. isinstance(json_compatible_basic_type_expected, (int, float, str, NoneType))Desmarais
G
49

There is no longer a NoneType reference in the types modules. You should just check for identity with None directly, i.e. obj is None. An alternative way, if you really need the NoneType, would be to get it using:

NoneType = type(None)

This is actually the exact same way types.NoneType was previously defined, before it was removed on November 28th, 2007.

As a side note, you do not need to import a module to be able to use the from .. import syntax, so you can drop your import types line if you don’t use the module reference anywhere else.

Godin answered 5/4, 2013 at 22:36 Comment(0)
G
2

Fetching the NoneType is useful when performing validation, to abbreviate the chain of conditions passing the allowed None type in the tuple of acceptable types. So instead of writing something like:

a = {
    # A dict with some fields...
}

# In this example, the optional field is valid if it is a string
is_valid = (
    a.get(optional_field) is None
    or isinstance(a[optional_field], str)
)

One could write:

is_valid = isinstance(a.get(optional_field), (str, NoneType))

It is possible to work around this issue by passing a default string value to .get(...) (because in the absence of the field, you would be returning something that intentionally passes the validation, even if the value is not there), but it's too hacky, obscure and really affects readability.

As NoneType is not something you can import anymore, you can make your own when needed. These are some options:

NoneType = type(None)
NoneType = None.__class__

The linter may complain that a variable called NoneType doesn't comply with your naming convention, if you are following PEP8 recommendations. I find it easier to simply use type(None) wherever you need a NoneType. It's only two chars difference, just as readable and you save a line of code ;)

The final solution for the snippet above would look like:

is_valid = isinstance(a.get(optional_field), (str, type(None)))
Giltedged answered 5/1, 2022 at 15:3 Comment(0)
T
0

If your use case allows it, you can:

if my_dict.get('key'):  # By Default: returns None if key doesn't exists
    # Do something
else:
    # Do something with None

None is a falsy value so you can get away with if-else statement without importing anything.

Torry answered 31/10, 2021 at 10:2 Comment(0)
D
0

NoneType has been restored, along with other types, on Sep 21, 2020 for general consistency and static checking reasons, effectively in Python 3.10.0.

Darlinedarling answered 15/7 at 18:35 Comment(0)
I
-1

In Python, NoneType errors are typically caught as AttributeError since NoneType represents the type of None and accessing an attribute or method on None will raise an AttributeError. You can catch this error using a try-except block.

try:
    # Code
except AttributeError:
    # Code
Irradiation answered 23/7 at 0:38 Comment(1)
How does this address the question?Mousse

© 2022 - 2024 — McMap. All rights reserved.