python / cpython

The Python programming language
https://www.python.org
Other
63.49k stars 30.4k forks source link

No SyntaxError raised for `return` with argument inside generator #77736

Closed 0a897b36-5d8a-438c-baf4-965d1bb0b78b closed 6 years ago

0a897b36-5d8a-438c-baf4-965d1bb0b78b commented 6 years ago
BPO 33555
Nosy @serhiy-storchaka, @FHTMitchell

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields: ```python assignee = None closed_at = created_at = labels = ['interpreter-core', 'invalid', 'type-bug', '3.7'] title = 'No SyntaxError raised for `return` with argument inside generator' updated_at = user = 'https://github.com/FHTMitchell' ``` bugs.python.org fields: ```python activity = actor = 'serhiy.storchaka' assignee = 'none' closed = True closed_date = closer = 'FHTMitchell' components = ['Interpreter Core'] creation = creator = 'FHTMitchell' dependencies = [] files = [] hgrepos = [] issue_num = 33555 keywords = [] message_count = 5.0 messages = ['316912', '316913', '316918', '316919', '316967'] nosy_count = 2.0 nosy_names = ['serhiy.storchaka', 'FHTMitchell'] pr_nums = [] priority = 'normal' resolution = 'not a bug' stage = 'resolved' status = 'closed' superseder = None type = 'behavior' url = 'https://bugs.python.org/issue33555' versions = ['Python 3.6', 'Python 3.7'] ```

0a897b36-5d8a-438c-baf4-965d1bb0b78b commented 6 years ago

In python 2.7 if you run the following code you get an error (as you would expect)

Python 2.7.14 | packaged by conda-forge | (default, Dec 25 2017, 01:17:32) [MSC v.1500 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information.

>>> def f():
...     yield 1
...     return 2
...
  File "<stdin>", line 3
SyntaxError: 'return' with argument inside generator

However, in python 3.6 the error is silently ignored

Python 3.6.4 | packaged by conda-forge | (default, Dec 24 2017, 10:11:43) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> def f():
...     yield 1
...     return 2
...
>>> for i in f():
...     print(i)
...
1

and still is in 3.7

Python 3.7.0b2 (v3.7.0b2:b0ef5c979b, Feb 28 2018, 02:24:20) [MSC v.1912 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> def f():
...     yield 1
...     return 2
...
>>> for i in f():
...     print(i)
...
1

This is a source of confusion

https://stackoverflow.com/questions/47831240/why-is-no-value-returned-from-my-generator/

especially since the PEP says it is disallowed:

https://www.python.org/dev/peps/pep-0255/#then-why-not-allow-an-expression-on-return-too

serhiy-storchaka commented 6 years ago

It is not silently ignored. It is used as an argument to construct StopIteration. See The Python Language Reference:

https://docs.python.org/3/reference/simple_stmts.html#the-return-statement

0a897b36-5d8a-438c-baf4-965d1bb0b78b commented 6 years ago

Apologies if I wasn't clear. I understand that

def f():
    yield 1
    return

is valid python. What I'm saying, if you follow the link, is that

def f():
    yield 1
    return 2  # not the argument

should not be considered valid python according to PEP-255. This is implemented in python 2 but not in python 3.

0a897b36-5d8a-438c-baf4-965d1bb0b78b commented 6 years ago

Whoops I understand. Reclosed.

serhiy-storchaka commented 6 years ago

See also What’s New In Python 3.3:

https://docs.python.org/3/whatsnew/3.3.html#pep-380-syntax-for-delegating-to-a-subgenerator

And PEP-380 itself.