Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge maintenance/3.0.x into main following 3.0.1 release #2323

Merged
merged 6 commits into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,24 @@ Release date: TBA



What's New in astroid 3.0.1?
What's New in astroid 3.0.2?
============================
Release date: TBA



What's New in astroid 3.0.1?
============================
Release date: 2023-10-15

* Fix crashes linting code using PEP 695 (Python 3.12) generic type syntax.

Closes pylint-dev/pylint#9098


What's New in astroid 3.0.0?
=============================
Release date: 2023-09-25
Release date: 2023-09-26

* Add support for Python 3.12, including PEP 695 type parameter syntax.

Expand Down
15 changes: 15 additions & 0 deletions astroid/nodes/node_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3405,6 +3405,11 @@ def _infer(
) -> Iterator[ParamSpec]:
yield self

assigned_stmts = protocols.generic_type_assigned_stmts
"""Returns the assigned statement (non inferred) according to the assignment type.
See astroid/protocols.py for actual implementation.
"""


class Pass(_base_nodes.NoChildrenNode, _base_nodes.Statement):
"""Class representing an :class:`ast.Pass` node.
Expand Down Expand Up @@ -4153,6 +4158,11 @@ def _infer(
) -> Iterator[TypeVar]:
yield self

assigned_stmts = protocols.generic_type_assigned_stmts
"""Returns the assigned statement (non inferred) according to the assignment type.
See astroid/protocols.py for actual implementation.
"""


class TypeVarTuple(_base_nodes.AssignTypeNode):
"""Class representing a :class:`ast.TypeVarTuple` node.
Expand Down Expand Up @@ -4192,6 +4202,11 @@ def _infer(
) -> Iterator[TypeVarTuple]:
yield self

assigned_stmts = protocols.generic_type_assigned_stmts
"""Returns the assigned statement (non inferred) according to the assignment type.
See astroid/protocols.py for actual implementation.
"""


UNARY_OP_METHOD = {
"+": "__pos__",
Expand Down
14 changes: 14 additions & 0 deletions astroid/protocols.py
Original file line number Diff line number Diff line change
Expand Up @@ -915,3 +915,17 @@ def match_as_assigned_stmts(
and self.pattern is None
):
yield self.parent.parent.subject


@decorators.yes_if_nothing_inferred
def generic_type_assigned_stmts(
self: nodes.TypeVar | nodes.TypeVarTuple | nodes.ParamSpec,
node: nodes.AssignName,
context: InferenceContext | None = None,
assign_path: None = None,
) -> Generator[nodes.NodeNG, None, None]:
"""Return empty generator (return -> raises StopIteration) so inferred value
is Uninferable.
"""
return
yield
2 changes: 2 additions & 0 deletions doc/release.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ Check the commit and then push to a release branch
appropriate changelog in the description. This triggers the PyPI release.
- Delete the `maintenance/X.Y-1.x` branch. (For example: `maintenance/2.3.x`)
- Create a `maintenance/X.Y.x` (For example: `maintenance/2.4.x` from the `v2.4.0` tag.)
based on the tag from the release. The maintenance branch are protected you won't be
able to fix it after the fact if you create it from main.

## Backporting a fix from `main` to the maintenance branch

Expand Down
29 changes: 28 additions & 1 deletion tests/test_protocols.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

import astroid
from astroid import extract_node, nodes
from astroid.const import PY310_PLUS
from astroid.const import PY310_PLUS, PY312_PLUS
from astroid.exceptions import InferenceError
from astroid.manager import AstroidManager
from astroid.util import Uninferable, UninferableBase
Expand Down Expand Up @@ -415,3 +415,30 @@ def test_assigned_stmts_match_as():
assert match_as.name
assigned_match_as = next(match_as.name.assigned_stmts())
assert assigned_match_as == subject


@pytest.mark.skipif(not PY312_PLUS, reason="Generic typing syntax requires python 3.12")
class TestGenericTypeSyntax:
@staticmethod
def test_assigned_stmts_type_var():
"""The result is 'Uninferable' and no exception is raised."""
assign_stmts = extract_node("type Point[T] = tuple[float, float]")
type_var: nodes.TypeVar = assign_stmts.type_params[0]
assigned = next(type_var.name.assigned_stmts())
assert assigned is Uninferable

@staticmethod
def test_assigned_stmts_type_var_tuple():
"""The result is 'Uninferable' and no exception is raised."""
assign_stmts = extract_node("type Alias[*Ts] = tuple[*Ts]")
type_var_tuple: nodes.TypeVarTuple = assign_stmts.type_params[0]
assigned = next(type_var_tuple.name.assigned_stmts())
assert assigned is Uninferable

@staticmethod
def test_assigned_stmts_param_spec():
"""The result is 'Uninferable' and no exception is raised."""
assign_stmts = extract_node("type Alias[**P] = Callable[P, int]")
param_spec: nodes.ParamSpec = assign_stmts.type_params[0]
assigned = next(param_spec.name.assigned_stmts())
assert assigned is Uninferable