summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Byrne <31762852+mbyrnepr2@users.noreply.github.com>2022-01-10 23:05:48 +0100
committerGitHub <noreply@github.com>2022-01-10 23:05:48 +0100
commit3ad42a05634d6913f57c7d65741bdbdb7b1ffc48 (patch)
treef298c8ef30938e1ba802a0ba2a3e6eb8988b46d6
parentd2475b42e3f4b17ca39eedd1ac65a929f70ca02e (diff)
downloadpylint-git-3ad42a05634d6913f57c7d65741bdbdb7b1ffc48.tar.gz
Fixed false positive for ``global-variable-not-assigned`` when the `del` statement is used (#5656)
Closes #5333
-rw-r--r--ChangeLog4
-rw-r--r--doc/whatsnew/2.13.rst4
-rw-r--r--pylint/checkers/utils.py9
-rw-r--r--pylint/checkers/variables.py1
-rw-r--r--tests/functional/g/globals.py7
-rw-r--r--tests/functional/g/globals.txt9
6 files changed, 30 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 424d8b064..44f4bfa36 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -62,6 +62,10 @@ Release date: TBA
Closes #5499
+* Fixed false positive for ``global-variable-not-assigned`` when the ``del`` statement is used
+
+ Closes #5333
+
* By default, pylint does no longer take files starting with ``.#`` into account. Those are
considered `emacs file locks`. See
https://www.gnu.org/software/emacs/manual/html_node/elisp/File-Locks.html.
diff --git a/doc/whatsnew/2.13.rst b/doc/whatsnew/2.13.rst
index 854fef618..ab88087b3 100644
--- a/doc/whatsnew/2.13.rst
+++ b/doc/whatsnew/2.13.rst
@@ -195,3 +195,7 @@ Other Changes
raise ValueError
Closes #4955
+
+* Fixed false positive for ``global-variable-not-assigned`` when the ``del`` statement is used
+
+ Closes #5333
diff --git a/pylint/checkers/utils.py b/pylint/checkers/utils.py
index f42123048..b0b15e361 100644
--- a/pylint/checkers/utils.py
+++ b/pylint/checkers/utils.py
@@ -1672,6 +1672,15 @@ def is_reassigned_after_current(node: nodes.NodeNG, varname: str) -> bool:
)
+def is_deleted_after_current(node: nodes.NodeNG, varname: str) -> bool:
+ """Check if the given variable name is deleted in the same scope after the current node"""
+ return any(
+ getattr(target, "name", None) == varname and target.lineno > node.lineno
+ for del_node in node.scope().nodes_of_class(nodes.Delete)
+ for target in del_node.targets
+ )
+
+
def is_function_body_ellipsis(node: nodes.FunctionDef) -> bool:
"""Checks whether a function body only consists of a single Ellipsis"""
return (
diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py
index f01866276..5ce58df14 100644
--- a/pylint/checkers/variables.py
+++ b/pylint/checkers/variables.py
@@ -1128,6 +1128,7 @@ class VariablesChecker(BaseChecker):
)
if (
not utils.is_reassigned_after_current(node, name)
+ and not utils.is_deleted_after_current(node, name)
and not_defined_locally_by_import
):
self.add_message("global-variable-not-assigned", args=name, node=node)
diff --git a/tests/functional/g/globals.py b/tests/functional/g/globals.py
index a5e4b4bff..56c852d8a 100644
--- a/tests/functional/g/globals.py
+++ b/tests/functional/g/globals.py
@@ -40,6 +40,13 @@ def global_no_assign():
print(CONSTANT)
+def global_del():
+ """Deleting the global name prevents `global-variable-not-assigned`"""
+ global CONSTANT # [global-statement]
+ print(CONSTANT)
+ del CONSTANT
+
+
def global_operator_assign():
"""Operator assigns should only throw a global statement error"""
global CONSTANT # [global-statement]
diff --git a/tests/functional/g/globals.txt b/tests/functional/g/globals.txt
index 0559eea21..4e3f6dca4 100644
--- a/tests/functional/g/globals.txt
+++ b/tests/functional/g/globals.txt
@@ -6,7 +6,8 @@ undefined-variable:22:10:22:13:other:Undefined variable 'HOP':UNDEFINED
global-variable-undefined:27:4:27:18:define_constant:Global variable 'SOMEVAR' undefined at the module level:UNDEFINED
global-statement:33:4:33:14:global_with_import:Using the global statement:UNDEFINED
global-variable-not-assigned:39:4:39:19:global_no_assign:Using global for 'CONSTANT' but no assignment is done:UNDEFINED
-global-statement:45:4:45:19:global_operator_assign:Using the global statement:UNDEFINED
-global-statement:52:4:52:19:global_function_assign:Using the global statement:UNDEFINED
-global-statement:62:4:62:15:override_func:Using the global statement:UNDEFINED
-global-statement:71:4:71:14:func:Using the global statement:UNDEFINED
+global-statement:45:4:45:19:global_del:Using the global statement:UNDEFINED
+global-statement:52:4:52:19:global_operator_assign:Using the global statement:UNDEFINED
+global-statement:59:4:59:19:global_function_assign:Using the global statement:UNDEFINED
+global-statement:69:4:69:15:override_func:Using the global statement:UNDEFINED
+global-statement:78:4:78:14:func:Using the global statement:UNDEFINED