
This issue trackerhas been migrated toGitHub, and is currentlyread-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.
Created on2015-01-08 14:42 byRosuav, last changed2022-04-11 14:58 byadmin. This issue is nowclosed.
| Files | ||||
|---|---|---|---|---|
| File name | Uploaded | Description | Edit | |
| 0001-lambda-generators-don-t-throw-away-stack-top.patch | bru,2015-03-02 11:16 | Fix lambda generator throwing away sent value | ||
| 0002-lambda-generator-fix-try-to-add-a-dis-test.patch | bru,2015-03-02 11:16 | Failed test tentative | ||
| 0001-Add-tests-for-issue-23192.patch | bru,2015-03-11 12:00 | |||
| Messages (8) | |||
|---|---|---|---|
| msg233662 -(view) | Author: Chris Angelico (Rosuav)* | Date: 2015-01-08 14:42 | |
As yield is an expression, it's legal in a lambda function, which thenmeans you have a generator function. But it's not quite the same asthe equivalent function made with def:$ python3Python 3.5.0a0 (default:1c51f1650c42+, Dec 29 2014, 02:29:06)[GCC 4.7.2] on linuxType "help", "copyright", "credits" or "license" for more information.>>> f=lambda: (yield 5)>>> x=f()>>> next(x)5>>> x.send(123)Traceback (most recent call last): File "<stdin>", line 1, in <module>StopIteration>>> def f(): return (yield 5)...>>> x=f()>>> next(x)5>>> x.send(123)Traceback (most recent call last): File "<stdin>", line 1, in <module>StopIteration: 123>>> x = (lambda: print((yield 1)) or 2)()>>> next(x)1>>> x.send(3)3Traceback (most recent call last): File "<stdin>", line 1, in <module>StopIterationThe last example demonstrates that send() is working, but the return value is not getting propagated. Disassembly shows this:>>> dis.dis(lambda: (yield 5)) 1 0 LOAD_CONST 1 (5) 3 YIELD_VALUE 4 POP_TOP 5 LOAD_CONST 0 (None) 8 RETURN_VALUE>>> def f(): return (yield 5)... >>> dis.dis(f) 1 0 LOAD_CONST 1 (5) 3 YIELD_VALUE 4 RETURN_VALUEI'm sure this is a bug that will affect very approximately zero people, but it's still a peculiar inconsistency!Verified with 3.5 and 3.4. | |||
| msg233668 -(view) | Author: Guido van Rossum (gvanrossum)*![]() | Date: 2015-01-08 15:56 | |
Hm, looks like nobody bothered to update the lambda code generation to use the value from yield. I almost feel like there is some unnecessary check "if we are in a lambda" in the code generation for yield. Have you looked through the code generation yet? | |||
| msg233673 -(view) | Author: Chris Angelico (Rosuav)* | Date: 2015-01-08 17:27 | |
I'm not sure what to look for in the code generation. In compile.c lines 3456 and following, there's a LOAD_CONST None coming through, in the else branch of "if (e->v.Yield.value)", but nothing talking about lambda functions. There are constants COMPILER_SCOPE_LAMBDA and COMPILER_SCOPE_FUNCTION, but the only place where they're used is compiler_set_qualname() and I can't see anything obvious there. Hopefully someone more familiar with the code internals will be able to figure this out! | |||
| msg237041 -(view) | Author: Bruno Cauet (bru)* | Date: 2015-03-02 11:16 | |
Here are the operations being emitted (line, macro used and eventual argument):>>> f = lambda: (yield 5)3487: ADDOP_O LOAD_CONST e->v.Num.n3472: ADDOP YIELD_VALUE1907: ADDOP_IN_SCOPE POP_TOP4349: ADDOP_O LOAD_CONST Py_None4350: ADDOP RETURN_VALUE1457: ADDOP_O LOAD_CONST (PyObject*)co1458: ADDOP_O LOAD_CONST qualname1459: ADDOP_I MAKE_FUNCTION args4349: ADDOP_O LOAD_CONST Py_None4350: ADDOP RETURN_VALUE>>> def g(): return (yield 5)... 3487: ADDOP_O LOAD_CONST e->v.Num.n3472: ADDOP YIELD_VALUE2533: ADDOP RETURN_VALUE1457: ADDOP_O LOAD_CONST (PyObject*)co1458: ADDOP_O LOAD_CONST qualname1459: ADDOP_I MAKE_FUNCTION args4349: ADDOP_O LOAD_CONST Py_None4350: ADDOP RETURN_VALUESo there's an extra POP_TOP + LOAD_CONST Py_NONE for the lambda version that throws away the "123" (in the exemple).The attached patch (0001-...) fixes it. However please note that I'm not knowledgable about that part of the code and devised the patch empirically.Moreover a test should probably added but I did not know where (test_dis? tried and failed... see patch 0002-...). | |||
| msg237804 -(view) | Author: Serhiy Storchaka (serhiy.storchaka)*![]() | Date: 2015-03-10 19:38 | |
Could you please add a test based on Chris's example? And it would be good to add a test for a lambda with "yield from". | |||
| msg237861 -(view) | Author: Bruno Cauet (bru)* | Date: 2015-03-11 12:00 | |
Here is a working test, testing yield by lambda & function as well as lambda and function yielding from those. | |||
| msg237883 -(view) | Author: Roundup Robot (python-dev)![]() | Date: 2015-03-11 16:23 | |
New changeset2b4a04c3681b by Serhiy Storchaka in branch '3.4':Issue#23192: Fixed generator lambdas. Patch by Bruno Cauet.https://hg.python.org/cpython/rev/2b4a04c3681bNew changeseta3b889e9d3f3 by Serhiy Storchaka in branch 'default':Issue#23192: Fixed generator lambdas. Patch by Bruno Cauet.https://hg.python.org/cpython/rev/a3b889e9d3f3 | |||
| msg237884 -(view) | Author: Serhiy Storchaka (serhiy.storchaka)*![]() | Date: 2015-03-11 16:25 | |
Committed with non-dis test. Thank you for your contribution Bruno. | |||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022-04-11 14:58:11 | admin | set | github: 67381 |
| 2015-03-11 16:25:22 | serhiy.storchaka | set | status: open -> closed resolution: fixed messages: +msg237884 stage: test needed -> resolved |
| 2015-03-11 16:23:18 | python-dev | set | nosy: +python-dev messages: +msg237883 |
| 2015-03-11 12:00:52 | bru | set | files: +0001-Add-tests-for-issue-23192.patch messages: +msg237861 |
| 2015-03-10 19:38:55 | serhiy.storchaka | set | assignee:serhiy.storchaka messages: +msg237804 stage: test needed |
| 2015-03-02 11:16:40 | bru | set | files: +0002-lambda-generator-fix-try-to-add-a-dis-test.patch |
| 2015-03-02 11:16:23 | bru | set | files: +0001-lambda-generators-don-t-throw-away-stack-top.patch nosy: +bru messages: +msg237041 keywords: +patch |
| 2015-03-02 08:29:57 | ezio.melotti | set | nosy: +ezio.melotti |
| 2015-01-08 17:27:16 | Rosuav | set | messages: +msg233673 |
| 2015-01-08 16:02:25 | vstinner | set | nosy: +vstinner |
| 2015-01-08 15:56:52 | gvanrossum | set | messages: +msg233668 |
| 2015-01-08 14:52:37 | serhiy.storchaka | set | nosy: +gvanrossum,benjamin.peterson,serhiy.storchaka |
| 2015-01-08 14:42:18 | Rosuav | set | type: behavior |
| 2015-01-08 14:42:05 | Rosuav | create | |