From d6f3ae8d72e65e89560403ca2241ec604b418bdf Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 12 Mar 2023 13:40:16 +0100 Subject: Deprecate redundant type checking guard utils (#8433) (#8439) (cherry picked from commit b968fa062f801626426ef399401c4530e13fcc49) Co-authored-by: Jacob Walls --- doc/whatsnew/fragments/8433.internal | 10 ++++++++++ pylint/checkers/imports.py | 29 +++++++++++++++-------------- pylint/checkers/utils.py | 15 +++++++++++++++ pylint/checkers/variables.py | 16 ++++++++++------ pylint/extensions/private_import.py | 4 ++-- tests/checkers/unittest_utils.py | 1 + 6 files changed, 53 insertions(+), 22 deletions(-) create mode 100644 doc/whatsnew/fragments/8433.internal diff --git a/doc/whatsnew/fragments/8433.internal b/doc/whatsnew/fragments/8433.internal new file mode 100644 index 000000000..4bc20c493 --- /dev/null +++ b/doc/whatsnew/fragments/8433.internal @@ -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 diff --git a/pylint/checkers/imports.py b/pylint/checkers/imports.py index ba526821a..dee12e591 100644 --- a/pylint/checkers/imports.py +++ b/pylint/checkers/imports.py @@ -21,9 +21,9 @@ from astroid.nodes._base_nodes import ImportNode 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 @@ -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) @@ -578,7 +580,11 @@ class ImportsChecker(DeprecatedMixin, BaseChecker): 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 @@ -884,10 +890,6 @@ class ImportsChecker(DeprecatedMixin, BaseChecker): 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) @@ -906,10 +908,9 @@ class ImportsChecker(DeprecatedMixin, BaseChecker): # 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: diff --git a/pylint/checkers/utils.py b/pylint/checkers/utils.py index c68f88388..771b21fff 100644 --- a/pylint/checkers/utils.py +++ b/pylint/checkers/utils.py @@ -1850,6 +1850,11 @@ 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") @@ -1857,6 +1862,11 @@ def is_typing_guard(node: nodes.If) -> bool: 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) @@ -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) ) diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py index 734231103..f55b71264 100644 --- a/pylint/checkers/variables.py +++ b/pylint/checkers/variables.py @@ -27,6 +27,7 @@ from pylint.checkers import BaseChecker, utils 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 @@ -1891,9 +1892,10 @@ class VariablesChecker(BaseChecker): # 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: @@ -1913,9 +1915,11 @@ class VariablesChecker(BaseChecker): # 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(".") diff --git a/pylint/extensions/private_import.py b/pylint/extensions/private_import.py index 01d800c94..df08c7116 100644 --- a/pylint/extensions/private_import.py +++ b/pylint/extensions/private_import.py @@ -39,7 +39,7 @@ class PrivateImportChecker(BaseChecker): @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) @@ -56,7 +56,7 @@ class PrivateImportChecker(BaseChecker): @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): diff --git a/tests/checkers/unittest_utils.py b/tests/checkers/unittest_utils.py index a0dfe299b..ac328d7cd 100644 --- a/tests/checkers/unittest_utils.py +++ b/tests/checkers/unittest_utils.py @@ -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( """ -- cgit v1.2.1