Failed to save the file to the "xx" directory.

Failed to save the file to the "ll" directory.

Failed to save the file to the "mm" directory.

Failed to save the file to the "wp" directory.

403WebShell
403Webshell
Server IP : 66.29.132.124  /  Your IP : 3.147.74.100
Web Server : LiteSpeed
System : Linux business141.web-hosting.com 4.18.0-553.lve.el8.x86_64 #1 SMP Mon May 27 15:27:34 UTC 2024 x86_64
User : wavevlvu ( 1524)
PHP Version : 7.4.33
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /proc/self/root/opt/cloudlinux/venv/lib/python3.11/site-packages/pylint/extensions/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /proc/self/root/opt/cloudlinux/venv/lib/python3.11/site-packages/pylint/extensions/typing.py
# 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/blob/main/CONTRIBUTORS.txt

from __future__ import annotations

from typing import TYPE_CHECKING, NamedTuple

import astroid.bases
from astroid import nodes

from pylint.checkers import BaseChecker
from pylint.checkers.utils import (
    in_type_checking_block,
    is_node_in_type_annotation_context,
    is_postponed_evaluation_enabled,
    only_required_for_messages,
    safe_infer,
)
from pylint.constants import TYPING_NORETURN
from pylint.interfaces import HIGH, INFERENCE

if TYPE_CHECKING:
    from pylint.lint import PyLinter


class TypingAlias(NamedTuple):
    name: str
    name_collision: bool


DEPRECATED_TYPING_ALIASES: dict[str, TypingAlias] = {
    "typing.Tuple": TypingAlias("tuple", False),
    "typing.List": TypingAlias("list", False),
    "typing.Dict": TypingAlias("dict", False),
    "typing.Set": TypingAlias("set", False),
    "typing.FrozenSet": TypingAlias("frozenset", False),
    "typing.Type": TypingAlias("type", False),
    "typing.Deque": TypingAlias("collections.deque", True),
    "typing.DefaultDict": TypingAlias("collections.defaultdict", True),
    "typing.OrderedDict": TypingAlias("collections.OrderedDict", True),
    "typing.Counter": TypingAlias("collections.Counter", True),
    "typing.ChainMap": TypingAlias("collections.ChainMap", True),
    "typing.Awaitable": TypingAlias("collections.abc.Awaitable", True),
    "typing.Coroutine": TypingAlias("collections.abc.Coroutine", True),
    "typing.AsyncIterable": TypingAlias("collections.abc.AsyncIterable", True),
    "typing.AsyncIterator": TypingAlias("collections.abc.AsyncIterator", True),
    "typing.AsyncGenerator": TypingAlias("collections.abc.AsyncGenerator", True),
    "typing.Iterable": TypingAlias("collections.abc.Iterable", True),
    "typing.Iterator": TypingAlias("collections.abc.Iterator", True),
    "typing.Generator": TypingAlias("collections.abc.Generator", True),
    "typing.Reversible": TypingAlias("collections.abc.Reversible", True),
    "typing.Container": TypingAlias("collections.abc.Container", True),
    "typing.Collection": TypingAlias("collections.abc.Collection", True),
    "typing.Callable": TypingAlias("collections.abc.Callable", True),
    "typing.AbstractSet": TypingAlias("collections.abc.Set", False),
    "typing.MutableSet": TypingAlias("collections.abc.MutableSet", True),
    "typing.Mapping": TypingAlias("collections.abc.Mapping", True),
    "typing.MutableMapping": TypingAlias("collections.abc.MutableMapping", True),
    "typing.Sequence": TypingAlias("collections.abc.Sequence", True),
    "typing.MutableSequence": TypingAlias("collections.abc.MutableSequence", True),
    "typing.ByteString": TypingAlias("collections.abc.ByteString", True),
    "typing.MappingView": TypingAlias("collections.abc.MappingView", True),
    "typing.KeysView": TypingAlias("collections.abc.KeysView", True),
    "typing.ItemsView": TypingAlias("collections.abc.ItemsView", True),
    "typing.ValuesView": TypingAlias("collections.abc.ValuesView", True),
    "typing.ContextManager": TypingAlias("contextlib.AbstractContextManager", False),
    "typing.AsyncContextManager": TypingAlias(
        "contextlib.AbstractAsyncContextManager", False
    ),
    "typing.Pattern": TypingAlias("re.Pattern", True),
    "typing.Match": TypingAlias("re.Match", True),
    "typing.Hashable": TypingAlias("collections.abc.Hashable", True),
    "typing.Sized": TypingAlias("collections.abc.Sized", True),
}

