Commit Graph

173 Commits

Author SHA1 Message Date
Aleksandr.Govenko
adcc559e5c PY-81676 Don't report lines with assert_never as unreachable
(cherry picked from commit afdbf35915823de02a6b8551f57770113d0feb2f)

IJ-CR-172556

GitOrigin-RevId: 0f8526e2877736ac606db9ed4657a530a66d6f23
2025-08-15 13:27:10 +00:00
Aleksandr.Govenko
6deddd7ee2 PY-81608 False positive "This code is unreachable" after try / finally if try has a while loop
(cherry picked from commit fbdefd71c5c9356c82d3c873426dd565dd95c613)

IJ-MR-169577

GitOrigin-RevId: b428a790336656088c9b3343a2f6772873cafca8
2025-08-08 18:19:44 +00:00
Aleksandr.Govenko
7e0924c394 PY-82712 False positive unreachable code after try / finally block if try has an if
(cherry picked from commit 53c13421523d780995fa83cc0625f6e99d5fe51f)

IJ-MR-169577

GitOrigin-RevId: f5254435a0512ba55db7fca9016a387740ac9b8b
2025-08-08 18:19:44 +00:00
Aleksandr.Govenko
63a9e9092d PY-81482 assert True in try triggers "This code is unreachable" after finally
(cherry picked from commit 9e5ea2546169cda70f2aaf810fa2f27d13cb102a)

IJ-MR-167790

GitOrigin-RevId: 2f6158133cd075f4b7155e8fe922dcfa85155085
2025-07-03 17:58:56 +00:00
Aleksandr.Govenko
b0ca1ef976 [python] PY-81674 Highlight all unreachable code gray
GitOrigin-RevId: 5a8dba3a51b7e9d415deb5401213ad3b79ddd3c5
2025-06-13 16:56:16 +00:00
Aleksandr.Govenko
b54f5b4ae8 PY-53880 Incorrect exhaustive pattern matching of Enum or Union types
Add PyNeverType and integrate it in PyTypeAssertionEvaluator

GitOrigin-RevId: 3db5224bfbf559f6d1bb146fd72c6cc6a97c4598
2025-05-30 18:33:26 +00:00
Aleksandr.Govenko
06a9b9bde5 PY-80421 PY-80471 PY-80824 PY-80550 false "unused variable" with for nested in if/else
PY-80564 Fp "Local variable might be referenced before assignment" when returning a comprehension in `try/except`

PY-80733 Fp "Local variable might be referenced before assignment" for `try/except` with a `break` inside a loop


Merge-request: IJ-MR-162320
Merged-by: Aleksandr Govenko <aleksandr.govenko@jetbrains.com>

GitOrigin-RevId: f3e5d76e1fb15e2951d395fa27768269e4d0cb8f
2025-05-14 12:15:56 +00:00
Petr
c8fb196d52 PY-76877 Conformance test failure: overloads_basic.py
PySliceExpression is replaced by PySubscriptionExpression in AST.
PySliceItem is returned by PySubscriptionExpression.getIndexExpression(). For that purpose PySliceItem is now a PyExpression of type `builtins.slice`.

GitOrigin-RevId: 9aa8de13ef7c51741e248317c5264b3a06ffb9bf
2025-05-12 18:15:13 +00:00
Aleksandr.Govenko
df545f8047 PY-79910 Variable incorrectly marked as unused or redeclared without usage in nested try/if blocks
When there is no `finally` in try-except statement, use transparent exit instruction to tie all normal exits from try-, else- and except- parts to the next instruction


Merge-request: IJ-MR-158265
Merged-by: Aleksandr Govenko <aleksandr.govenko@jetbrains.com>

GitOrigin-RevId: 734581b732a1a558b72811fdda977c470d045cc9
2025-04-23 22:39:58 +00:00
Aleksandr.Govenko
0073c7a8bb PY-48011 Pattern Matching: Type inference
Merge-request: IJ-MR-154823
Merged-by: Aleksandr Govenko <aleksandr.govenko@jetbrains.com>

