classification
Title: Add __qualname__ attribute to Python generators and change default __name__
Type: enhancement Stage:
Components: asyncio Versions: Python 3.5
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: SzieberthAdam, gvanrossum, haypo, pitrou, python-dev, r.david.murray, yselivanov
Priority: normal Keywords: patch

Created on 2014-04-12 11:14 by SzieberthAdam, last changed 2014-06-16 14:28 by haypo. This issue is now closed.

Files
File name Uploaded Description Edit
gen_qualname.patch haypo, 2014-06-11 14:18
gen_qualname-2.patch haypo, 2014-06-12 21:45 review
gen_qualname-3.patch haypo, 2014-06-13 08:03 review
Messages (14)
msg215968 - (view) Author: Szieberth Ádám (SzieberthAdam) Date: 2014-04-12 11:14
I faced this particular issue by writing decorators for asyncio coroutines. 

I even posted a question to SO: http://stackoverflow.com/questions/23015626/how-to-decorate-an-asyncio-coroutine-to-retain-its-name

However, since that I realized the problem is more general. I believe that a generator object should inherit its function's __name__ attribute instead of ignoring it. Example:


################################################################
import functools

def decorated(genfunc):
    @functools.wraps(genfunc)
    def wrapper(*args, **kargs):
        print('inside wrapper')
        for x in genfunc(*args, **kargs):
            yield 'decorated: {!r}'.format(x)
    print('outside wrapper')
    print('wrapper.__name__: {!r}'.format(wrapper.__name__))
    return wrapper

@decorated
def simple_genfunc():
    """Testdoc."""
    yield from range(10)

if __name__ == '__main__':
    print('simple_genfunc.__name__: {!r}'.format(
        simple_genfunc.__name__))
    print('simple_genfunc().__name__: {!r}'.format(
        simple_genfunc().__name__))
################################################################

And its result:

Z:\>python -i genfuncdec.py
outside wrapper
wrapper.__name__: 'simple_genfunc'
simple_genfunc.__name__: 'simple_genfunc'
simple_genfunc().__name__: 'wrapper'
>>> simple_genfunc
<function simple_genfunc at 0x00C30420>
>>> simple_genfunc.__wrapped__
<function simple_genfunc at 0x00C304B0>
>>> simple_genfunc()
<generator object wrapper at 0x00C0EE18>
>>> simple_genfunc.__wrapped__()
<generator object simple_genfunc at 0x00C0ED28>

As you can see the generator object's __name__ remained the hardcoded one.
msg215995 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2014-04-13 04:15
I think this is a specific case of a more general need to improve 'wraps' that was discussed on python-dev not too long ago.
msg220273 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2014-06-11 14:18
gen_qualname.patch: add a new "__qualname__" attribute to generators and change how the name is set: use the name of the function, instead of using the name of the code.

Incompatible changes of this patch:

- repr(generator) now shows the qualified name instead of the name
- generator name comes from the function name which may be different

If the function has a name different than the code (if the function name was changed, for example by @functools.wraps), the generator now gets the name from the function, no more from the code object. IMO it's the expected behaviour, and it's more useful.

I'm writing on email to python-dev to discuss these changes.
msg220337 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2014-06-12 09:41
Discussion on python-dev:
https://mail.python.org/pipermail/python-dev/2014-June/135026.html
msg220369 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2014-06-12 16:44
@Antoine: Can you please review gen_qualname.patch?
msg220385 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2014-06-12 21:22
Your patch doesn't have a "review" link. Perhaps it should be regenerated against updated default?
msg220389 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2014-06-12 21:45
Updated patch, rebased on the default branch. I add a minor unit test (modify also gen.__name__).
msg220424 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2014-06-13 08:03
Updated patch: names must now be strings and cannot be deleted; make _PyEval_EvalCodeWithName private.
msg220720 - (view) Author: Roundup Robot (python-dev) Date: 2014-06-16 14:00
New changeset aa85e8d729ae by Victor Stinner in branch 'default':
Issue #21205: Add a new ``__qualname__`` attribute to generator, the qualified
http://hg.python.org/cpython/rev/aa85e8d729ae
msg220722 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2014-06-16 14:20
Ok, this issue is now fixed in Python 3.5.

For Python 2.7 and 3.4, it may be possible to change how the generator name is set (from the function, not from the code object). It might break the backward compatibility, even if I don't think that anyone rely on the exact name of the generator, and the function name is more useful than the code name.

What do you think for Python 2.7 and 3.4: would you be ok to change also the generator name? I can write a patch which adds a new gi_name but the name would not be modifiable to limit the incompatible changes.
msg220723 - (view) Author: Roundup Robot (python-dev) Date: 2014-06-16 14:24
New changeset 901a8265511a by Victor Stinner in branch 'default':
Issue #21205: Fix unit tests
http://hg.python.org/cpython/rev/901a8265511a
msg220724 - (view) Author: Roundup Robot (python-dev) Date: 2014-06-16 14:25
New changeset 28b3b8b22654 by Victor Stinner in branch 'default':
Issue #21205: Complete the "versionchanged" note in inspect documentation
http://hg.python.org/cpython/rev/28b3b8b22654
msg220725 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2014-06-16 14:26
Le 16/06/2014 10:20, STINNER Victor a écrit :
>
> What do you think for Python 2.7 and 3.4: would you be ok to change
also the generator name? I can write a patch which adds a new gi_name
but the name would not be modifiable to limit the incompatible changes.

I don't think it is worthwhile.
msg220726 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2014-06-16 14:28
Antoine Pitrou wrote:
> I don't think it is worthwhile.

Ok, let's keep the issue closed then ;-)

Thanks for the review Antoine.
History
Date User Action Args
2014-06-16 14:28:24hayposetmessages: + msg220726
2014-06-16 14:26:48pitrousetmessages: + msg220725
2014-06-16 14:25:35python-devsetmessages: + msg220724
2014-06-16 14:24:12python-devsetmessages: + msg220723
2014-06-16 14:20:06hayposetstatus: open -> closed
resolution: fixed
messages: + msg220722
2014-06-16 14:00:17python-devsetnosy: + python-dev
messages: + msg220720
2014-06-13 08:03:47hayposetfiles: + gen_qualname-3.patch

messages: + msg220424
2014-06-12 21:45:12hayposetfiles: + gen_qualname-2.patch

messages: + msg220389
2014-06-12 21:22:15pitrousetmessages: + msg220385
2014-06-12 16:44:43hayposetmessages: + msg220369
2014-06-12 09:41:50hayposetmessages: + msg220337
2014-06-11 16:13:28hayposetnosy: + pitrou
2014-06-11 14:39:18hayposettitle: Add a name to Python generators -> Add __qualname__ attribute to Python generators and change default __name__
2014-06-11 14:19:00hayposetfiles: + gen_qualname.patch
keywords: + patch
messages: + msg220273

title: Unable to make decorated generator object to inherit generator function's __name__ -> Add a name to Python generators
2014-06-06 11:42:22hayposetnosy: + yselivanov, haypo, gvanrossum
components: + asyncio
2014-04-13 04:15:23r.david.murraysetnosy: + r.david.murray

messages: + msg215995
versions: + Python 3.5, - Python 3.4
2014-04-12 11:14:07SzieberthAdamcreate