third_party.pylibs.pylint.src/pylint/checkers/unsupported_version.py
Pierre Sassoulas 9e0baf370a Simplify hard to maintain copyright notice
git is the source of truth for the copyright, copyrite (the tool)
was taking exponentially longer with each release, and it's
polluting the code with sometime as much as 50 lines of names.
2022-03-24 13:06:15 +01:00

87 lines
3.0 KiB
Python

# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
# For details: https://github.com/PyCQA/pylint/blob/main/LICENSE
# Copyright (c) https://github.com/PyCQA/pylint/graphs/contributors
"""Checker for features used that are not supported by all python versions
indicated by the py-version setting.
"""
from typing import TYPE_CHECKING
from astroid import nodes
from pylint.checkers import BaseChecker
from pylint.checkers.utils import (
check_messages,
safe_infer,
uninferable_final_decorators,
)
from pylint.interfaces import IAstroidChecker
from pylint.utils import get_global_option
if TYPE_CHECKING:
from pylint.lint import PyLinter
class UnsupportedVersionChecker(BaseChecker):
"""Checker for features that are not supported by all python versions
indicated by the py-version setting.
"""
__implements__ = (IAstroidChecker,)
name = "unsupported_version"
msgs = {
"W2601": (
"F-strings are not supported by all versions included in the py-version setting",
"using-f-string-in-unsupported-version",
"Used when the py-version set by the user is lower than 3.6 and pylint encounters "
"a f-string.",
),
"W2602": (
"typing.final is not supported by all versions included in the py-version setting",
"using-final-decorator-in-unsupported-version",
"Used when the py-version set by the user is lower than 3.8 and pylint encounters "
"a ``typing.final`` decorator.",
),
}
def open(self) -> None:
"""Initialize visit variables and statistics."""
py_version = get_global_option(self, "py-version")
self._py36_plus = py_version >= (3, 6)
self._py38_plus = py_version >= (3, 8)
@check_messages("using-f-string-in-unsupported-version")
def visit_joinedstr(self, node: nodes.JoinedStr) -> None:
"""Check f-strings."""
if not self._py36_plus:
self.add_message("using-f-string-in-unsupported-version", node=node)
@check_messages("using-final-decorator-in-unsupported-version")
def visit_decorators(self, node: nodes.Decorators) -> None:
"""Check decorators."""
self._check_typing_final(node)
def _check_typing_final(self, node: nodes.Decorators) -> None:
"""Add a message when the `typing.final` decorator is used and the
py-version is lower than 3.8
"""
if self._py38_plus:
return
decorators = []
for decorator in node.get_children():
inferred = safe_infer(decorator)
if inferred and inferred.qname() == "typing.final":
decorators.append(decorator)
for decorator in decorators or uninferable_final_decorators(node):
self.add_message(
"using-final-decorator-in-unsupported-version", node=decorator
)
def register(linter: "PyLinter") -> None:
linter.register_checker(UnsupportedVersionChecker(linter))