|
6 | 6 |
|
7 | 7 | from __future__ import annotations
|
8 | 8 |
|
| 9 | +import textwrap |
9 | 10 | import typing
|
10 | 11 | from collections.abc import Iterator
|
11 | 12 | from functools import partial
|
12 | 13 | from typing import Final
|
13 | 14 |
|
14 | 15 | from astroid import context, extract_node, inference_tip
|
15 |
| -from astroid.builder import _extract_single_node |
16 |
| -from astroid.const import PY39_PLUS |
| 16 | +from astroid.brain.helpers import register_module_extender |
| 17 | +from astroid.builder import AstroidBuilder, _extract_single_node |
| 18 | +from astroid.const import PY39_PLUS, PY312_PLUS |
17 | 19 | from astroid.exceptions import (
|
18 | 20 | AttributeInferenceError,
|
19 | 21 | InferenceError,
|
@@ -231,7 +233,8 @@ def _looks_like_typing_alias(node: Call) -> bool:
|
231 | 233 | """
|
232 | 234 | return (
|
233 | 235 | isinstance(node.func, Name)
|
234 |
| - and node.func.name == "_alias" |
| 236 | + # TODO: remove _DeprecatedGenericAlias when Py3.14 min |
| 237 | + and node.func.name in {"_alias", "_DeprecatedGenericAlias"} |
235 | 238 | and (
|
236 | 239 | # _alias function works also for builtins object such as list and dict
|
237 | 240 | isinstance(node.args[0], (Attribute, Name))
|
@@ -273,6 +276,8 @@ def infer_typing_alias(
|
273 | 276 |
|
274 | 277 | :param node: call node
|
275 | 278 | :param context: inference context
|
| 279 | +
|
| 280 | + # TODO: evaluate if still necessary when Py3.12 is minimum |
276 | 281 | """
|
277 | 282 | if (
|
278 | 283 | not isinstance(node.parent, Assign)
|
@@ -415,6 +420,29 @@ def infer_typing_cast(
|
415 | 420 | return node.args[1].infer(context=ctx)
|
416 | 421 |
|
417 | 422 |
|
| 423 | +def _typing_transform(): |
| 424 | + return AstroidBuilder(AstroidManager()).string_build( |
| 425 | + textwrap.dedent( |
| 426 | + """ |
| 427 | + class Generic: |
| 428 | + @classmethod |
| 429 | + def __class_getitem__(cls, item): return cls |
| 430 | + class ParamSpec: ... |
| 431 | + class ParamSpecArgs: ... |
| 432 | + class ParamSpecKwargs: ... |
| 433 | + class TypeAlias: ... |
| 434 | + class Type: |
| 435 | + @classmethod |
| 436 | + def __class_getitem__(cls, item): return cls |
| 437 | + class TypeVar: |
| 438 | + @classmethod |
| 439 | + def __class_getitem__(cls, item): return cls |
| 440 | + class TypeVarTuple: ... |
| 441 | + """ |
| 442 | + ) |
| 443 | + ) |
| 444 | + |
| 445 | + |
418 | 446 | AstroidManager().register_transform(
|
419 | 447 | Call,
|
420 | 448 | inference_tip(infer_typing_typevar_or_newtype),
|
@@ -442,3 +470,6 @@ def infer_typing_cast(
|
442 | 470 | AstroidManager().register_transform(
|
443 | 471 | Call, inference_tip(infer_special_alias), _looks_like_special_alias
|
444 | 472 | )
|
| 473 | + |
| 474 | +if PY312_PLUS: |
| 475 | + register_module_extender(AstroidManager(), "typing", _typing_transform) |
0 commit comments