GitOrigin-RevId: 42cb07bee63f34127c85574fc9c09e6043bc7591
2025-03-07 22:56:00 +00:00
Aleksandr.Govenko
68ae14a71c PY-78964 Incorrect return type warning when using try...finally
Added a new CFG instruction to indicate implicit raise after finally block. Also added PyDataFlow as an future entry point for DFA.


Merge-request: IJ-MR-155798
Merged-by: Aleksandr Govenko <aleksandr.govenko@jetbrains.com>

GitOrigin-RevId: db63ba632c48235cc51b8e64869d21f5bcfc2d1c
2025-03-07 01:31:33 +00:00
Aleksandr.Govenko
e8f5b1c631 PY-52477 PY-78913 Add inspection for inconsistent returns
Merge-request: IJ-MR-154297
Merged-by: Aleksandr Govenko <aleksandr.govenko@jetbrains.com>

GitOrigin-RevId: e89225212cc981a5b256fca4ee23d77659b3ce5e
2025-02-14 17:21:51 +00:00
Aleksandr.Govenko
6659947437 PY-51564 "code is unreachable" warning does not consider that context managers can abort
Added PyWithContextExitInstruction that works as 'except' node in try-except statements, but for 'with context-manager' statements. This allows to see when it can recover from exception by checking the type of `contextlib.AbstractContextManager`

Merge-request: IJ-MR-152213
Merged-by: Aleksandr Govenko <aleksandr.govenko@jetbrains.com>

GitOrigin-RevId: fd5a139de31d47136cc86b4a7e090a20b73b8744
2025-02-14 13:18:20 +00:00
Petr
04cac6392b PY-76906 Support type narrowing for comparisons with literal types
GitOrigin-RevId: 8094877f9b02b57f005391dd1b95befba621b604
2025-01-14 20:04:53 +00:00
Petr
3b75807c89 [python] Introduced PyRaiseInstruction to be able to handle assertions while finding out function's exit points
GitOrigin-RevId: 88cb616037af7f3b833351b29b123c34fc177eec
2024-12-20 18:27:13 +00:00
Petr
3f8f4f40c3 [python] CFG support logical expressions in if/while conditions
GitOrigin-RevId: 274b3271dccc93be64830374c8047a8f6552033e
2024-12-19 19:51:11 +00:00
Aleksandr.Govenko
582260c604 PY-37718 "This code is unreachable" after an 'assert False' a context manager
Treat 'assert False' like 'raise AssertionError'


Merge-request: IJ-MR-150462
Merged-by: Aleksandr Govenko <aleksandr.govenko@jetbrains.com>

GitOrigin-RevId: d8d0a5e27d377362059a0d2a5e15aa730bdfb49a
2024-12-12 02:56:58 +00:00
Aleksandr.Govenko
31dd92576e PY-20611 Missing warning about functions implicitly returning None when return type is not Optional
Updated PyFunction to account for implicit 'return None' statements when inferring return statement types.

It affected return type inference of PyFunction.

Fixed a failing test related to formatted strings.

Added a quick fix to make all return statements explicit.

Updated the CFG to include PyPassStatements, enabling detection of exit points in empty functions.

Simplified PyMakeFunctionReturnTypeQuickFix to independently infer function types and handle required imports. Currently, it does not support specifying custom suggested types.



Merge-request: IJ-MR-148719
Merged-by: Aleksandr Govenko <aleksandr.govenko@jetbrains.com>

GitOrigin-RevId: 9f58961f9eb70e4f9dbba7359f5aafdfd392b7e2
2024-11-26 17:02:37 +00:00
Irina Fediaeva
01e08f43e4 PY-52574: Update tests after removing Epytext docstring format
GitOrigin-RevId: d4a90a8da56ca889cf380aa5bc72ac82b0716abc
2024-10-29 21:03:06 +00:00
Mikhail Golubev
190a55438e [python] Special-case typing.Generic while calculating a class MRO
typing.Generic is a magical class that can be specified in any position
in the list of base classes, not affecting the MRO consistency. It's done by
the custom __mro_entries__ implementation in typing._BaseGenericAlias (Python < 3.12),
which skips this Generic entry if there are other generic classes following
it on the list of superclasses. Namely, it's possible to do the following:

```
class Base(Generic[T]):
    pass

class MyClass(Generic[T], Base[T]):
    pass
```

