great-river-11779
07/05/2023, 11:13 PMflat-zoo-31952
07/05/2023, 11:22 PMgreat-river-11779
07/05/2023, 11:35 PMgreat-river-11779
07/05/2023, 11:35 PMenough-analyst-54434
07/05/2023, 11:45 PMenough-analyst-54434
07/05/2023, 11:47 PMgreat-river-11779
07/06/2023, 12:57 AMenough-analyst-54434
07/06/2023, 1:01 AMenough-analyst-54434
07/06/2023, 1:03 AMgreat-river-11779
07/06/2023, 1:12 AMgreat-river-11779
07/06/2023, 1:17 AMpants run
which will figure out that the function is an async function, perhaps similar to how my pants test
seems to just run async functions with pytestgreat-river-11779
07/06/2023, 1:17 AMbroad-processor-92400
07/06/2023, 3:51 AMpants test
, that'll be pytest doing magic, potentially via a plugin like pytest-asyncio
. Pants is effectively just running pytest path/to/file.py
(plus extra args)great-river-11779
07/06/2023, 4:31 AMpants test
and I happen to know its pytest doing it. what's to say when you go pants run there isn't something behind it? I think its a reasonable assumptionflat-zoo-31952
07/06/2023, 12:59 PMpython -m path.to.module
, Python just synchronously runs path.to.module
with its name set to __main__
... the if __name__ == "__main__": ...
convention is used to detect this case so you can distinguish between when your module is used as an entry point and when its just being loaded for use by another module.
Many tools in the Python ecosystem take this further by using an entry point syntax, path.to.module:callable_object
which will essentially create a small wrapper script around your code that will invoke that callable object on startup. This is necessarily synchronous, because Python is synchronous by default. You would always have to setup and launch your async loop in that entry point function, with e.g. asyncio.run(async_main())
or something.
In the case of pytest, it's Pytest that has its own (synchronous) entry point that invokes your async tests. There isn't really any magic there, it's just a framework for calling your code. You could do this with pants run
if your pex_binary pointed at some framework that new how to run an async function, for example how a framework like uvicorn
can run an ASGI app. But this is the point here. There's no async magic in Pants or Pex. It's the underlying frameworks that know how to launch async functions from (default) sync Python code.