Skip to content

extmod/uasyncio: Provide asyncio.iscoroutine function. #11526

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

Closed

Conversation

andrewleech
Copy link
Contributor

Matches https://docs.python.org/3/library/asyncio-task.html#asyncio.iscoroutine

I've run into needing this function a number of times when using cpython compatible asyncio code, particularly with code that passes (async) functions around like "function pointers" and/or wrapper functions.

When a non-async function is used instead of an async one, the await function() fails with errors like TypeError: 'NoneType' object isn't iterable (assuming function returns None) which can be tricky to track and debug. In these cases I'd like to do an asyncio.iscoroutine(function) earlier to ensure the right function type has been passed in, preferably in a manner that's compatible with cpython.

@github-actions
Copy link

Code size report:

   bare-arm:    +0 +0.000% 
minimal x86:    +0 +0.000% 
   unix x64:  +224 +0.028% standard[incl +96(data)]
      stm32:   +64 +0.016% PYBV10
        rp2:   +64 +0.020% PICO

@andrewleech andrewleech force-pushed the asyncio_iscoroutine branch from 3bce440 to d4904f1 Compare May 17, 2023 00:36
@codecov-commenter
Copy link

codecov-commenter commented May 17, 2023

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 98.39%. Comparing base (6a4a9bc) to head (d4904f1).
Report is 2219 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master   #11526   +/-   ##
=======================================
  Coverage   98.39%   98.39%           
=======================================
  Files         156      156           
  Lines       20609    20609           
=======================================
  Hits        20278    20278           
  Misses        331      331           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@peterhinch
Copy link
Contributor

I don't know if this is any help but I have classes where a passed callback may be either a function or a coroutine. The detection is as follows:

async def _g():
    pass
type_coro = type(_g())

# If a callback is passed, run it and return.
# If a coro is passed initiate it and return.
def launch(func, tup_args):
    res = func(*tup_args)
    if isinstance(res, type_coro):
        res = asyncio.create_task(res)
    return res

@andrewleech
Copy link
Contributor Author

@peterhinch thanks yeah I was testing doing exactly the same thing, unfortunately it's not cpython compatible - there the type() of async functions and regular functions are the same!

That being said, this type() based method does work for implementing iscoroutine on micropython, I just thought it was cleaner to re-use the existing hasattr method used in uasyncio, even if it's less exact than actually checking the type.

@stephanelsmith
Copy link
Contributor

Would be a good addition. I've run into this as well, and use Peter's method. I strive for interoperability with python code, having same modules running on server and embedded. Anything along that path, especially implementing an existing standard method, sounds good to me.

@dpgeorge dpgeorge added the extmod Relates to extmod/ directory in source label May 19, 2023
@smurfix
Copy link
Contributor

smurfix commented Apr 11, 2025

There's inspect.iscoroutine in the library. Would that not do what you're proposing here?

@peterhinch
Copy link
Contributor

There's inspect.iscoroutine in the library.

? I can't find it in the inspect source.

@smurfix
Copy link
Contributor

smurfix commented Apr 12, 2025

Ugh, sorry, you're right, that was my own copy with

iscoroutinefunction = isgeneratorfunction
iscoroutine = isgenerator

added. Seems I forgot to create a PR for that.

@andrewleech
Copy link
Contributor Author

@smurfix fwiw I would certainly support a PR for that though, I'd be quite happy to have this as an optional install via mip as part of the inspect library.

@smurfix
Copy link
Contributor

smurfix commented Apr 13, 2025

I added a comment to that effect to micropython/micropython-lib#998 and will create a separate PR if that's merged without these two lines.

@andrewleech
Copy link
Contributor Author

Closed in favour of micropython/micropython-lib#998 thanks @smurfix !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
extmod Relates to extmod/ directory in source
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants