You can use tempfiles and (on OSX) use the private API of ctypes to dlclose to close the handle. Different call on Windows I think. Something like
import _ctypes
import shutil
import tempfile
@pytest.fixture
def libfact():
tmp = tempfile.NamedTemporaryFile(delete=True)
shutil.copy2("./fact.so", tmp.name)
lib = CDLL(tmp.name)
yield lib
_ctypes.dlclose(lib.handle)
EDIT: fixed error mentioned in reply.Did you mean to have the `tmp.name` as the library passed into `CDDL`? If not, what’s the purpose of the copy?
Yes! Thank you. Fixed it.
Re:Running C unit tests with Pytest
by 10000truths on Saturday February 12, 2022 @07:57PM
(#30317999)
If you're using Linux, I would recommend using TemporaryFile instead of NamedTemporaryFile. It takes advantage of the O_TMPFILE flag, which guarantees that the kernel will clean up the file for you when the process exits:
import shutil
import tempfile
@pytest.fixture
def libfact():
tmp = tempfile.TemporaryFile()
tmp_name = f"/dev/fd/{tmp.name}"
shutil.copy2("./fact.so", tmp_name)
lib = CDLL(tmp_name)
yield lib
It's better than relying on your application to clean up the file for you. With application-level cleanup hooks, you're still vulnerable to a resource leak if the process gets a SIGKILL or crashes or otherwise ends before your hooks run.Does this even work? The documentation states that one should not rely on TemporaryFile having a name. Otherwise why would NamedTemporaryFile exist?
For the rare occurrence of sigkill before cleanup, I think your /tmp has ample of space to keep a few more kb until the next reboot. Servers running tests probably restart more often than desktops nowadays, when wrapped in containers.
That's a good observation. Towards the end the fixture is dropped in favour of a module-like object, which spaws the compiler once per test run. One could enhance this to skip compilation in the sandbox process to avoid unnecessary compilations.
That gets more relevant when on-the-fly compilation is added to the mix, spawning a compiler for every test is a complete waste of time.