Skip to content

Commit

Permalink
Python 3.12 adjustments for typing brain
Browse files Browse the repository at this point in the history
A C-accelerator was introduced for the typing module in
Python 3.12 (see python/cpython#103764).

Because a pure python source is no longer available, now we stub
out the missing classes and provide some __class_getitem__
methods to allow subscripting like Type[int].

This may mean when 3.12 is the minimum, we can remove older
brain features like infer_typing_alias().
  • Loading branch information
jacobtylerwalls committed Jun 23, 2023
1 parent 6c325a9 commit bd9e62d
Showing 1 changed file with 34 additions and 3 deletions.
37 changes: 34 additions & 3 deletions astroid/brain/brain_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@

from __future__ import annotations

import textwrap
import typing
from collections.abc import Iterator
from functools import partial
from typing import Final

from astroid import context, extract_node, inference_tip
from astroid.builder import _extract_single_node
from astroid.const import PY39_PLUS
from astroid.brain.helpers import register_module_extender
from astroid.builder import AstroidBuilder, _extract_single_node
from astroid.const import PY39_PLUS, PY312_PLUS
from astroid.exceptions import (
AttributeInferenceError,
InferenceError,
Expand Down Expand Up @@ -231,7 +233,8 @@ def _looks_like_typing_alias(node: Call) -> bool:
"""
return (
isinstance(node.func, Name)
and node.func.name == "_alias"
# TODO: remove _DeprecatedGenericAlias when Py3.14 min
and node.func.name in {"_alias", "_DeprecatedGenericAlias"}
and (
# _alias function works also for builtins object such as list and dict
isinstance(node.args[0], (Attribute, Name))
Expand Down Expand Up @@ -273,6 +276,8 @@ def infer_typing_alias(
:param node: call node
:param context: inference context
# TODO: evaluate if still necessary when Py3.12 is minimum
"""
if (
not isinstance(node.parent, Assign)
Expand Down Expand Up @@ -415,6 +420,29 @@ def infer_typing_cast(
return node.args[1].infer(context=ctx)


def _typing_transform():
return AstroidBuilder(AstroidManager()).string_build(
textwrap.dedent(
"""
class Generic:
@classmethod
def __class_getitem__(cls, item): return cls
class ParamSpec: ...
class ParamSpecArgs: ...
class ParamSpecKwargs: ...
class TypeAlias: ...
class Type:
@classmethod
def __class_getitem__(cls, item): return cls
class TypeVar:
@classmethod
def __class_getitem__(cls, item): return cls
class TypeVarTuple: ...
"""
)
)


AstroidManager().register_transform(
Call,
inference_tip(infer_typing_typevar_or_newtype),
Expand Down Expand Up @@ -442,3 +470,6 @@ def infer_typing_cast(
AstroidManager().register_transform(
Call, inference_tip(infer_special_alias), _looks_like_special_alias
)

if PY312_PLUS:
register_module_extender(AstroidManager(), "typing", _typing_transform)

0 comments on commit bd9e62d

Please sign in to comment.