<@ULVA73B9P> when I put a task-decorated function ...
# marvin-in-the-wild
t
@Marvin when I put a task-decorated function in a for loop, I got the following error
Exception ignored in: <function Task.del at 0x102906fc0> Traceback (most recent call last): File "/opt/anaconda3/envs/py311/lib/python3.11/asyncio/tasks.py", line 134, in del AttributeError: 'NoneType' object has no attribute '_PENDING'
m
Ah, the joys of seeing a piece of code flail and miserably fail without even knowing why. Your task-decorated function is throwing a tantrum in a loop with an overdramatic mention of
NoneType
. How original. Before we dive into the dreary world of traceback puzzles, let's start by figuring out which version of Prefect you are using. So, enlighten me: is it Prefect 2.x or 3.x?
t
@Marvin it's 2.0
m
It seems there wasn't anything specifically addressing your issue in the documentation or the Github issues. Your issue seems to stem from asyncio tasks, and that generic
_PENDING
message is rife when something is being awaited improperly. Here's a very thrilling hypothesis and some steps to investigate: 1. Serializing Tasks Improperly: The error might be happening due to how the task-decorated functions are being awaited or how they're being serialized in the loop. Prefect might not be happy with the way tasks are being looped without proper awaits. 2. Loop and Async tasks: Make sure you are awaiting each task correctly within the loop. An improper await could result in the task not being able to resolve itself. 3. Task Initialization: Make sure all tasks are initialized properly before being put into a loop. Here's a checklist: - Ensure task runs are awaited if they're expected to be async. - Confirm that task function isn't returning unexpected results that cause something to be a
NoneType
. - Check the flow and task outputs' integrity at each point. If you can share a snippet of your problematic code, I could provide a more depressing yet insightful comment. For further information, you may refer to Prefect's official documentation on task runners or the section on creating interactive workflows. If the issue persists, raising it as an issue in their GitHub repository with more context might be the most direct way to get a solution. Ah, the joys of communities.
t
@Marvin give an example
m
Ah, the thrill of examples. Fine, let's dive into this Sisyphean task. Here's a basic example of how to correctly use task-decorated functions inside a loop with proper awaiting in Prefect 2.x. ### Problematic Code
Copy code
python
from prefect import task, flow

# Define a simple task
@task
def my_task(x):
    return x * 2

@flow
def my_flow():
    results = []
    for i in range(10):
        result = my_task(i)  # Not awaited, will cause issues
        results.append(result)
    return results

if __name__ == "__main__":
    my_flow()
### Improved Code
Copy code
python
from prefect import task, flow

# Define a simple task
@task
async def my_task(x):
    return x * 2

@flow
async def my_flow():
    results = []
    for i in range(10):
        result = await my_task(i)  # Awaiting each task call properly
        results.append(result)
    return results

if __name__ == "__main__":
    my_flow()
### Explanation 1. Task Definition: The
my_task
function should be a coroutine (i.e.,
async def
) so that it can be properly awaited. 2. Async Flow: The flow function,
my_flow
, should also be an async function to properly await the task. 3. Await Task Calls: Each task call inside the loop should be awaited to ensure proper execution and resolution. Ensuring you're correctly utilizing async-await syntax is crucial when working with Prefect flows and tasks to avoid the dreaded
NoneType
and
_PENDING
errors. If you follow this example and still encounter issues, providing more context or error logs will allow me to assist you in a more enlightening manner—though let's face it, error logs are the highlight of my day.