-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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: possibly-used-before-assignment
and pytest.skip
(and other NoReturn
functions)
#9674
Comments
Agree we should do this, and also update the docs for |
- Add a couple new "raise utils.Unreachable" to avoid possibly-used-before-assignment issues. - Simplify an "if" for the same reason - Remove an unneeded "return" - Use "NoReturn" to prepare for pylint knowing about it in the future: pylint-dev/pylint#9674 - Add some ignores for used-before-assignment false-positives - Ignore new undefined-variable messages for Qt wrapers - Ignore a new no-member warning for KeySequence: pylint-dev/astroid#2448 (comment)
I was wondering if it should be in pylint-pytest only but it's easy enough to do to be in pylint directly. (@stdedos fyi) |
Sure, why not? In pylint context, it does feel like a https://github.com/pylint-dev/pylint-pytest thing |
I still think this should be more generic than hardcoding pytest methods. I had another scenario in my codebase where I have something like: def _raise_invalid_node(...) -> NoReturn:
# do some additional work
raise Exception(...)
def func():
if ...:
var = 1
else:
_raise_invalid_node(...)
print(var) and I'd expect pylint to know that |
I don't object the correct-ness of your statement. What concerns me is how much should pylint enter the fields of mypy 😅 I don't know how strong pylint is / invested in data flow analysis |
There's a lot of work to start taking typing into account in pylint (generically at least). Hypothetically, pylint would infer first, and use typing if inference fail (#4813) Making inference handle a calls that always exit well is something to consider for sure. I don't know if we have an open issue for that. But the reasonable short term solution is to pre-populate |
What if pylint does the short-term solution, and then pylint-pytest builds on top of that, and auto-inject more |
There are great test cases for this in #9692 |
Yes, there is not enough volunteer labor nor would it be a wise use of it to emulate mypy in pylint. Part of pylint's value prop is "not trusting your typing", making it especially useful for legacy/untyped codebases. (see "realist pylint user" quoted in the repo readme) However... it strikes me that that's still consistent with observing declarations like This diff makes the false positive go away (someone should kick the tires and make sure it's right): diff --git a/pylint/checkers/utils.py b/pylint/checkers/utils.py
index a3e649651..a7938528a 100644
--- a/pylint/checkers/utils.py
+++ b/pylint/checkers/utils.py
@@ -2165,6 +2165,13 @@ def is_terminating_func(node: nodes.Call) -> bool:
and inferred.qname() in TERMINATING_FUNCS_QNAMES
):
return True
+ if (
+ isinstance(inferred, nodes.FunctionDef)
+ and isinstance(inferred.returns, nodes.Name)
+ and (inferred_func := inferred.returns.inferred()[0])
+ and (inferred_func.qname() == 'typing.NoReturn')
+ ):
+ return True
except (StopIteration, astroid.InferenceError):
pass @stdedos would you potentially be interested in being the person to kick the tires? Make sure that's right, and get a test and changelog added? |
I would love to be that person. ... However, I have "lack-of-knowledge" of my own that I need to kick sometime (pylint-dev/pylint-pytest#68), and also "lack-of-time" these days 😕 |
Bug description
Configuration
No response
Command used
Pylint output
Expected behavior
No error: The
pytest
module has a couple of functions that never return:pytest.exit(...)
pytest.skip(...)
pytest.fail(...)
pytest.xfail(...)
Related:
possibly-used-before-assignment
does not understandassert_never
#9643Instead of maintaining a list of functions like this, could pylint maybe instead check whether they have a
NoReturn
return type, if type information is available? That would coverassert_never()
, all the pytest functions, possiblysys.exit()
and friends (if stdlib typing information is available via typeshed), and lots and lots of other third-party cases like this.Pylint version
OS / Environment
Archlinux
Additional dependencies
No response
The text was updated successfully, but these errors were encountered: