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

Deprecate redundant type checking guard utils #8433

Merged
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions doc/whatsnew/fragments/8433.user_action
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
The following utilities are deprecated in favor of the more robust ``in_type_checking_block``
and will be removed in pylint 3.0:

- ``is_node_in_guarded_import_block``
- ``is_node_in_typing_guarded_import_block``
- ``is_typing_guard``

``is_sys_guard`` is still available, which was part of ``is_node_in_guarded_import_block``.

Refs #8433
29 changes: 15 additions & 14 deletions pylint/checkers/imports.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
from pylint.checkers import BaseChecker, DeprecatedMixin
from pylint.checkers.utils import (
get_import_name,
in_type_checking_block,
is_from_fallback_block,
is_node_in_guarded_import_block,
is_typing_guard,
is_sys_guard,
node_ignores_exception,
)
from pylint.exceptions import EmptyReportError
Expand Down Expand Up @@ -154,9 +154,11 @@ def _ignore_import_failure(
if submodule in ignored_modules:
return True

if is_node_in_guarded_import_block(node):
# Ignore import failure if part of guarded import block
# I.e. `sys.version_info` or `typing.TYPE_CHECKING`
# Ignore import failure if part of guarded import block
# I.e. `sys.version_info` or `typing.TYPE_CHECKING`
if in_type_checking_block(node):
return True
if isinstance(node.parent, nodes.If) and is_sys_guard(node.parent):
return True

return node_ignores_exception(node, ImportError)
Expand Down Expand Up @@ -578,7 +580,11 @@ def leave_module(self, node: nodes.Module) -> None:
current_package
and current_package != package
and package in met
and is_node_in_guarded_import_block(import_node) is False
and not in_type_checking_block(import_node)
and not (
isinstance(import_node.parent, nodes.If)
and is_sys_guard(import_node.parent)
)
):
self.add_message("ungrouped-imports", node=import_node, args=package)
current_package = package
Expand Down Expand Up @@ -884,10 +890,6 @@ def _add_imported_module(self, node: ImportNode, importedmodname: str) -> None:
except ImportError:
pass

in_type_checking_block = isinstance(node.parent, nodes.If) and is_typing_guard(
node.parent
)

if context_name == importedmodname:
self.add_message("import-self", node=node)

Expand All @@ -906,10 +908,9 @@ def _add_imported_module(self, node: ImportNode, importedmodname: str) -> None:

# update import graph
self.import_graph[context_name].add(importedmodname)
if (
not self.linter.is_message_enabled("cyclic-import", line=node.lineno)
or in_type_checking_block
):
if not self.linter.is_message_enabled(
"cyclic-import", line=node.lineno
) or in_type_checking_block(node):
self._excluded_edges[context_name].add(importedmodname)

def _check_preferred_module(self, node: ImportNode, mod_path: str) -> None:
Expand Down
16 changes: 16 additions & 0 deletions pylint/checkers/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import numbers
import re
import string
import warnings
from collections import deque
from collections.abc import Iterable, Iterator
from functools import lru_cache, partial
Expand Down Expand Up @@ -1798,13 +1799,23 @@ def is_typing_guard(node: nodes.If) -> bool:
>>> if TYPE_CHECKING:
>>> from xyz import a
"""
warnings.warn(
"This method will be removed in pylint 3.0; use in_type_checking_block() instead.",
DeprecationWarning,
stacklevel=2,
)
return isinstance(
node.test, (nodes.Name, nodes.Attribute)
) and node.test.as_string().endswith("TYPE_CHECKING")


def is_node_in_typing_guarded_import_block(node: nodes.NodeNG) -> bool:
"""Return True if node is part for guarded `typing.TYPE_CHECKING` if block."""
warnings.warn(
"This method will be removed in pylint 3.0; use in_type_checking_block() instead.",
DeprecationWarning,
stacklevel=2,
)
return isinstance(node.parent, nodes.If) and is_typing_guard(node.parent)


Expand All @@ -1813,6 +1824,11 @@ def is_node_in_guarded_import_block(node: nodes.NodeNG) -> bool:

I.e. `sys.version_info` or `typing.TYPE_CHECKING`
"""
warnings.warn(
"This method will be removed in pylint 3.0; use in_type_checking_block() instead.",
DeprecationWarning,
stacklevel=2,
)
return isinstance(node.parent, nodes.If) and (
is_sys_guard(node.parent) or is_typing_guard(node.parent)
)
Expand Down
16 changes: 10 additions & 6 deletions pylint/checkers/variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from pylint.checkers.utils import (
in_type_checking_block,
is_postponed_evaluation_enabled,
is_sys_guard,
)
from pylint.constants import PY39_PLUS, TYPING_NEVER, TYPING_NORETURN
from pylint.interfaces import CONTROL_FLOW, HIGH, INFERENCE, INFERENCE_FAILURE
Expand Down Expand Up @@ -1891,9 +1892,10 @@ def visit_import(self, node: nodes.Import) -> None:
# No need to verify this, since ImportError is already
# handled by the client code.
return
if utils.is_node_in_guarded_import_block(node) is True:
# Don't verify import if part of guarded import block
# I.e. `sys.version_info` or `typing.TYPE_CHECKING`
# Don't verify import if part of guarded import block
if in_type_checking_block(node):
return
if isinstance(node.parent, nodes.If) and is_sys_guard(node.parent):
return

for name, _ in node.names:
Expand All @@ -1913,9 +1915,11 @@ def visit_importfrom(self, node: nodes.ImportFrom) -> None:
# No need to verify this, since ImportError is already
# handled by the client code.
return
if utils.is_node_in_guarded_import_block(node) is True:
# Don't verify import if part of guarded import block
# I.e. `sys.version_info` or `typing.TYPE_CHECKING`
# Don't verify import if part of guarded import block
# I.e. `sys.version_info` or `typing.TYPE_CHECKING`
if in_type_checking_block(node):
return
if isinstance(node.parent, nodes.If) and is_sys_guard(node.parent):
return

name_parts = node.modname.split(".")
Expand Down
4 changes: 2 additions & 2 deletions pylint/extensions/private_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def __init__(self, linter: PyLinter) -> None:

@utils.only_required_for_messages("import-private-name")
def visit_import(self, node: nodes.Import) -> None:
if utils.is_node_in_typing_guarded_import_block(node):
if utils.in_type_checking_block(node):
return
names = [name[0] for name in node.names]
private_names = self._get_private_imports(names)
Expand All @@ -56,7 +56,7 @@ def visit_import(self, node: nodes.Import) -> None:

@utils.only_required_for_messages("import-private-name")
def visit_importfrom(self, node: nodes.ImportFrom) -> None:
if utils.is_node_in_typing_guarded_import_block(node):
if utils.in_type_checking_block(node):
return
# Only check imported names if the module is external
if self.same_root_dir(node, node.modname):
Expand Down
1 change: 1 addition & 0 deletions tests/checkers/unittest_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,7 @@ def test_if_sys_guard() -> None:
assert utils.is_sys_guard(code[2]) is False


@pytest.mark.filterwarnings("ignore::DeprecationWarning")
def test_if_typing_guard() -> None:
code = astroid.extract_node(
"""
Expand Down