mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-06 18:10:40 +02:00
Fixed broken import in typecaster.h (#1181)
Some checks failed
Native CMake Build / Configure and build using cmake (push) Failing after 28s
Some checks failed
Native CMake Build / Configure and build using cmake (push) Failing after 28s
- Fixed the broken import _slsdet --> slsdet._slsdet caused by a previous upgrade - Added tests that exercises the conversion from python to C++ and from C++ to python - Python unit tests now run in CI (!)
This commit is contained in:
parent
884e17f0c4
commit
5ab2c1693e
19
.github/workflows/cmake.yaml
vendored
19
.github/workflows/cmake.yaml
vendored
@ -14,7 +14,13 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
name: Configure and build using cmake
|
name: Configure and build using cmake
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: 3.12
|
||||||
|
cache: 'pip'
|
||||||
|
- run: pip install pytest numpy
|
||||||
|
|
||||||
- uses: awalsh128/cache-apt-pkgs-action@latest
|
- uses: awalsh128/cache-apt-pkgs-action@latest
|
||||||
with:
|
with:
|
||||||
packages: libhdf5-dev qtbase5-dev qt5-qmake libqt5svg5-dev libpng-dev libtiff-dev
|
packages: libhdf5-dev qtbase5-dev qt5-qmake libqt5svg5-dev libpng-dev libtiff-dev
|
||||||
@ -27,12 +33,15 @@ jobs:
|
|||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
# Build your program with the given configuration
|
# Build your program with the given configuration
|
||||||
run: cmake --build ${{github.workspace}}/build -j2 --config ${{env.BUILD_TYPE}}
|
run: cmake --build ${{github.workspace}}/build -j4 --config ${{env.BUILD_TYPE}}
|
||||||
|
|
||||||
- name: Test
|
- name: C++ unit tests
|
||||||
working-directory: ${{github.workspace}}/build
|
working-directory: ${{github.workspace}}/build
|
||||||
# Execute tests defined by the CMake configuration.
|
|
||||||
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
|
|
||||||
run: ctest -C ${{env.BUILD_TYPE}} -j1
|
run: ctest -C ${{env.BUILD_TYPE}} -j1
|
||||||
|
|
||||||
|
- name: Python unit tests
|
||||||
|
working-directory: ${{github.workspace}}/build/bin
|
||||||
|
run: |
|
||||||
|
python -m pytest ${{github.workspace}}/python/tests
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,3 +41,6 @@ def read_version():
|
|||||||
|
|
||||||
__version__ = read_version()
|
__version__ = read_version()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include <chrono>
|
||||||
#include "py_headers.h"
|
#include "py_headers.h"
|
||||||
|
|
||||||
#include "DurationWrapper.h"
|
#include "DurationWrapper.h"
|
||||||
@ -19,4 +20,25 @@ void init_duration(py::module &m) {
|
|||||||
<< " count: " << self.count() << ")";
|
<< " count: " << self.count() << ")";
|
||||||
return ss.str();
|
return ss.str();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
m.def(
|
||||||
|
"test_return_DurationWrapper",
|
||||||
|
[]() {
|
||||||
|
DurationWrapper t(1.3);
|
||||||
|
return t;
|
||||||
|
},
|
||||||
|
R"(
|
||||||
|
Test function to return a DurationWrapper object. Ensures that the automatic conversion in typecaster.h works.
|
||||||
|
)");
|
||||||
|
|
||||||
|
m.def(
|
||||||
|
"test_duration_to_ns",
|
||||||
|
[](const std::chrono::nanoseconds t) {
|
||||||
|
//Duration wrapper is used to be able to convert from time in python to chrono::nanoseconds
|
||||||
|
//return count to have something to test
|
||||||
|
return t.count();
|
||||||
|
},
|
||||||
|
R"(
|
||||||
|
Test function convert DurationWrapper or number to chrono::ns. Ensures that the automatic conversion in typecaster.h works.
|
||||||
|
)"); // default value to test the default constructor
|
||||||
}
|
}
|
||||||
|
@ -54,11 +54,16 @@ template <> struct type_caster<std::chrono::nanoseconds> {
|
|||||||
value = duration_cast<nanoseconds>(duration<double>(PyFloat_AsDouble(src.ptr())));
|
value = duration_cast<nanoseconds>(duration<double>(PyFloat_AsDouble(src.ptr())));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
// If invoked with an int we assume it is nanoseconds and convert, same as in chrono.h
|
||||||
|
if (PyLong_Check(src.ptr())) {
|
||||||
|
value = duration_cast<nanoseconds>(duration<int64_t>(PyLong_AsLongLong(src.ptr())));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Lastly if we were actually called with a DurationWrapper object we get
|
// Lastly if we were actually called with a DurationWrapper object we get
|
||||||
// the number of nanoseconds and create a std::chrono::nanoseconds from it
|
// the number of nanoseconds and create a std::chrono::nanoseconds from it
|
||||||
py::object py_cls = py::module::import("_slsdet").attr("DurationWrapper");
|
py::object py_cls = py::module::import("slsdet._slsdet").attr("DurationWrapper");
|
||||||
if (py::isinstance(src, py_cls)){
|
if (py::isinstance(src, py_cls)){
|
||||||
sls::DurationWrapper *cls = src.cast<sls::DurationWrapper *>();
|
sls::DurationWrapper *cls = src.cast<sls::DurationWrapper *>();
|
||||||
value = nanoseconds(cls->count());
|
value = nanoseconds(cls->count());
|
||||||
@ -77,7 +82,7 @@ template <> struct type_caster<std::chrono::nanoseconds> {
|
|||||||
* set the count from chrono::nanoseconds and return
|
* set the count from chrono::nanoseconds and return
|
||||||
*/
|
*/
|
||||||
static handle cast(std::chrono::nanoseconds src, return_value_policy /* policy */, handle /* parent */) {
|
static handle cast(std::chrono::nanoseconds src, return_value_policy /* policy */, handle /* parent */) {
|
||||||
py::object py_cls = py::module::import("_slsdet").attr("DurationWrapper");
|
py::object py_cls = py::module::import("slsdet._slsdet").attr("DurationWrapper");
|
||||||
py::object* obj = new py::object;
|
py::object* obj = new py::object;
|
||||||
*obj = py_cls();
|
*obj = py_cls();
|
||||||
sls::DurationWrapper *dur = obj->cast<sls::DurationWrapper *>();
|
sls::DurationWrapper *dur = obj->cast<sls::DurationWrapper *>();
|
||||||
|
58
python/tests/test_DurationWrapper.py
Normal file
58
python/tests/test_DurationWrapper.py
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from slsdet import DurationWrapper
|
||||||
|
|
||||||
|
#import the compiled extension to use test functions for the automatic conversion
|
||||||
|
from slsdet import _slsdet
|
||||||
|
|
||||||
|
|
||||||
|
def test_default_construction_of_DurationWrapper():
|
||||||
|
"""Test default construction of DurationWrapper"""
|
||||||
|
t = DurationWrapper()
|
||||||
|
assert t.count() == 0
|
||||||
|
assert t.total_seconds() == 0
|
||||||
|
|
||||||
|
def test_construction_of_DurationWrapper():
|
||||||
|
"""Test construction of DurationWrapper with total_seconds"""
|
||||||
|
t = DurationWrapper(5)
|
||||||
|
assert t.count() == 5e9
|
||||||
|
assert t.total_seconds() == 5
|
||||||
|
|
||||||
|
def test_set_count_on_DurationWrapper():
|
||||||
|
"""Test set_count on DurationWrapper"""
|
||||||
|
t = DurationWrapper()
|
||||||
|
t.set_count(10)
|
||||||
|
assert t.count() == 10
|
||||||
|
assert t.total_seconds() == 10e-9
|
||||||
|
t.set_count(0)
|
||||||
|
assert t.count() == 0
|
||||||
|
assert t.total_seconds() == 0
|
||||||
|
|
||||||
|
|
||||||
|
def test_return_a_DurationWrapper_from_cpp():
|
||||||
|
"""Test returning a DurationWrapper from C++"""
|
||||||
|
t = _slsdet.test_return_DurationWrapper()
|
||||||
|
assert t.count() == 1.3e9
|
||||||
|
assert t.total_seconds() == 1.3
|
||||||
|
|
||||||
|
def test_call_a_cpp_function_with_a_duration_wrapper():
|
||||||
|
"""C++ functions can accept a DurationWrapper"""
|
||||||
|
t = DurationWrapper(5)
|
||||||
|
assert _slsdet.test_duration_to_ns(t) == 5e9
|
||||||
|
|
||||||
|
def test_call_a_cpp_function_converting_number_to_DurationWrapper():
|
||||||
|
"""int and float can be converted to std::chrono::nanoseconds"""
|
||||||
|
assert _slsdet.test_duration_to_ns(0) == 0
|
||||||
|
assert _slsdet.test_duration_to_ns(3) == 3e9
|
||||||
|
assert _slsdet.test_duration_to_ns(1.3) == 1.3e9
|
||||||
|
assert _slsdet.test_duration_to_ns(10e-9) == 10
|
||||||
|
|
||||||
|
def test_call_a_cpp_function_with_datetime_timedelta():
|
||||||
|
"""datetime.timedelta can be converted to std::chrono::nanoseconds"""
|
||||||
|
import datetime
|
||||||
|
t = datetime.timedelta(seconds=5)
|
||||||
|
assert _slsdet.test_duration_to_ns(t) == 5e9
|
||||||
|
t = datetime.timedelta(seconds=0)
|
||||||
|
assert _slsdet.test_duration_to_ns(t) == 0
|
||||||
|
t = datetime.timedelta(seconds=1.3)
|
||||||
|
assert _slsdet.test_duration_to_ns(t) == 1.3e9
|
Loading…
x
Reference in New Issue
Block a user