This way they have access to type parameters of these functions, and PyReferenceImpl.getResultsFromProcessor
can properly perform flow-sensitive resolve for them now that READ instructions for expressions
inside annotations and WRITE instructions for type parameters are in the same CFG. It allowed to
remove all the special logic for type parameters from PyReferenceImpl as well as from
PyUnboundLocalVariableInspection.
I had to special-case these annotations in PyResolveUtil.scopeCrawlUp, though, to "lift" their
original scope back from what ScopeUtil.getScopeOwner returns, making names defined in a class scope,
e.g., nested classes, visible to them.
GitOrigin-RevId: b2e78211565300dbcd7c2e2b246a7a8e14bb0e8f
Both of these are evaluated in the outer scope, e.g., in a scope of a containing class or a module,
with the corresponding instructions already processed there, and were duplicated in the CFG
of function bodies.
GitOrigin-RevId: 4460cbef6446a311f0ab15ffe3407bfbb73286e2
Functions annotated with `NoReturn` and `Never` now taken into account in the Control Flow Graph building process, and the code after calling such functions is treated as unreachable.
Merge-request: IJ-MR-105973
Merged-by: Daniil Kalinin <Daniil.Kalinin@jetbrains.com>
GitOrigin-RevId: ef5840ae6e593498fc334dc9bd2daadccebf2b13
Control flow now abrupts on `exit()` and `pytest.fail()` calls
Control flow now abrupts only if class which contains `self.fail()` call contains case-insensitive "test" word in the name
Merge-request: IJ-MR-96165
Merged-by: Daniil Kalinin <Daniil.Kalinin@jetbrains.com>
GitOrigin-RevId: ea173fdb72a10a373cd95f266ea7589e36545f30
In case of syntactic ambiguity with previous versions of the grammar, such as
"with (expr)" or "with (expr1, expr2)", PyWithStatement is still parsed as
having its own parentheses, not a parenthesized expression or a tuple as
a single context expression. The latter case, even though syntactically legal,
is still reported by the compatibility inspection in Python <3.9.
These changes also include proper formatter and editing support (e.g. not
inserting backslashes on line breaks inside parentheses), as well as
Complete Current Statement, which now takes possible parentheses into account
while inserting a missing colon.
The changes in the formatter are somewhat ad-hoc, intended to minimize the effect
on other constructs. "With" statement is somewhat special in the sense that it's
the first compound statement (having a statement list) with its own list-like
part in parentheses.
Existing tests on with statement processing were expanded and uniformly named.
Co-authored-by: Semyon Proshev <semyon.proshev@jetbrains.com>
GitOrigin-RevId: 15c33e97f177e81b5ed23891063555df016feb05
Not stopping at a statement break token and continuing recovery until a colon,
we considered the subsequent well-formed case clause to be a part of an error
message about a missing pattern, thus, moving the caret to its colon.
GitOrigin-RevId: f4ee0e12876960e989de3dee89925b65e3cf2339
I introduced a new type of CFG instructions, similar to ConditionalInstruction,
called RefutablePatternInstruction. The idea is that every pattern that can
possibly fail to match is surrounded with a pair of such instructions, helping
to describe how the control flow moves in each case. The PEP calls the opposite
type of patterns that always match "irrefutable", hence the name. We need these
synthetic instructions because otherwise some refutable patterns such as literal
ones (e.g. "42") don't leave any nodes in the graph. Incorporating the information
about irrefutable patterns right into the graph allows catching cases such
as "wildcard/name capture makes remaining patterns unreachable", both in OR
patterns and independent case clauses.
GitOrigin-RevId: beebe1890a6a824b188e6954a2c92f7ec52079e0
Previously, it used an odd convention with lowercased names of test data
files (with nothing separating individual words), which made adding new tests
quite tedious.
Also, I removed the test data "exit.py" as it wasn't used by any test.
GitOrigin-RevId: 92b1963c67ed01977f5b7ad020984056c9fe045d
It's weird, however, that Python implementation might query fixers for elements
that are at completely different lines with the caret as in the originally
reported case. This confusing and error-prone behavior needs to be revised
separately.
GitOrigin-RevId: 1f48fe0e0936fb2007022dfc889c44ad32e1eaf0
It works by automatically inserting a trailing comma before a line break in
multiline collection literals. Additionally, a colon is inserted between a key
and a value in dict literals.
Because of the language ambiguity regarding syntax of some incomplete collection
literals, colon is not inserted after the first key of a dict literal
(it's indistinguishable from a set literal with one item), and comma is not
inserted after the first item of a parenthesized tuple (it's indistinguishable
from a parenthesized expression).
The idea was taken from such implementation of Complete Current Statement for
JSON.
GitOrigin-RevId: 49ff9857d8c12476bfa9aacaed0b49faa99810fd
- treat deletion by slice and subscription expressions as read access
- delete instruction in dataflow only inserted for PyReferenceExpression
GitOrigin-RevId: 72ae5e964a1e287e007dabb8f41433b284523a02
self is inserted for methods that are not class-/staticmethod
cls is inserted for classmethod
empty parameter list for staticmethod
GitOrigin-RevId: 9743ae50c89c069b8123b8b6eb26fb841dd1f5b2
There is no edge between loop statement and next after loop instruction
when loop has at least one iteration
so `continue` is marked as one more last instruction in the loop
but properly take them into account in PyClassType#getMetaClassType().
This check was implemented there instead of PyClass#getMetaClassType()
itself, since the former method already looks up for explicitly declared
metaclasses in ancestors unlike PyClassImpl that considers only those
specified directly in the class definition or its containing module.
Moreover, there are actual usages that expects such behavior from
PyClass#getMetaClassType(), e.g. PyAbstractClassInspection.
in case this relationship was created implicitly by inheriting an
instance of metaclass.
It also fixes warnings about the first parameter of SQLAlchemy model
methods being named "self" instead of "cls" since we no longer consider
these classes descendants of "type".
to handle, in particular, lazy initialization scenarios
For instance, the statement "foo.bar = 42" should add a node
"WRITE ACCESS foo.bar" containing the corresponding target expression.
Additionally, "Unused local" inspection doesn't consider writes to
attributes, since, strictly speaking, these are not local names.
The check that we should add such synthetic node only if there were no
pending edges inside the body of if statement (e.g. if it contained only
break/continue/return for the enclosing loop) seems doubtful and
doesn't cover the simplest/most common cases.
Otherwise it's impossible to flow-sensitively resolve names referenced
inside such f-strings since we use the containing statement as the anchor
node in the graph.