The refactoring also fixes the problem with wrong types inferred for contextlib.contextmanager
GitOrigin-RevId: 1601047786a0c43a463a82225b18635d407bcb40
`dataclass_transform` support posed a number of challenges to the current
AST/PSI stubs separation in our architecture. For the standard "dataclasses"
module and the "attrs" package API, we could rely on well-known names
and defaults to recognize and preserve the information about decorator
arguments and field specifier arguments in PSI stubs. With `dataclass_transform`
however, effectively any decorator call or extending any base class can indicate
using a "magical" API that should generate dataclass-like entities.
At the moment of building PSI stubs we can't be sure, because we can't leave
the boundaries of the current file to resolve these names and determine if these
decorators and base classes are decorated themselves with `dataclass_transform`.
To support that, we instead rely on well-known keyword argument names documented
in the spec, e.g. "kw_only" or "frozen". In other words, whenever we encounter
any decorator call or a superclass list with such keyword arguments, we generate
a `PyDataclassStub` stub for the corresponding class.
The same thing is happening with class attribute initializers, i.e. whenever
we see a function call with argument such as "default" or "kw_only" in their
RHS, we generate a `PyDataclassFieldStub` for the corresponding target expression.
Both of these stub interfaces now can contain null values for the corresponding
properties if they were not specified directly in the class definition.
Finally, for the `dataclass_transform` decorator itself, a new custom decorator stub
was introduced -- `PyDataclassTransformDecoratorStub`, it preserves its keyword
arguments, such as "keyword_only_default" or "frozen_default" controlling
the default properties of generated dataclasses.
Later, when we need concluded information about specific dataclass properties,
e.g. in `PyDataclassTypeProvider` to generate a constructor signature, or in
`PyDataclassInspection`, we try to "resolve" this incomplete information from stubs
into finalized `PyDataclassParameters` and `PyDataclassFieldParameters` that
contain non-null versions of the same fields. The main entry points for that
are `resolveDataclassParameters` and `resolveDataclassFieldParameters`.
These methods additionally handle the situations where decorators, superclass
lists and field specifiers lack any keyword arguments, and thus, there were no
automatically created custom stubs for them.
All the existing usages of `PyDataclassStub` and `PyDataclassFieldStub`
were updated to operate on `PyDataclassParameters` and `PyDataclassFieldParameters`
instead.
Counterparts of the tests on various inspection checks for the standard dataclasses
definitions were added for dataclasses created with `dataclass_transform`, even
though the spec is unclear on some aspects the expected type checker semantics, e.g.
if combining "eq=False" and "order=True" or specifying both "default" and
"default_factory" for a field should be reported.
I tried to follow common sense when enabling existing checks for such arbitrary
user-defined dataclass APIs.
GitOrigin-RevId: 4180a1e32b5e4025fc4e3ed49bb8d67af0d60e66
The changes include:
- Inferring implicitly parameterized types for classes if they are generic classes with type parameters that have defaults.
- Inferring partially parameterized types for classes where only some of the default Type Parameters are overridden by explicit parameterization.
- Supporting both old-style and new-style generic Type Aliases, now considering defaults of Type Parameters.
GitOrigin-RevId: c3a0d7eb4a85585df9638081291ff83b850eb7f6
- Infer default types for TypeVars, ParamSpecs and TypeVarTuples
- Allow explicitly parameterizing ParamSpecs with `[type1, type2, ...]` constructions
- Correctly set declaration elements of Type Parameters inferred from references
GitOrigin-RevId: 024392a03f744e08c6dee054bbc2ca42c1f4b19e
In particular:
- Add getters and setters for default types of Type Parameters
- Change the type of declaration elements for Type Parameters from hardcoded PyTargetExpression to PyQualifiedNameOwner to make it possible to set new-style Type Parameters as declaration elements
- Correctly calculate the qualified names of the new-style type alias statements as now they will be used in declaration elements of Type Parameters
GitOrigin-RevId: 5185d85c1a75052dfcb3f97c0eee17b52540d24b
- PEP-696 adds a new syntax for declaring the default types of Type Parameters in new-new style generic classes, functions and type alias statements. Support these grammar changes.
- Store info about default types in stubs for Type Parameters
- Increment the stub version counter in PyFileElementType
GitOrigin-RevId: b6b22e3eaa86ce06132885781e5775a89bf4b840
Fix a bug with a situation when two identical inctances of type `Generic` were stored in the map in `com.jetbrains.python.psi.impl.PyClassImpl.mroLinearize` and were processed separately due to not matching hashcodes and equals methods. This situation caused an `MROException` to be thrown so the class ancestors could not be defined properly. It affected generic types matching as an actually generic class was not recognized as generic because of the wrong list of ancestors.
GitOrigin-RevId: 391390c5143b0c7247bd55f148d519f80063d5a8
As far as `__get__` call when accessing the attribute is implicit, create a synthetic call considering the type of callsite (access via instance or via class) and use its type as a type of property typed with descriptor class.
GitOrigin-RevId: acc36ebd2d62acfe99a5202b2478356f7b7aea46
In other words, this API allows inferring results of function calls based only on the type of reciever (e.g., class), if exists, and types of arguments passed to the function. The aim of this API is to replace the existing approach where we infer types of such "synthetic" calls by creating a new expression using `com.jetbrains.python.psi.PyUtil.createExpressionFromFragment` and then inferring the type of created expression
GitOrigin-RevId: 09bee7ba1757cb07910be245253fe4bd855f5076
Does not solve the issue yet, but adds proper code fragment with hidden imports
fixup! PY-24044 Fix PyCodeFragmentWithHiddenImports
Changed streams to StringUtil
Changed internal keyword to ApiStatus.Internal
fixup! PY-24044 Fix PyCodeFragmentWithHiddenImports
Convert method to accept a collection of imports
fixup! PY-24044 Fix PyCodeFragmentWithHiddenImports
Mark class as internal
fixup! PY-24044 Fix PyCodeFragmentWithHiddenImports
Remove commented code
fixup! PY-24044 Fix PyCodeFragmentWithHiddenImports
Made publicly exposed collection immutable
Changed PyImportNameDefiner to PyImportedStatementBase
Changed String to List<String>
PY-24044 Fix PyCodeFragmentWithHiddenImports
Merge-request: IJ-MR-143472
Merged-by: Aleksandr Govenko <aleksandr.govenko@jetbrains.com>
GitOrigin-RevId: bcf28b4a74deeb2adf4d4e53a3c867a9ab7b8ef4
Performance snapshot shows that an enormous amount of time is spent calculating hashcodes for types.
GitOrigin-RevId: 47d488ada253c1aa78ae247d45af50cf4a553426
Added new PyCodeFragmentWithHiddenImports that allows adding imports for unresolved names into a hidden file
GitOrigin-RevId: fb3fa4e491164bdd376d3b25204202034994afa5
This method collects all methods defined in the class and its parents.
Similar to `getPropertiesInherited` and `getClassAttributesInherited`.
GitOrigin-RevId: 8dcec5a002ffa105083ece6f4418d51e6d8c2879