POP Release 19.0.0

We are pleased to release POP 19.0.0. This release separates loop management into it’s own project. Additional tools that are helpful in async applications are added.

pop-loop integration

Previously, you would call hub.pop.loop.create() to initialize an asyncio loop or hub.pop.loop.start(coro) to run a program in a new event loop. The loop would then be available on hub.pop.Loop. This core functionality has not changed, but alternative loops can be used via the pop-loop project.

hub.pop.loop.create() is still an idempotent operation, but under the hood, it calls hub.loop.init.create().

hub.pop.loop.create() and hub.pop.loop.start() now take a loop_plugin parameter for specifying which plugin from the pop-loop project to use. The default loop plugin is “auto”.

The “auto” loop plugin will try to automatically select the best loop available in this order:

  • uvloop if installed
  • trio if installed
  • proactor for windows
  • selector for *nix

New functions


A sleep function using the current loop that doesn’t require an asyncio import

async def my_func(hub):
    await hub.pop.loop.sleep(1)


Run a synchronous function asynchronously in the executor of the active loop plugin.

def my_func(hub, *args, **kwargs):

async def my_other_func(hub):
    await hub.pop.loop.wrap(hub._.my_func, *args, **kwargs)


Pass the return of a function that is unknown to be async or synchronous, if the value is awaitable it will be awaited.

async def my_func(hub, *args, **kwargs):

async def my_other_func(hub, *args, **kwargs):
    ret = hub._.my_func(*args, **kwargs)
    await hub.pop.loop.unwrap(ret)