Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(🎁) Warn when NoneType is used in a type #11288

Closed
KotlinIsland opened this issue Oct 7, 2021 · 2 comments · Fixed by #13153
Closed

(🎁) Warn when NoneType is used in a type #11288

KotlinIsland opened this issue Oct 7, 2021 · 2 comments · Fixed by #13153

Comments

@KotlinIsland
Copy link
Contributor

KotlinIsland commented Oct 7, 2021

NoneType is a mangled up mess in the type realm and should never be used in a typing context.

With the special case of None being a secret alias to NoneType I think that many, many people are going to try to use NoneType as an annotation. Adding a warning for the 99% of the time that it's invalidly used would be a great one.

I understand that there are always edge cases, and disabling those warnings with a type comment would be the way to go IMO.

from types import NoneType

def foo(a: NoneType):  # sus alert, NoneType is a mess in the type realm, you should use `None` or `type[None]` instead.
    print(isinstance(a, NoneType))
@JukkaL
Copy link
Collaborator

JukkaL commented Jul 16, 2022

Some more context from the duplicate issue #13139 below.

Hints:

  • Fix this in mypy.typeanal
  • Currently types.NoneType is treated as an mypy.types.Instance type but None is mapped to mypy.types.NoneType
  • If we'd create an Instance with fullname equal to types.NoneType, generate an error

Example illustrating the problem:

from types import NoneType

def f(x: NoneType) -> None:
    pass

f(None)   # Incompatible type None, expected NoneType

@KotlinIsland KotlinIsland changed the title Warn when NoneType is used in a type (🎁) Warn when NoneType is used in a type Jul 16, 2022
@KotlinIsland
Copy link
Contributor Author

@JukkaL I have partially improved this case in basedmypy.

basedmypy:

from types import NoneType

def foo(n: NoneType):  # error: Variable "types.NoneType" is not valid as a type
    print("hi")

nt: type[None] = NoneType  # no error

just by simply making NoneType an alias instead of a class def. It's not perfect, but I think it's a big improvement.

KotlinIsland@f424a34

ilevkivskyi pushed a commit that referenced this issue Jul 17, 2022
### Description

Fixes #11288

Warns people to not use `NoneType` as a type annotation, as requested in #11288.

### Example

**Before**

```python
from types import NoneType

def f(x: NoneType) -> None:
    pass

f(None) # E: Argument 1 to "f" has incompatible type "None"; expected "NoneType"
```

**After**

```python
from types import NoneType

def f(x: NoneType) -> None: # E: NoneType should not be used as a type, please use None instead 
    pass

f(None)
```

Had to edit `test-data/unit/lib-stub/types.pyi` to allow NoneType type annotation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants