Skip to content

Fixed false positive for global-variable-undefined #5690

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

Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 3 additions & 1 deletion ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ Release date: TBA
* Fixed false positive ``consider-using-dict-comprehension`` when creating a dict
using a list of tuples where key AND value vary depending on the same condition.

Closes #5588
* Fixed false positive for ``global-variable-undefined`` when ``global`` is used with a class name

Closes #3088

* Added ``lru-cache-decorating-method`` checker with checks for the use of ``functools.lru_cache``
on class methods. This is unrecommended as it creates memory leaks by never letting the instance
Expand Down
4 changes: 4 additions & 0 deletions doc/whatsnew/2.13.rst
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ Other Changes
* When run in parallel mode ``pylint`` now pickles the data passed to subprocesses with
the ``dill`` package. The ``dill`` package has therefore been added as a dependency.

* Fixed false positive for ``global-variable-undefined`` when ``global`` is used with a class name

Closes #3088

* Fixed crash on properties and inherited class methods when comparing them for
equality against an empty dict.

Expand Down
4 changes: 3 additions & 1 deletion pylint/checkers/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1668,7 +1668,9 @@ def is_reassigned_after_current(node: nodes.NodeNG, varname: str) -> bool:
"""Check if the given variable name is reassigned in the same scope after the current node"""
return any(
a.name == varname and a.lineno > node.lineno
for a in node.scope().nodes_of_class((nodes.AssignName, nodes.FunctionDef))
for a in node.scope().nodes_of_class(
(nodes.AssignName, nodes.ClassDef, nodes.FunctionDef)
)
)


Expand Down
5 changes: 4 additions & 1 deletion pylint/checkers/variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -1205,7 +1205,10 @@ def visit_global(self, node: nodes.Global) -> None:
if anode.frame(future=True) is module:
# module level assignment
break
if isinstance(anode, nodes.FunctionDef) and anode.parent is module:
if (
isinstance(anode, (nodes.ClassDef, nodes.FunctionDef))
and anode.parent is module
):
# module level function assignment
break
else:
Expand Down
14 changes: 13 additions & 1 deletion tests/functional/g/globals.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""Warnings about global statements and usage of global variables."""
# pylint: disable=invalid-name, redefined-outer-name, missing-function-docstring, import-outside-toplevel
# pylint: disable=invalid-name, redefined-outer-name, missing-function-docstring, missing-class-docstring, import-outside-toplevel, too-few-public-methods
from __future__ import print_function

global CSTE # [global-at-module-level]
Expand All @@ -9,6 +9,9 @@
def FUNC():
pass

class CLASS:
pass

def fix_contant(value):
"""all this is ok, but try not using global ;)"""
global CONSTANT # [global-statement]
Expand Down Expand Up @@ -78,3 +81,12 @@ def func():
global sys # [global-statement]

import sys

def override_class():
"""Overriding a class should only throw a global statement error"""
global CLASS # [global-statement]

class CLASS():
pass

CLASS()
23 changes: 12 additions & 11 deletions tests/functional/g/globals.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
global-at-module-level:5:0:5:11::Using the global statement at the module level:UNDEFINED
undefined-variable:6:6:6:10::Undefined variable 'CSTE':UNDEFINED
global-statement:14:4:14:19:fix_contant:Using the global statement:UNDEFINED
global-variable-not-assigned:21:4:21:14:other:Using global for 'HOP' but no assignment is done:UNDEFINED
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_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
global-statement:17:4:17:19:fix_contant:Using the global statement:UNDEFINED
global-variable-not-assigned:24:4:24:14:other:Using global for 'HOP' but no assignment is done:UNDEFINED
undefined-variable:25:10:25:13:other:Undefined variable 'HOP':UNDEFINED
global-variable-undefined:30:4:30:18:define_constant:Global variable 'SOMEVAR' undefined at the module level:UNDEFINED
global-statement:36:4:36:14:global_with_import:Using the global statement:UNDEFINED
global-variable-not-assigned:42:4:42:19:global_no_assign:Using global for 'CONSTANT' but no assignment is done:UNDEFINED
global-statement:48:4:48:19:global_del:Using the global statement:UNDEFINED
global-statement:55:4:55:19:global_operator_assign:Using the global statement:UNDEFINED
global-statement:62:4:62:19:global_function_assign:Using the global statement:UNDEFINED
global-statement:72:4:72:15:override_func:Using the global statement:UNDEFINED
global-statement:81:4:81:14:func:Using the global statement:UNDEFINED
global-statement:87:4:87:16:override_class:Using the global statement:UNDEFINED