Skip to content

Commit

Permalink
Deprecate redundant type checking guard utils (#8433) (#8439)
Browse files Browse the repository at this point in the history
(cherry picked from commit b968fa0)

Co-authored-by: Jacob Walls <jacobtylerwalls@gmail.com>
  • Loading branch information
github-actions[bot] and jacobtylerwalls committed Mar 12, 2023
1 parent 16dd28d commit d6f3ae8
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 22 deletions.
10 changes: 10 additions & 0 deletions doc/whatsnew/fragments/8433.internal
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
15 changes: 15 additions & 0 deletions pylint/checkers/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1850,13 +1850,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,
) # pragma: no cover
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,
) # pragma: no cover
return isinstance(node.parent, nodes.If) and is_typing_guard(node.parent)


Expand All @@ -1865,6 +1875,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,
) # pragma: no cover
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 @@ -414,6 +414,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

0 comments on commit d6f3ae8

Please sign in to comment.