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

AssertionError on await of Future returned by asyncio.wrap_future #77419

Closed
jhaydaman mannequin opened this issue Apr 6, 2018 · 4 comments
Closed

AssertionError on await of Future returned by asyncio.wrap_future #77419

jhaydaman mannequin opened this issue Apr 6, 2018 · 4 comments
Labels
3.8 (EOL) end of life stdlib Python modules in the Lib dir topic-asyncio

Comments

@jhaydaman
Copy link
Mannequin

jhaydaman mannequin commented Apr 6, 2018

BPO 33238
Nosy @asvetlov, @1st1, @jhaydaman
PRs
  • bpo-33238: Add InvalidStateError to concurrent.futures. #7056
  • 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 2018-05-30.17:53:49.619>
    created_at = <Date 2018-04-06.18:02:45.599>
    labels = ['3.8', 'library', 'expert-asyncio']
    title = 'AssertionError on await of Future returned by asyncio.wrap_future'
    updated_at = <Date 2018-05-30.17:53:49.619>
    user = 'https://github.com/jhaydaman'

    bugs.python.org fields:

    activity = <Date 2018-05-30.17:53:49.619>
    actor = 'asvetlov'
    assignee = 'none'
    closed = True
    closed_date = <Date 2018-05-30.17:53:49.619>
    closer = 'asvetlov'
    components = ['Library (Lib)', 'asyncio']
    creation = <Date 2018-04-06.18:02:45.599>
    creator = 'jhaydaman'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 33238
    keywords = ['patch']
    message_count = 4.0
    messages = ['315030', '315031', '317224', '318157']
    nosy_count = 3.0
    nosy_names = ['asvetlov', 'yselivanov', 'jhaydaman']
    pr_nums = ['7056']
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = None
    url = 'https://bugs.python.org/issue33238'
    versions = ['Python 3.8']

    @jhaydaman
    Copy link
    Mannequin Author

    jhaydaman mannequin commented Apr 6, 2018

    When the concurrent Future wrapped by asyncio.wrap_future has set_result or set_exception called multiple times, I get the following traceback:

    Traceback (most recent call last):
      File "/usr/local/lib/python3.6/asyncio/events.py", line 145, in _run
        self._callback(*self._args)
      File "/usr/local/lib/python3.6/asyncio/futures.py", line 399, in _set_state
        _copy_future_state(other, future)
      File "/usr/local/lib/python3.6/asyncio/futures.py", line 369, in _copy_future_state
        assert not dest.done()
    AssertionError

    Minimal reproducible example:

    import asyncio
    import concurrent.futures
    
    f = concurrent.futures.Future()
    async_f = asyncio.wrap_future(f)
    f.set_result(1)
    f.set_result(1)
    
    loop = asyncio.get_event_loop()
    loop.run_until_complete(async_f)

    The documentation says that set_result and set_exception are only meant for Executors, so, arguably using them outside of that context would fall into undocumented behavior rather than a bug. But it still seems like it should be the second set_result that raises something like InvalidStateError. Alternatively, this can be avoided if _copy_future_state checks for done in addition to cancellation. What should happen here?

    @jhaydaman jhaydaman mannequin added stdlib Python modules in the Lib dir topic-asyncio labels Apr 6, 2018
    @jhaydaman
    Copy link
    Mannequin Author

    jhaydaman mannequin commented Apr 6, 2018

    May also be worth pointing out that even in the case of only calling set_result once, _done_callbacks still has _chain_future in it:

    import asyncio
    import concurrent.futures
    
    
    f = concurrent.futures.Future()
    async_f = asyncio.wrap_future(f)
    
    f.set_result(1)
    loop = asyncio.get_event_loop()
    print(loop.run_until_complete(async_f))
    print(f._done_callbacks)

    >> 1
    >> [<function _chain_future.<locals>._call_set_state at 0x7f1687f3c620>]

    Should that be cleared by that point?

    @asvetlov
    Copy link
    Contributor

    Raising InvalidStateError sounds perfect.

    Would you make a pull request?

    @asvetlov asvetlov added the 3.8 (EOL) end of life label May 21, 2018
    @asvetlov
    Copy link
    Contributor

    New changeset 0a28c0d by Andrew Svetlov (jhaydaman) in branch 'master':
    bpo-33238: Add InvalidStateError to concurrent.futures. (GH-7056)
    0a28c0d

    @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 (EOL) end of life stdlib Python modules in the Lib dir topic-asyncio
    Projects
    None yet
    Development

    No branches or pull requests

    1 participant