which would cause a TypeError for regular classes. Since it broke our implementation
of the C3 algorithm in PyClassImpl.getMROAncestorTypes, we now special-case it by
always moving typing.Generic to the very end of the base class list while constructing
MRO.

See https://github.com/python/cpython/blob/3.11/Lib/typing.py#L1298 for a pure-Python
version of typing._BaseGenericAlias.__mro_entries__ and a relevant discussion in
https://github.com/python/cpython/issues/106102.

GitOrigin-RevId: e7d765193d532ab8457133e8fb5ad06840d89225
2024-10-02 14:29:04 +00:00
Vladimir Koshelev
82e8947e95 [pycharm] move type guards from control flow to PyDefUse stage
GitOrigin-RevId: e66971e619978ad179bb49a15820a7482b27df7c
2024-07-15 18:43:02 +00:00
Vladimir Koshelev
582edda2e8 [pycharm] fix control flow tests after adding CallInstruction
GitOrigin-RevId: 1878a3211a07b216a64df3efa6ac7cb1c94fd246
2024-07-10 14:22:00 +00:00
Mikhail Golubev
98016a1ae6 PY-63367 PY-63366 Include instructions for annotations of new-styles generic functions in their own CFG
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
2023-10-16 23:42:44 +00:00
Mikhail Golubev
caf1082077 [python] Remove instructions for parameter defaults and return type annotations from functions CFG
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
2023-10-16 23:42:44 +00:00
Daniil Kalinin
65cc3ddfd0 PY-61877, PY-61878 PEP 695 Type Parameter Syntax: Control flow for type parameters and type aliases
GitOrigin-RevId: 2db381cbb97891296bae09e48c17b46eefa57a04
2023-09-28 15:05:31 +00:00
Vladimir Koshelev
7aeb74fe0a [PY-49040] add support for TypeGuards
Merge-request: IJ-MR-109904
Merged-by: Vladimir Koshelev <Vladimir.Koshelev@jetbrains.com>

GitOrigin-RevId: 8441ce35b2fc97fb0cdaf747feff2cf9ba3347ea
2023-08-02 22:27:54 +00:00
Daniil Kalinin
45bb1fffb8 PY-24273, PY-53703 Support for functions annotated with typing.NoReturn and typing.Never
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
2023-06-13 22:08:30 +00:00
Daniil Kalinin
7842a42c51 PY-41231, FL-15391 Ignore type annotations in Python live templates
Merge-request: IJ-MR-102294
Merged-by: Daniil Kalinin <Daniil.Kalinin@jetbrains.com>

GitOrigin-RevId: 753721489edb85702b72d56da1016bbc85af9f52
2023-02-09 16:59:39 +00:00
Daniil Kalinin
c245993809 PY-7758, PY-23859 improvements in Control Flow analysis
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
2022-11-01 09:54:20 +00:00
Daniil Kalinin
93e169eea2 PY-26060 New version-dependent super method signature macro
Tests for PY-26060

Merge-request: IJ-MR-95531
Merged-by: Daniil Kalinin <Daniil.Kalinin@jetbrains.com>

GitOrigin-RevId: 134f45d43aefc3cf7a3f806e0ea1ea6f768528f4
2022-10-14 14:02:44 +00:00
Daniil Kalinin
fa259d0727 PY-52162 deprecated implementation of PythonTemplateContextType#isInContext changed to accept TemplateActionContext
Tests for PY-52162

Merge-request: IJ-MR-24510
Merged-by: Daniil Kalinin <Daniil.Kalinin@jetbrains.com>

GitOrigin-RevId: 8cb7674b3840424015eeb06981ec16734fe26af2
2022-05-20 08:37:03 +00:00
Mikhail Golubev
97b22aaa13 PY-42200 Support parenthesized context managers in Python 3.9+
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
2022-05-04 12:31:37 +00:00
Mikhail Golubev
20097f7a69 PY-49785 Properly recover from "case" keyword in the middle of a match statement
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
2021-07-19 16:29:15 +00:00
Mikhail Golubev
353d7f24d1 PY-48014 Implement Complete Current Statement for match statement and its clauses
GitOrigin-RevId: dba29d39fc90397a2f4af8a347cfcbf208ce5c92
2021-06-24 15:04:01 +00:00
Mikhail Golubev
cb08d4de98 PY-48760 Implement CFG for PEP-634 match statements
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
2021-06-11 10:16:38 +00:00
Mikhail Golubev
7c226889fc Preserve the capitalization in test data files of PyControlFlowBuilderTest
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
2021-05-11 15:55:26 +00:00
Semyon Proshev
ea9c2c9415 Reuse if-statements approach for while-statements to understand when and where condition is succeeded/failed (PY-39262)
It allows to assume that under `and` condition all sub-conditions are satisfied.

GitOrigin-RevId: f58ed2706d7eb9c1595415cce57cb8020011b57a
2021-03-23 11:45:13 +00:00
Semyon Proshev
882c5348b3 Add separate CFG instructions to if-statements to understand when and where a condition is succeeded/failed (PY-39262)
It allows to assume that under `and` condition all sub-conditions are satisfied.

GitOrigin-RevId: 104bb5a2200791d183cc26e008b974a6b658fa37
2021-03-23 11:45:12 +00:00
Andrey Vlasovskikh
a79f1a9dd9 PY-43889 Fixed capitalisation in names of test data directories
GitOrigin-RevId: 145ab5cf3f9d990112b722ea8f97564a88631f59
2021-03-09 14:48:46 +00:00
Andrey Vlasovskikh
ff7ead9b79 PY-43889 Expand 'main' live template only at top-level
GitOrigin-RevId: bcf272b5032a6f9ee4143a38cf7cc6da965053f4
2021-03-08 23:05:55 +00:00
Mikhail Golubev
13afc2cbfb PY-43053 Handle Complete Current Statement after a collection at the end of a file
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
2020-06-18 19:23:01 +03:00
Mikhail Golubev
16eebe034e PY-25001 Implement Complete Current Statement for collection literals
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
2020-06-10 22:57:53 +03:00
andrey.matveev
de6a66846e [pycharm] Delete testNumberOfOccurrencesNamedArgsWithPrefix test
GitOrigin-RevId: 4d1a8134438a09f9388f6cb8aae2513fc4d73d75
2020-06-05 13:08:31 +03:00
andrey.matveev
bf9aa197ad PY-41056 Impl new ml completion features
GitOrigin-RevId: 2c7d1296854ced8f291aa7ee399ebd1881e2b005
2020-04-15 10:02:07 +00:00
andrey.matveev
073af04a6a PY-38581 Implement previous calls feature
GitOrigin-RevId: 5682350bfd95a6abfc325b511c55d6e27b41476a
2020-02-25 05:37:15 +00:00
andrey.matveev
c4950335ac PY-39607 Add new features for ml completion
GitOrigin-RevId: caf60bd52a1872a2eb53f3617a6ffb51b195ff33
2020-01-29 13:41:50 +00:00
andrey.matveev
92e41799f2 PY-37720 Impl python ml completion features
GitOrigin-RevId: 3b8029ab460672b286d7b1cf96fd35bf9c57bf59
2019-10-11 08:01:46 +00:00
aleksei.kniazev
16786f4b89 added inspection for deleted variables with no qualifiers (PY-4537)
- treat deletion by slice and subscription expressions as read access
- delete instruction in dataflow only inserted for PyReferenceExpression

GitOrigin-RevId: 72ae5e964a1e287e007dabb8f41433b284523a02
2019-10-02 13:08:48 +00:00
Aleksei Kniazev
3c203f5382 IDEA-CR-51590: added self parameter for methods on smart enter (PY-35163)
self is inserted for methods that are not class-/staticmethod
cls is inserted for classmethod
empty parameter list for staticmethod

GitOrigin-RevId: 9743ae50c89c069b8123b8b6eb26fb841dd1f5b2
2019-09-04 15:08:25 +00:00
Semyon Proshev
a86c0b2bbe Fix building CFG for assignment expressions so target is visited after assigned value (PEP 572) (PY-33886)
GitOrigin-RevId: ac57729f8a9188a9fccf12936675c5818969435c
2019-07-02 06:52:16 +03:00