From 81ccef6e3540de26e0be19450007228d00148efa Mon Sep 17 00:00:00 2001 From: Erik Frojdh Date: Fri, 2 Jun 2023 09:26:12 +0200 Subject: [PATCH] reader accept Path obj --- examples/hist.py | 2 +- src/ClusterReader.c | 19 ++++++++++++++----- tests/test_ClusterReader.py | 20 ++++++++++++++++++++ 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/examples/hist.py b/examples/hist.py index 74aff53..83c7dee 100644 --- a/examples/hist.py +++ b/examples/hist.py @@ -12,7 +12,7 @@ except: fname = "Moench_LGAD_SIM_Nov22/moenchLGAD202211/clustW17new/beam_En800eV_-40deg_300V_10us_d0_f5_0.clust" -r = ClusterFileReader((base/fname).as_posix()) +r = ClusterFileReader(base/fname) hist1 = bh.Histogram(bh.axis.Regular(40, -2, 2**14)) i = 0 while (cl:=r.read(100000)).size: diff --git a/src/ClusterReader.c b/src/ClusterReader.c index 1fba613..14352f9 100644 --- a/src/ClusterReader.c +++ b/src/ClusterReader.c @@ -17,22 +17,31 @@ typedef struct { static int ClusterFileReader_init(ClusterFileReader *self, PyObject *args, PyObject *Py_UNUSED(kwds)) { - // Parse file name + // Parse file name, accepts string or pathlike objects const char *fname = NULL; - if (!PyArg_ParseTuple(args, "s", &fname)) + PyObject* buf; + Py_ssize_t len; + + if (!PyArg_ParseTuple(args, "O&", PyUnicode_FSConverter, &buf)) return -1; + PyBytes_AsStringAndSize(buf, &fname, &len); self->fp = fopen(fname, "rb"); self->n_left = 0; + //Keep the return code to not return before releasing buffer + int rc = 0; + // Raise python exception using information from errno if (self->fp == NULL) { PyErr_SetFromErrnoWithFilename(PyExc_OSError, fname); - return -1; + rc = -1; } + //Release buffer + Py_DECREF(buf) - // Success - return 0; + // Success or fail + return rc; } // Custom destructor to make sure we close the file diff --git a/tests/test_ClusterReader.py b/tests/test_ClusterReader.py index 261f01f..aaa84b8 100644 --- a/tests/test_ClusterReader.py +++ b/tests/test_ClusterReader.py @@ -4,6 +4,26 @@ from creader import ClusterFileReader from fixtures import data_path import numpy as np +def test_open_file_using_Path(data_path): + # C extension cannot directly parse pathlib.Path to char * + # Check that implementation is working + try: + fname= data_path/'beam_En700eV_-40deg_300V_10us_d0_f0_100.clust' + r = ClusterFileReader(fname) + assert r.read(10).size == 10 # Read to make sure file is really open + + except: + pytest.fail("Could not open file using Path object") + +def test_open_file_using_str(data_path): + # Check that we didn't mess up the string passing + try: + fname= f'{data_path}/beam_En700eV_-40deg_300V_10us_d0_f0_100.clust' + r = ClusterFileReader(fname) + assert r.read(10).size == 10 # Read to make sure file is really open + except: + pytest.fail("Could not open file using string") + def test_references_on_read(data_path): fname= (data_path/'beam_En700eV_-40deg_300V_10us_d0_f0_100.clust').as_posix() r = ClusterFileReader(fname)