allegroai / clearml

ClearML - Auto-Magical CI/CD to streamline your AI workload. Experiment Management, Data Management, Pipeline, Orchestration, Scheduling & Serving in one MLOps/LLMOps solution
https://clear.ml/docs
Apache License 2.0
5.69k stars 655 forks source link

Task.init causes "I/O operation on closed file" on pytest #989

Closed gabrieleballetti closed 1 year ago

gabrieleballetti commented 1 year ago

Describe the bug

We test our ClearML integration with pytest. Under certain circumstances pytest raises an exception ValueError: I/O operation on closed file on a test where Task.init() gets called. I suppose that some resources are not disposed correctly, but I struggle going through the pytest code and I haven't found a way around it beside disabling ClearML for that test, which I really would like to avoid.

To reproduce

Below the content of test.py.

from typer.testing import CliRunner
from clearml import Task
import tensorflow

runner = CliRunner()

app = typer.Typer()

@app.command()
def main():
    Task.init()

def test_task():
    runner.invoke(app)

Then run pytest test.py. This runs test_task() which invokes (through typer) the main function. Surprisingly, that import of tensorflow is needed to make it crash!

Environment

gabrieleballetti commented 1 year ago

It turns out that this issue is probably caused by some bad interactions between pytest and the click.testing module (typer.testing is build on top of that). From the CliRunner docs:

This only works in single-threaded systems without any concurrency as it changes the global interpreter state.

The fact that clearml spins new threads, together with some poor handling from pytest and some not completely understood interaction with tensorflow seems to cause the issue. I solved by parsing manually cl arguments and calling the command function manually instead.

Might be that something could be done on the clearml side, but I consider this closed.