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

False positive for global-variable-not-assigned when using with #5073

Closed
andy-maier opened this issue Sep 26, 2021 · 7 comments · Fixed by #8151
Closed

False positive for global-variable-not-assigned when using with #5073

andy-maier opened this issue Sep 26, 2021 · 7 comments · Fixed by #8151
Labels
Documentation 📗 Enhancement ✨ Improvement to a component Good first issue Friendly and approachable by new contributors

Comments

@andy-maier
Copy link

Bug description

# File a.py
"""
The "global-variable-not-assigned" check does not take into account that a "with"
statement can very well change the global variable.
For example, when using a global condition variable by multiple threads:
"""

import threading

COND = threading.Condition()


def func1():
    "Function that is called in one thread"
    # pylint: disable=global-statement
    global COND
    with COND:
        COND.notify()

Configuration

No response

Command used

pylint a.py

Pylint output

************* Module a
a.py:16:4: W0602: Using global for 'COND' but no assignment is done (global-variable-not-assigned)

Expected behavior

Pylint realizes that "with" may change the global variable and thus counts it like it was an assignment, and thus does not raise the issue in this case.

Pylint version

pylint 2.11.1
astroid 2.8.0
Python 3.9.7 (default, Sep  3 2021, 12:45:31) 
[Clang 12.0.0 (clang-1200.0.32.29)]

OS / Environment

macOS

Additional dependencies

Output of pipdeptree:
pylint==1.6.4

  • astroid [required: >=1.4.5,<1.5.0, installed: 1.4.9]
    • lazy-object-proxy [required: Any, installed: 1.4.2]
    • six [required: Any, installed: 1.15.0]
    • wrapt [required: Any, installed: 1.11.2]
  • backports.functools-lru-cache [required: Any, installed: 1.6.4]
  • configparser [required: Any, installed: 4.0.2]
  • isort [required: >=4.2.5, installed: 4.2.15]
  • mccabe [required: Any, installed: 0.6.1]
  • six [required: Any, installed: 1.15.0]
@andy-maier andy-maier added Bug 🪲 Needs triage 📥 Just created, needs acknowledgment, triage, and proper labelling labels Sep 26, 2021
@timmartin
Copy link
Contributor

Is it true that the with statement is assigning to the variable? It should only read and execute the __enter__ and __exit__ methods on the object, and neither of these should be able to bind the global variable to a new object. Of course it's possible for with statement to mutate the contents of the object, but that's true of any method call on the object, and doesn't necessitate global.

It's worth noting that variables qualified by global are explicitly disallowed from being used as a target of a with statement, presumably because in that case the variable can be reassigned to a new object, and it would create unnecessary complexity to handle this.

@DanielNoord DanielNoord added False Positive 🦟 A message is emitted but nothing is wrong with the code and removed Bug 🪲 Needs triage 📥 Just created, needs acknowledgment, triage, and proper labelling labels Feb 9, 2022
@Pierre-Sassoulas Pierre-Sassoulas added the Needs investigation 🔬 A bug or crash where it's not immediately obvious what is happenning label Jul 6, 2022
@nickdrozd
Copy link
Collaborator

Is the global statement required here? What happens if it's removed?

@andy-maier
Copy link
Author

@nickdrozd @timmartin
Sorry for the delay.

The global statement is in fact not needed, because the global name is not bound again in the function. In our real code, that is also the case. Thanks for the hint, so I can simplify our code there.

However, I still think raising "global-variable-not-assigned error" is not right here. It is assigned (in the global scope) and it cannot be reassigned by the with statement.

@timmartin
Copy link
Contributor

I don't understand. You're saying that the global is not needed, but also claiming that the Pylint warning telling you that global is not needed is a false positive? Surely if the global is unnecessary then Pylint is doing exactly the right thing by telling you this?

Perhaps the name global-variable-not-assigned is causing some confusion. I think the point of the warning is to say that it isn't assigned, therefore global is unnecessary, but I can see how that string could be read as "variable not assigned", which I don't think is intended.

@mbyrnepr2
Copy link
Member

Right, I think a documentation update could be made to clarify it. Currently the message is not explicit about where the assignment is expected (in the same block as the global statement).

@timmartin
Copy link
Contributor

Perhaps change the message to something like Unnecessary use of global for 'COND' not assigned in scope? It's a bit clunky, but we want to fit the message on a single line. Or possibly even Unnecessary use of global for 'COND'? It sounds like the reference to assignment is making things less clear, not more clear.

@mbyrnepr2
Copy link
Member

I agree and I think your second example is a good clear and simple way to go.

@mbyrnepr2 mbyrnepr2 added Documentation 📗 Enhancement ✨ Improvement to a component Good first issue Friendly and approachable by new contributors and removed Needs investigation 🔬 A bug or crash where it's not immediately obvious what is happenning False Positive 🦟 A message is emitted but nothing is wrong with the code labels Dec 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Documentation 📗 Enhancement ✨ Improvement to a component Good first issue Friendly and approachable by new contributors
Projects
None yet
6 participants