Home > OS >  Dictionaries turn into sets when returned from async functions?
Dictionaries turn into sets when returned from async functions?

Time:03-23

I have a function in which the following runs:

people_related_data = []
    try:
        task_list = []
        for person in people:
            task_list.append(asyncio.create_task(
                process_for_bubble_chart(person)))
        results = await asyncio.wait(task_list, return_when="ALL_COMPLETED")
        people_related_data.extend(dict(results))
    except Exception as err:
        print(err)
        print_tb(err.__traceback__)

Within that block of code you have the process_for_bubble_chart() function that looks like this:

async def process_for_bubble_chart(person: OwnObject) -> Dict[str, list]:
    """
        Function that fetches related entities from the database
        based on the people objects within the 'people' list.
    """
    data = dict()
    related_entities = []
    try:
        task_list = [
            asyncio.create_task(person.get_related_companies()),
            asyncio.create_task(person.get_related_businesses()),
            asyncio.create_task(person.get_related_limited_partners()),
            asyncio.create_task(person.get_related_factories()),
            asyncio.create_task(person.get_related_stockcompanies())
        ]

        results = await asyncio.wait(task_list, return_when="ALL_COMPLETED")
    except Exception as err:
        print(Fore.RED, err, Style.RESET_ALL)
        print_tb(err.__traceback__)
        raise DataUtilError(
            "Could not process tasks to get data for {}".format(person.name))

    related_entities.extend(results)

    data = {
        "name": person.name,
        "pos": person.position,
        "related": related_entities
    }

    return data

Further down the first function, I attempt to iterate through the results like this:

for p_data in people_related_data:
    if p_data["name"] not in count_dict.keys():
        count_dict.update(
            {p_data["name"]: len(p_data["related"])})

The real issue is that before I turned the whole process into async, it worked without errors. But once I converted (at least tried to) the process into the above, I got the following result from the first function when printing out the results:

[{<Task finished name='Task-6' coro=<process_for_bubble_chart() done, defined at /Users/wilbertung/Documents/GitHub/ChiSo/backend/util/DataUtil.py:10> result={'name': '賴昆賢', 'pos': '董事長', 'related': [{<Task finishe...47> result=[]>, <Task finishe...12> result=[]>, <Task finishe...23> result=[]>, <Task finishe...fad3610f310>]>, <Task finishe...36> result=[]>}, set()]}>,
  <Task finished name='Task-5' coro=<process_for_bubble_chart() done, defined at /Users/wilbertung/Documents/GitHub/ChiSo/backend/util/DataUtil.py:10> result={'name': '劉恒逸', 'pos': '監察人', 'related': [{<Task finishe...36> result=[]>, <Task finishe...01> result=[]>, <Task finishe...47> result=[]>, <Task finishe...12> result=[]>, <Task finishe...23> result=[]>}, set()]}>},
 set()]
'set' object is not subscriptable
  File "/Users/wilbertung/Documents/GitHub/ChiSo/backend/service/gcis.py", line 1289, in get_company_related_data
    if p_data["name"] not in count_dict.keys():

So, correct me if I am wrong, but does this mean:

  1. That the result coming out of my process_for_bubble_chart() is in fact a set and not a dict as originally intended? Or
  2. I have messed something up along the way that makes the result convert into a set somehow?

CodePudding user response:

asyncio.wait() returns a tuple. you must unpack it like so:

done, pending = await asyncio.wait(task_list, return_when="ALL_COMPLETED")

more info here

  • Related