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

builtins.help function is not much help with async functions #80226

Closed
rotu mannequin opened this issue Feb 19, 2019 · 5 comments
Closed

builtins.help function is not much help with async functions #80226

rotu mannequin opened this issue Feb 19, 2019 · 5 comments
Labels
3.8 only security fixes easy topic-asyncio type-feature A feature request or enhancement

Comments

@rotu
Copy link
Mannequin

rotu mannequin commented Feb 19, 2019

BPO 36045
Nosy @rhettinger, @asvetlov, @1st1, @eamanu, @miss-islington, @rotu
PRs
  • bpo-36045: builtins.help() now prefixes async for async functions #12010
  • 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 2019-05-24.11:38:46.186>
    created_at = <Date 2019-02-19.23:36:27.160>
    labels = ['easy', 'type-feature', '3.8', 'expert-asyncio']
    title = 'builtins.help function is not much help with async functions'
    updated_at = <Date 2019-05-24.11:38:46.185>
    user = 'https://github.com/rotu'

    bugs.python.org fields:

    activity = <Date 2019-05-24.11:38:46.185>
    actor = 'asvetlov'
    assignee = 'none'
    closed = True
    closed_date = <Date 2019-05-24.11:38:46.186>
    closer = 'asvetlov'
    components = ['asyncio']
    creation = <Date 2019-02-19.23:36:27.160>
    creator = 'Dan Rose'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 36045
    keywords = ['patch', 'easy']
    message_count = 5.0
    messages = ['336025', '336027', '336046', '336047', '343376']
    nosy_count = 6.0
    nosy_names = ['rhettinger', 'asvetlov', 'yselivanov', 'eamanu', 'miss-islington', 'Dan Rose']
    pr_nums = ['12010']
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'enhancement'
    url = 'https://bugs.python.org/issue36045'
    versions = ['Python 3.8']

    @rotu
    Copy link
    Mannequin Author

    rotu mannequin commented Feb 19, 2019

    It is very important when using a callable to know whether it is async or not. It is expected that builtins.help function should provide the information needed to properly use the function, but it omits whether it is an async function or not.

    import asyncio
    
    def the_answer():
    	return 42
    
    async def the_answer2():
    	await asyncio.sleep(100)
    	return the_answer()
    
    >>> help(the_answer)
    Help on function the_answer in module __main__:
    
    the_answer()
    
    >>> help(the_answer2)
    Help on function the_answer2 in module __main__:
    
    the_answer2()
    

    Note there is no way to tell whether the result of the function needs to be awaited.

    In the similar case of generator functions versus regular functions, one obvious solution is to add a type annotation. That doesn't work here, since PEP-0484 indicates that the correct annotation for a coroutine function is the type that is awaited, not the coroutine object created when the function is called.

    import typing
    def non_answers() -> typing.Iterable[int]:
        yield from range(42)
    
    >>> help(non_answers)
    Help on function non_answers in module __main__:
    
    non_answers() -> Iterable[int]
    

    One awkward workaround is to wrap the coroutine function in a regular function:

    def the_answer3() -> typing.Awaitable[int]:
        return the_answer2()
    
    >>> help(the_answer3)
    Help on function the_answer3 in module __main__:
    
    the_answer3() -> Awaitable[int]
    

    @rotu rotu mannequin added 3.7 (EOL) end of life topic-asyncio labels Feb 19, 2019
    @rotu rotu mannequin changed the title Help function is not much help with async functions builtins.help function is not much help with async functions Feb 19, 2019
    @rhettinger
    Copy link
    Contributor

    This would be a reasonable addition to help(). Would you like to make a PR?

    An "async def" can be detected with inspect.iscoroutinefunction(the_answer2).

    @rhettinger rhettinger added easy 3.8 only security fixes type-feature A feature request or enhancement and removed 3.7 (EOL) end of life labels Feb 19, 2019
    @rotu
    Copy link
    Mannequin Author

    rotu mannequin commented Feb 20, 2019

    Thanks for the suggestion, Raymond. I was toying with the idea of a PR, but wasn’t sure what the resolution should be, and it’s a rather subtle decision for my first contribution.

    It seems to me that this might be an oversight in PEP-0484, and the purest resolution is that either Generator and Coroutine should both be part of the type signature or neither should be.

    If the PEP is indeed correct, the help output *could* look like:

    async the_answer2() -> int

    Which would be equivalent to the (functionally identical) wrapper:

    the_answer3() -> Awaitable[int]

    Philosophically, does asyncness belong on the left or right of the arrow? Should it change just because of how the function is expressed?

    @rotu
    Copy link
    Mannequin Author

    rotu mannequin commented Feb 20, 2019

    Note to future self: whatever solution should also play nice with functools.partial

    @miss-islington
    Copy link
    Contributor

    New changeset 2a37f8f by Miss Islington (bot) (Dan Rose) in branch 'master':
    bpo-36045: builtins.help() now prefixes async for async functions (GH-12010)
    2a37f8f

    @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
    3.8 only security fixes easy topic-asyncio type-feature A feature request or enhancement
    Projects
    None yet
    Development

    No branches or pull requests

    3 participants