Search code examples
typeerrorpytestfinalizerfixture

Pytest fixture finalizer TypeError 'NoneType' object is not callable


I have a simple pytest fixture to ensure that the test data file is present (and deleted at the end of the test), but if gives me the error described in the title.

@pytest.fixture
def ensure_test_data_file(request):
    data_file = server.DATA_FILE_NAME
    with open(data_file, 'w') as text_file:
        text_file.write(json.dumps(TEST_DATA))
        text_file.close()

    print(os.path.abspath(data_file))

    request.addfinalizer(os.remove(data_file))

If I remove the finalizer, it works (except that the file is not deleted). Am I doing something wrong?


Solution

  • You need to pass a function object to request.addfinalizer - what you're doing is actually calling os.remove(data_file), which returns None, and thus you're doing request.addfinalizer(None).

    Here you'd use request.addfinalizer(lambda: os.remove(data_file)) or request.addfinalizer(functools.partial(os.remove, data_file)) to get a callable with the argument already "applied", but which isn't actually called.

    However, I'd recommend using yield in the fixture instead (docs), which makes this much cleaner by letting you "pause" your fixture and run the test in between:

    @pytest.fixture
    def ensure_test_data_file(request):
        data_file = server.DATA_FILE_NAME
        with open(data_file, 'w') as text_file:
            text_file.write(json.dumps(TEST_DATA))
            text_file.close()
    
        print(os.path.abspath(data_file))
    
        yield
    
        os.remove(data_file)