Files
openide/python/python-psi-impl
Mikhail Golubev f6d7b71285 PY-56541 Preserve PyTypingTypeProvider.Context between calls to the provider
The problem was caused by the recursive alias CoreSchema in pydantic-core, none
of our existing recursive type guards protected against.
Namely, pydantic_core.core_schema.CoreSchema alias referred to a number of
TypedDict declarations, many of which used CoreSchema in their own annotations.
Normally, the guard against recursive type aliases in PyTypingTypeProvider
should have caught that, but PyTypedDictType instances are constructed in
another provider and once we left PyTypingTypeProvider we lost the information
about already traversed type aliases, as this information is not preserved in a
regular TypeEvalContext instances.

The protection against recursive evaluation of types in TypeEvalContext, on the
other hand, did catch that, but because it intercepts recursive inference for
the same PyTypedElement and knows nothing about type aliases, so it happened
only when we tried to evaluate the type for the same TypedDict attribute twice.
Depending on the order of TypedDict references within the union type, for some
of them, it occurred only after we'd already traversed through all remaining
TypedDicts trying to build the union type for CoreSchema again for their
attributes. As a result, the size of the tree of these union types grew
exponentially, reaching 13 million elements and bringing our analysis to
its knees.

Ideally, we should have a single entry point in our API for all the computations
related to type hints that should take care of keeping the information about
type aliases. For now, as a workaround, I store the state of PyTypingTypeProvider
in a thread local cache per TypeEvalContext and restore it if we leave and then
get back to the same provider.

GitOrigin-RevId: 5a9b498fefa7dc275e3c4d7d265bdd07f846ad87
2023-03-02 18:10:08 +00:00
..