[syntax-errors] Allow yield in base classes and annotations (#17206)

Summary
--

This PR fixes the issue pointed out by @JelleZijlstra in
https://github.com/astral-sh/ruff/pull/17101#issuecomment-2777480204.
Namely, I conflated two very different errors from CPython:

```pycon
>>> def m[T](x: (yield from 1)): ...
  File "<python-input-310>", line 1
    def m[T](x: (yield from 1)): ...
                 ^^^^^^^^^^^^
SyntaxError: yield expression cannot be used within the definition of a generic
>>> def m(x: (yield from 1)): ...
  File "<python-input-311>", line 1
    def m(x: (yield from 1)): ...
              ^^^^^^^^^^^^
SyntaxError: 'yield from' outside function
>>> def outer():
...     def m(x: (yield from 1)): ...
...
>>>
```

I thought the second error was the same as the first, but `yield` (and
`yield from`) is actually valid in this position when inside a function
scope. The same is true for base classes, as pointed out in the original
comment.

We don't currently raise an error for `yield` outside of a function, but
that should be handled separately.

On the upside, this had the benefit of removing the
`InvalidExpressionPosition::BaseClass` variant and the
`allow_named_expr` field from the visitor because they were both no
longer used.

Test Plan
--

Updated inline tests.
This commit is contained in:
Brent Westbrook 2025-04-04 13:48:28 -04:00 committed by GitHub
parent 33a56f198b
commit acc5662e8b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 1081 additions and 686 deletions

View file

@ -1,6 +1,4 @@
class F[T](y := list): ...
class G((yield 1)): ...
class H((yield from 1)): ...
class I[T]((yield 1)): ...
class J[T]((yield from 1)): ...
class K[T: (yield 1)]: ... # yield in TypeVar

View file

@ -1,13 +1,9 @@
def f[T]() -> (y := 3): ...
def g[T](arg: (x := 1)): ...
def h[T](x: (yield 1)): ...
def i(x: (yield 1)): ...
def j[T]() -> (yield 1): ...
def k() -> (yield 1): ...
def l[T](x: (yield from 1)): ...
def m(x: (yield from 1)): ...
def n[T]() -> (yield from 1): ...
def o() -> (yield from 1): ...
def p[T: (yield 1)](): ... # yield in TypeVar bound
def q[T = (yield 1)](): ... # yield in TypeVar default
def r[*Ts = (yield 1)](): ... # yield in TypeVarTuple default

View file

@ -0,0 +1,8 @@
# parse_options: {"target-version": "3.14"}
def f() -> (y := 3): ...
def g(arg: (x := 1)): ...
def outer():
def i(x: (yield 1)): ...
def k() -> (yield 1): ...
def m(x: (yield from 1)): ...
def o() -> (yield from 1): ...