astral-sh / ruff

An extremely fast Python linter and code formatter, written in Rust.
https://docs.astral.sh/ruff
MIT License
32.82k stars 1.1k forks source link

Missing check and fix for pep 484 implicit optional #1983

Closed rytilahti closed 1 year ago

rytilahti commented 1 year ago

Recent mypy versions have started to warn about implicit optionals on function signatures, which has been prohibited by pep 484 since https://github.com/python/peps/pull/689. It would be great if ruff would spot and fix this automatically for you, considering how easy it is to forget to do this while coding.

Minimal code example:

def implicit_optional(optional: str = None) -> None:
    pass

mypy output:

test.py:1: error: Incompatible default for argument "optional" (default has type "None", argument has type "str")  [assignment]
test.py:1: note: PEP 484 prohibits implicit Optional. Accordingly, mypy has changed its default to no_implicit_optional=True
test.py:1: note: Use https://github.com/hauntsaninja/no_implicit_optional to automatically upgrade your codebase

The fix for python3.10 and newer would be modifying the definition to be:

def implicit_optional(optional: str | None = None) -> None:
    pass

On the implementation side, I think this would belong to flake8-annotations but as it isn't checking for this, I'm wondering what would be the correct place to implement this?

For older Python versions the fix would require either from __future__ import annotations or from typing import Optional and using optional: Optional[str], both of which might be too invasive for automated fixing.

charliermarsh commented 1 year ago

Yeah I'd love to do this. I want to add a couple autofixes for typing-related stuff and this is a good candidate.

dhruvmanila commented 1 year ago

I think this is a good rule to add along with the auto-fix ability. Should this be added under the RUF or ANN category? I'm leaning towards RUF. I can take this on.

dhruvmanila commented 1 year ago

I've started working on this