pylint icon indicating copy to clipboard operation
pylint copied to clipboard

Emit new message ``used-global-in-annotation`` instead of ``used-prior-global-declaration``

Open Davichet-e opened this issue 6 years ago • 7 comments

Steps to reproduce

I have a namedtuple that I want to mutate on a function:

foo = collections.namedtuple("foo", "")

def bar() -> foo # Here pylint warns me
    global foo
    foo = collections.namedtuple("foo", "a b")
    return foo

Current behavior

Pylint warning me on the function return type annotation that is invalid for this reason: Name 'foo' is used prior to global declaration: pylint(used-prior-global-declaration)

Expected behavior

It should not warn at all since when I run the code, it runs without errors.

pylint --version output

pylint: 2.3.1 python: 3.7.3

Davichet-e avatar Sep 03 '19 15:09 Davichet-e

Thanks, I can reproduce the issue.

PCManticore avatar Sep 08 '19 08:09 PCManticore

I think we should be able to solve this bug, however, wouldn't it be better to pass the global variable to the function and re-assign the functions output to the variable? I don't think modifying global variables is recommended. Therefore, I would suggest changing the code that is currently throwing this error to start throwing a function-modifying-global-variable (name could be improved..) message. Users who still would like to do this can then disable this message.

DanielNoord avatar Aug 05 '21 18:08 DanielNoord

Agree. Note that this warning exists in pylint it's W0603 global-statement.

Pierre-Sassoulas avatar Aug 05 '21 18:08 Pierre-Sassoulas

Yes. I was thinking of a new warning based on the fact that the typing includes a global variable. However, the result can only be achieved by using the global statement somewhere in the function. So raising W0603 on the line that includes the typing seems to be enough!

DanielNoord avatar Aug 05 '21 18:08 DanielNoord

Pinging @cdce8p as I need some help with the order of typing resolution here.

foo = int

def bar() -> foo # Here pylint warns me
    global foo
    foo = str
    return foo()

pyright complains about (rightfully I think) as it thinks bar() should return an int while it doesn't. The case of the original report is more like:

foo = int

def bar() -> foo # Here pylint warns me
    global foo
    foo = int
    return foo()

That would be fine, but then the only way for us to determine whether or not we should raise used-prior-global-declaration is by comparing types, which is not our main competence.

I would be okay with used-prior-global-declaration also meaning: "don't use global for variables you use as type annotations". Or splitting this into a new message used-global-in-annotation and let users turn this off as they wish. This pattern seems likely to cause troubles.

DanielNoord avatar Jun 15 '22 11:06 DanielNoord

This pattern seems likely to cause troubles.

I agree. This looks like bad code. Tbh. I can't think of a situation where you would want to use a type alias (like foo) together with global at the moment. Just because it's valid, doesn't mean it's good.

I would be okay with used-prior-global-declaration also meaning: "don't use global for variables you use as type annotations".

🤔 Although the pattern is bad, it is valid. The annotation is evaluated in the module scope, we don't care about the function body itself here. So used-prior-global-declaration doesn't really fit. No matter how type checkers will resolve that.

Or splitting this into a new message used-global-in-annotation and let users turn this off as they wish.

That might be the best option here and most importantly captures the root issue: Using a type alias both in an annotation and with a global statement.

cdce8p avatar Jun 19 '22 11:06 cdce8p

Or splitting this into a new message used-global-in-annotation and let users turn this off as they wish.

That might be the best option here and most importantly captures the root issue: Using a type alias both in an annotation and with a global statement.

Thanks! Refocusing this issue then as I agree with you!

DanielNoord avatar Jun 19 '22 11:06 DanielNoord