Asynchronous dictionary in Python So I am working on writing a discord bot with discord.py.

I decided, rather than making a serie of if/elif, to map the messages to the functions in a dictionnary, like so:

my_dict = { "!trigger": func }

I then wanted to parse this dictionnary into an async for loop, but ran into some problems. To face those problems, I decided to write a dict() subclass, which I called AsyncDict. I just want to know if this is safe to work like this, or not? The main purpose of this little class is to avoid errors like "an async for loop needs an item that defines the function __aiter__" 

AsyncDict class:

class AsyncDict(dict):
    def __init__(self, *args, **kwargs):
        super(AsyncDict, self).__init__(*args, **kwargs)

    async def items(self):
        items = super().items()
        for item in items:
            yield item

    async def keys(self):
        keys = super().keys()
        for key in keys:
            yield key

    async def values(self):
        values = super().values()
        for value in values:
            yield 


Once this is done, I just create my dictionary "as usual":
calls = AsyncDict([("!ping", ping)])

Here is the relevant code in my main.py:

import discord
import asyncio

async def ping(message):
    await client.send_message(message.channel, 'pong')

calls = AsyncDict([("!ping", ping)])

@client.event
async def on_message(message):
    async for k, v in calls.items():
        if message.content.startswith(k):
            await v(message)


I just want to know if it's "safe" to work like this (cf.: AsyncDict)? I'm quite new to asynchronous development and I don't know if I'm missing something.
I saw your post on python-ideas. I think you have a misconception about native coroutines (i.e. async def). For example, this method in AsyncDict:

async def items(self):
    items = super().items()
    for item in items:
        yield item


This method does not have any await expressions, therefore the method itself should not be async def. It should just be a regular def. You may not realize it, but an async def function can still call regular def functions, and it can use regular with and for blocks.

In your use case, you should use a regular dictionary and a regular for loop:

calls = {"!ping": ping}

@client.event
async def on_message(message):
    for k, v in calls.items():
        if message.content.startswith(k):
            await v(message)


This is perfectly legal, and in fact better than trying to create "Async" variants of common data structures that don't need it.