diff --git a/motivating_sequence.md b/motivating_sequence.md new file mode 100644 index 0000000..1d88f04 --- /dev/null +++ b/motivating_sequence.md @@ -0,0 +1,68 @@ +# Advantage of using PySequence internally. + +CPython provides an API to handle any type of +sequence by the same interface: + +* PySequence_Check +* PySequence_GetItem + +or similar methods. + +Currenty the main effect on user side is that one does not need to call +`list(obj)` when returning an object. Its main use is for array as +a large array does not be converted to a list before passing it +as output. + + +``` +# record for reference waveform +record(pycalc, "ref_wf") +{ + field(DESC, "reference waveform") + field(CALC, "( A * np.sin(B * (C + np.asarray(D)) ) ).tolist()") + #field(CALC, "test_pydev.calc(%A%, %B%, %C%, %D%, tpro=%TPRO%) ") + field(INPA, "src:amp") + field(INPB, "src:frq") + field(INPC, "src:phs") + field(INPD, "src:t") + field(FTA, "DOUBLE") + field(FTB, "DOUBLE") + field(FTC, "DOUBLE") + field(FTD, "DOUBLE") + field(MED, 64) + field(MEVL, 64) + field(FTVL, "DOUBLE") + field(TPRO, 1) +} + +record(waveform, "src:t") +{ + field(DTYP, "pydev") + field(INP, "@np.linspace(0, 2*np.pi, num=64 + 1).tolist()") + field(FTVL, "DOUBLE") + field(NELM, 64) + field(PINI, "YES") + field(FLNK, "ref_wf") +} + +record(ao, "src:amp") +{ + field(VAL, 1.0) + field(FLNK, "ref_wf") +} + +record(ao, "src:frq") +{ + field(VAL, 2.0) + field(FLNK, "ref_wf") +} + +record(ao, "src:phs") +{ + field(VAL, 0) + field(FLNK, "ref_wf") +} + + + +``` diff --git a/src/pywrapper.cpp b/src/pywrapper.cpp index d96a91a..625b4ee 100644 --- a/src/pywrapper.cpp +++ b/src/pywrapper.cpp @@ -6,6 +6,11 @@ #include "pywrapper.h" #include "util.h" +#if PY_MAJOR_VERSION >= 3 +#if PY_MINOR_VERSION >= 2 +#define Py_LIMITED_API +#endif // PY_MINOR_VERSION >= 2 +#endif // PY_MAJOR_VERSION >= 3 #include #include @@ -270,14 +275,14 @@ bool PyWrapper::convert(void* in_, Variant& out) return true; } - if (PyList_Check(in)) { + if (PySequence_Check(in)) { std::vector vd; std::vector vl; std::vector vs; Variant::Type t = Variant::Type::NONE; - for (Py_ssize_t i = 0; i < PyList_Size(in); i++) { - PyObject* el = PyList_GetItem(in, i); + for (Py_ssize_t i = 0; i < PySequence_Size(in); i++) { + PyObject* el = PySequence_GetItem(in, i); #if PY_MAJOR_VERSION < 3 if (PyInt_Check(el) && (t == Variant::Type::NONE || t == Variant::Type::VECTOR_LONG)) { long long val = PyInt_AsLong(el); diff --git a/src/unittest/test_pywrapper.cpp b/src/unittest/test_pywrapper.cpp index 82129ce..55ecbe6 100644 --- a/src/unittest/test_pywrapper.cpp +++ b/src/unittest/test_pywrapper.cpp @@ -82,6 +82,11 @@ struct TestPyWrapper { testOk1(PyWrapper::exec("[1,2,3]").get_unsigned_array() == cmpulli); testOk1(PyWrapper::exec("[1,2,3]").get_double_array() == cmpd); testOk1(PyWrapper::exec("[1,2,3]").get_string_array() == cmps); + + // tuple as input ... + testOk1(PyWrapper::exec("(1,2,3)").get_long_array() == cmplli); + + } };