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

Add __qualname__ attribute to Python generators and change default __name__ #65404

Closed
SzieberthAdam mannequin opened this issue Apr 12, 2014 · 14 comments
Closed

Add __qualname__ attribute to Python generators and change default __name__ #65404

SzieberthAdam mannequin opened this issue Apr 12, 2014 · 14 comments
Labels
topic-asyncio type-feature A feature request or enhancement

Comments

@SzieberthAdam
Copy link
Mannequin

SzieberthAdam mannequin commented Apr 12, 2014

BPO 21205
Nosy @gvanrossum, @pitrou, @vstinner, @bitdancer, @1st1
Files
  • gen_qualname.patch
  • gen_qualname-2.patch
  • gen_qualname-3.patch
  • 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:

    assignee = None
    closed_at = <Date 2014-06-16.14:20:06.745>
    created_at = <Date 2014-04-12.11:14:07.640>
    labels = ['type-feature', 'expert-asyncio']
    title = 'Add __qualname__ attribute to Python generators and change default __name__'
    updated_at = <Date 2014-06-16.14:28:24.641>
    user = 'https://bugs.python.org/SzieberthAdam'

    bugs.python.org fields:

    activity = <Date 2014-06-16.14:28:24.641>
    actor = 'vstinner'
    assignee = 'none'
    closed = True
    closed_date = <Date 2014-06-16.14:20:06.745>
    closer = 'vstinner'
    components = ['asyncio']
    creation = <Date 2014-04-12.11:14:07.640>
    creator = 'SzieberthAdam'
    dependencies = []
    files = ['35571', '35603', '35611']
    hgrepos = []
    issue_num = 21205
    keywords = ['patch']
    message_count = 14.0
    messages = ['215968', '215995', '220273', '220337', '220369', '220385', '220389', '220424', '220720', '220722', '220723', '220724', '220725', '220726']
    nosy_count = 7.0
    nosy_names = ['gvanrossum', 'pitrou', 'vstinner', 'r.david.murray', 'python-dev', 'yselivanov', 'SzieberthAdam']
    pr_nums = []
    priority = 'normal'
    resolution = 'fixed'
    stage = None
    status = 'closed'
    superseder = None
    type = 'enhancement'
    url = 'https://bugs.python.org/issue21205'
    versions = ['Python 3.5']

    @SzieberthAdam
    Copy link
    Mannequin Author

    SzieberthAdam mannequin commented Apr 12, 2014

    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.

    @SzieberthAdam SzieberthAdam mannequin added the type-feature A feature request or enhancement label Apr 12, 2014
    @bitdancer
    Copy link
    Member

    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.

    @vstinner
    Copy link
    Member

    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.

    @vstinner vstinner changed the title Unable to make decorated generator object to inherit generator function's __name__ Add a name to Python generators Jun 11, 2014
    @vstinner vstinner changed the title Add a name to Python generators Add __qualname__ attribute to Python generators and change default __name__ Jun 11, 2014
    @vstinner
    Copy link
    Member

    @vstinner
    Copy link
    Member

    @antoine: Can you please review gen_qualname.patch?

    @pitrou
    Copy link
    Member

    pitrou commented Jun 12, 2014

    Your patch doesn't have a "review" link. Perhaps it should be regenerated against updated default?

    @vstinner
    Copy link
    Member

    Updated patch, rebased on the default branch. I add a minor unit test (modify also gen.__name__).

    @vstinner
    Copy link
    Member

    Updated patch: names must now be strings and cannot be deleted; make _PyEval_EvalCodeWithName private.

    @python-dev
    Copy link
    Mannequin

    python-dev mannequin commented Jun 16, 2014

    New changeset aa85e8d729ae by Victor Stinner in branch 'default':
    Issue bpo-21205: Add a new __qualname__ attribute to generator, the qualified
    http://hg.python.org/cpython/rev/aa85e8d729ae

    @vstinner
    Copy link
    Member

    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.

    @python-dev
    Copy link
    Mannequin

    python-dev mannequin commented Jun 16, 2014

    New changeset 901a8265511a by Victor Stinner in branch 'default':
    Issue bpo-21205: Fix unit tests
    http://hg.python.org/cpython/rev/901a8265511a

    @python-dev
    Copy link
    Mannequin

    python-dev mannequin commented Jun 16, 2014

    New changeset 28b3b8b22654 by Victor Stinner in branch 'default':
    Issue bpo-21205: Complete the "versionchanged" note in inspect documentation
    http://hg.python.org/cpython/rev/28b3b8b22654

    @pitrou
    Copy link
    Member

    pitrou commented Jun 16, 2014

    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.

    @vstinner
    Copy link
    Member

    Antoine Pitrou wrote:

    I don't think it is worthwhile.

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

    Thanks for the review Antoine.

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    topic-asyncio type-feature A feature request or enhancement
    Projects
    None yet
    Development

    No branches or pull requests

    3 participants