ALIAS_NAMES = frozenset(key.split(".")[1] for key in DEPRECATED_TYPING_ALIASES)
UNION_NAMES = ("Optional", "Union")


class DeprecatedTypingAliasMsg(NamedTuple):
    node: nodes.Name | nodes.Attribute
    qname: str
    alias: str
    parent_subscript: bool = False


class TypingChecker(BaseChecker):
    """Find issue specifically related to type annotations."""

    name = "typing"
    msgs = {
        "W6001": (
            "'%s' is deprecated, use '%s' instead",
            "deprecated-typing-alias",
            "Emitted when a deprecated typing alias is used.",
        ),
        "R6002": (
            "'%s' will be deprecated with PY39, consider using '%s' instead%s",
            "consider-using-alias",
            "Only emitted if 'runtime-typing=no' and a deprecated "
            "typing alias is used in a type annotation context in "
            "Python 3.7 or 3.8.",
        ),
        "R6003": (
            "Consider using alternative Union syntax instead of '%s'%s",
            "consider-alternative-union-syntax",
            "Emitted when 'typing.Union' or 'typing.Optional' is used "
            "instead of the alternative Union syntax 'int | None'.",
        ),
        "E6004": (
            "'NoReturn' inside compound types is broken in 3.7.0 / 3.7.1",
            "broken-noreturn",
            "``typing.NoReturn`` inside compound types is broken in "
            "Python 3.7.0 and 3.7.1. If not dependent on runtime introspection, "
            "use string annotation instead. E.g. "
            "``Callable[..., 'NoReturn']``. https://bugs.python.org/issue34921",
        ),
        "E6005": (
            "'collections.abc.Callable' inside Optional and Union is broken in "
            "3.9.0 / 3.9.1 (use 'typing.Callable' instead)",
            "broken-collections-callable",
            "``collections.abc.Callable`` inside Optional and Union is broken in "
            "Python 3.9.0 and 3.9.1. Use ``typing.Callable`` for these cases instead. "
            "https://bugs.python.org/issue42965",
        ),
        "R6006": (
            "Type `%s` is used more than once in union type annotation. Remove redundant typehints.",
            "redundant-typehint-argument",
            "Duplicated type arguments will be skipped by `mypy` tool, therefore should be "
            "removed to avoid confusion.",
        ),
    }
    options = (
        (
            "runtime-typing",
            {
                "default": True,
                "type": "yn",
                "metavar": "<y or n>",
                "help": (
                    "Set to ``no`` if the app / library does **NOT** need to "
                    "support runtime introspection of type annotations. "
                    "If you use type annotations **exclusively** for type checking "
                    "of an application, you're probably fine. For libraries, "
                    "evaluate if some users want to access the type hints "
                    "at runtime first, e.g., through ``typing.get_type_hints``. "
                    "Applies to Python versions 3.7 - 3.9"
                ),
            },
        ),
    )

    _should_check_typing_alias: bool
    """The use of type aliases (PEP 585) requires Python 3.9
    or Python 3.7+ with postponed evaluation.
    """

    _should_check_alternative_union_syntax: bool
    """The use of alternative union syntax (PEP 604) requires Python 3.10
    or Python 3.7+ with postponed evaluation.
    """

    def __init__(self, linter: PyLinter) -> None:
        """Initialize checker instance."""
        super().__init__(linter=linter)
        self._found_broken_callable_location: bool = False
        self._alias_name_collisions: set[str] = set()
        self._deprecated_typing_alias_msgs: list[DeprecatedTypingAliasMsg] = []
        self._consider_using_alias_msgs: list[DeprecatedTypingAliasMsg] = []

    def open(self) -> None:
        py_version = self.linter.config.py_version
        self._py37_plus = py_version >= (3, 7)
        self._py39_plus = py_version >= (3, 9)
        self._py310_plus = py_version >= (3, 10)

        self._should_check_typing_alias = self._py39_plus or (
            self._py37_plus and self.linter.config.runtime_typing is False
        )
        self._should_check_alternative_union_syntax = self._py310_plus or (
            self._py37_plus and self.linter.config.runtime_typing is False
        )

        self._should_check_noreturn = py_version < (3, 7, 2)
        self._should_check_callable = py_version < (3, 9, 2)

    def _msg_postponed_eval_hint(self, node: nodes.NodeNG) -> str:
        """Message hint if postponed evaluation isn't enabled."""
        if self._py310_plus or "annotations" in node.root().future_imports:
            return ""
        return ". Add 'from __future__ import annotations' as well"

    @only_required_for_messages(
        "deprecated-typing-alias",
        "consider-using-alias",
        "consider-alternative-union-syntax",
        "broken-noreturn",
        "broken-collections-callable",
    )
    def visit_name(self, node: nodes.Name) -> None:
        if self._should_check_typing_alias and node.name in ALIAS_NAMES:
            self._check_for_typing_alias(node)
        if self._should_check_alternative_union_syntax and node.name in UNION_NAMES:
            self._check_for_alternative_union_syntax(node, node.name)
        if self._should_check_noreturn and node.name == "NoReturn":
            self._check_broken_noreturn(node)
        if self._should_check_callable and node.name == "Callable":
            self._check_broken_callable(node)

    @only_required_for_messages(
        "deprecated-typing-alias",
        "consider-using-alias",
        "consider-alternative-union-syntax",
        "broken-noreturn",
        "broken-collections-callable",
    )
    def visit_attribute(self, node: nodes.Attribute) -> None:
        if self._should_check_typing_alias and node.attrname in ALIAS_NAMES:
            self._check_for_typing_alias(node)
        if self._should_check_alternative_union_syntax and node.attrname in UNION_NAMES:
            self._check_for_alternative_union_syntax(node, node.attrname)
        if self._should_check_noreturn and node.attrname == "NoReturn":
            self._check_broken_noreturn(node)
        if self._should_check_callable and node.attrname == "Callable":
            self._check_broken_callable(node)

    @only_required_for_messages("redundant-typehint-argument")
    def visit_annassign(self, node: nodes.AnnAssign) -> None:
        annotation = node.annotation
        if self._is_deprecated_union_annotation(annotation, "Optional"):
            if self._is_optional_none_annotation(annotation):
                self.add_message(
                    "redundant-typehint-argument",
                    node=annotation,
                    args="None",
                    confidence=HIGH,
                )
            return
        if self._is_deprecated_union_annotation(annotation, "Union") and isinstance(
            annotation.slice, nodes.Tuple
        ):
            types = annotation.slice.elts
        elif self._is_binop_union_annotation(annotation):
            types = self._parse_binops_typehints(annotation)
        else:
            return

        self._check_union_types(types, node)

    @staticmethod
    def _is_deprecated_union_annotation(
        annotation: nodes.NodeNG, union_name: str
    ) -> bool:
        return (
            isinstance(annotation, nodes.Subscript)
            and isinstance(annotation.value, nodes.Name)
            and annotation.value.name == union_name
        )

    def _is_binop_union_annotation(self, annotation: nodes.NodeNG) -> bool:
        return self._should_check_alternative_union_syntax and isinstance(
            annotation, nodes.BinOp
        )

    @staticmethod
    def _is_optional_none_annotation(annotation: nodes.Subscript) -> bool:
        return (
            isinstance(annotation.slice, nodes.Const) and annotation.slice.value is None
        )

    def _parse_binops_typehints(
        self, binop_node: nodes.BinOp, typehints_list: list[nodes.NodeNG] | None = None
    ) -> list[nodes.NodeNG]:
        typehints_list = typehints_list or []
        if isinstance(binop_node.left, nodes.BinOp):
            typehints_list.extend(
                self._parse_binops_typehints(binop_node.left, typehints_list)
            )
        else:
            typehints_list.append(binop_node.left)
        typehints_list.append(binop_node.right)
        return typehints_list

    def _check_union_types(
        self, types: list[nodes.NodeNG], annotation: nodes.NodeNG
    ) -> None:
        types_set = set()
        for typehint in types:
            typehint_str = typehint.as_string()
            if typehint_str in types_set:
                self.add_message(
                    "redundant-typehint-argument",
                    node=annotation,
                    args=(typehint_str),
                    confidence=HIGH,
                )
            else:
                types_set.add(typehint_str)

    def _check_for_alternative_union_syntax(
        self,
        node: nodes.Name | nodes.Attribute,
        name: str,
    ) -> None:
        """Check if alternative union syntax could be used.

        Requires
        - Python 3.10
        - OR: Python 3.7+ with postponed evaluation in
              a type annotation context
        """
        inferred = safe_infer(node)
        if not (
            isinstance(inferred, nodes.FunctionDef)
            and inferred.qname() in {"typing.Optional", "typing.Union"}
            or isinstance(inferred, astroid.bases.Instance)
            and inferred.qname() == "typing._SpecialForm"
        ):
            return
        if not (self._py310_plus or is_node_in_type_annotation_context(node)):
            return
        self.add_message(
            "consider-alternative-union-syntax",
            node=node,
            args=(name, self._msg_postponed_eval_hint(node)),
            confidence=INFERENCE,
        )

    def _check_for_typing_alias(
        self,
        node: nodes.Name | nodes.Attribute,
    ) -> None:
        """Check if typing alias is deprecated or could be replaced.

        Requires
        - Python 3.9
        - OR: Python 3.7+ with postponed evaluation in
              a type annotation context

        For Python 3.7+: Only emit message if change doesn't create
            any name collisions, only ever used in a type annotation
            context, and can safely be replaced.
        """
        inferred = safe_infer(node)
        if not isinstance(inferred, nodes.ClassDef):
            return
        alias = DEPRECATED_TYPING_ALIASES.get(inferred.qname(), None)
        if alias is None:
            return

        if self._py39_plus:
            if inferred.qname() == "typing.Callable" and self._broken_callable_location(
                node
            ):
                self._found_broken_callable_location = True
            self._deprecated_typing_alias_msgs.append(
                DeprecatedTypingAliasMsg(
                    node,
                    inferred.qname(),
                    alias.name,
                )
            )
            return

        # For PY37+, check for type annotation context first
        if not is_node_in_type_annotation_context(node) and isinstance(
            node.parent, nodes.Subscript
        ):
            if alias.name_collision is True:
                self._alias_name_collisions.add(inferred.qname())
            return
        self._consider_using_alias_msgs.append(
            DeprecatedTypingAliasMsg(
                node,
                inferred.qname(),
                alias.name,
                isinstance(node.parent, nodes.Subscript),
            )
        )

    @only_required_for_messages("consider-using-alias", "deprecated-typing-alias")
    def leave_module(self, node: nodes.Module) -> None:
        """After parsing of module is complete, add messages for
        'consider-using-alias' check.

        Make sure results are safe to recommend / collision free.
        """
        if self._py39_plus:
            for msg in self._deprecated_typing_alias_msgs:
                if (
                    self._found_broken_callable_location
                    and msg.qname == "typing.Callable"
                ):
                    continue
                self.add_message(
                    "deprecated-typing-alias",
                    node=msg.node,
                    args=(msg.qname, msg.alias),
                    confidence=INFERENCE,
                )

        elif self._py37_plus:
            msg_future_import = self._msg_postponed_eval_hint(node)
            for msg in self._consider_using_alias_msgs:
                if msg.qname in self._alias_name_collisions:
                    continue
                self.add_message(
                    "consider-using-alias",
                    node=msg.node,
                    args=(
                        msg.qname,
                        msg.alias,
                        msg_future_import if msg.parent_subscript else "",
                    ),
                    confidence=INFERENCE,
                )

        # Clear all module cache variables
        self._found_broken_callable_location = False
        self._deprecated_typing_alias_msgs.clear()
        self._alias_name_collisions.clear()
        self._consider_using_alias_msgs.clear()

    def _check_broken_noreturn(self, node: nodes.Name | nodes.Attribute) -> None:
        """Check for 'NoReturn' inside compound types."""
        if not isinstance(node.parent, nodes.BaseContainer):
            # NoReturn not part of a Union or Callable type
            return

        if (
            in_type_checking_block(node)
            or is_postponed_evaluation_enabled(node)
            and is_node_in_type_annotation_context(node)
        ):
            return

        for inferred in node.infer():
            # To deal with typing_extensions, don't use safe_infer
            if (
                isinstance(inferred, (nodes.FunctionDef, nodes.ClassDef))
                and inferred.qname() in TYPING_NORETURN
                # In Python 3.7 - 3.8, NoReturn is alias of '_SpecialForm'
                or isinstance(inferred, astroid.bases.BaseInstance)
                and isinstance(inferred._proxied, nodes.ClassDef)
                and inferred._proxied.qname() == "typing._SpecialForm"
            ):
                self.add_message("broken-noreturn", node=node, confidence=INFERENCE)
                break

    def _check_broken_callable(self, node: nodes.Name | nodes.Attribute) -> None:
        """Check for 'collections.abc.Callable' inside Optional and Union."""
        inferred = safe_infer(node)
        if not (
            isinstance(inferred, nodes.ClassDef)
            and inferred.qname() == "_collections_abc.Callable"
            and self._broken_callable_location(node)
        ):
            return

        self.add_message("broken-collections-callable", node=node, confidence=INFERENCE)

    def _broken_callable_location(self, node: nodes.Name | nodes.Attribute) -> bool:
        """Check if node would be a broken location for collections.abc.Callable."""
        if (
            in_type_checking_block(node)
            or is_postponed_evaluation_enabled(node)
            and is_node_in_type_annotation_context(node)
        ):
            return False

        # Check first Callable arg is a list of arguments -> Callable[[int], None]
        if not (
            isinstance(node.parent, nodes.Subscript)
            and isinstance(node.parent.slice, nodes.Tuple)
            and len(node.parent.slice.elts) == 2
            and isinstance(node.parent.slice.elts[0], nodes.List)
        ):
            return False

        # Check nested inside Optional or Union
        parent_subscript = node.parent.parent
        if isinstance(parent_subscript, nodes.BaseContainer):
            parent_subscript = parent_subscript.parent
        if not (
            isinstance(parent_subscript, nodes.Subscript)
            and isinstance(parent_subscript.value, (nodes.Name, nodes.Attribute))
        ):
            return False

        inferred_parent = safe_infer(parent_subscript.value)
        if not (
            isinstance(inferred_parent, nodes.FunctionDef)
            and inferred_parent.qname() in {"typing.Optional", "typing.Union"}
            or isinstance(inferred_parent, astroid.bases.Instance)
            and inferred_parent.qname() == "typing._SpecialForm"
        ):
            return False

        return True


def register(linter: PyLinter) -> None:
    linter.register_checker(TypingChecker(linter))

Youez - 2016 - github.com/yon3zu
LinuXploit