diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 79ffdea6..481a8221 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -43,10 +43,11 @@ jobs: # Check build from .tar - name: Source os: ubuntu-latest - python: "3.9" + python: "3.12" source: true # Linux py builds x64 + # TODO: manylinux1 and 2014 are EOL, even more reason to remove these supported versions - name: linux 2.7 amd64 os: ubuntu-latest pyver: cp27-cp27m @@ -109,9 +110,17 @@ jobs: piparch: manylinux2014_x86_64 numpy: numpy==1.23.5 cython: Cython==0.29.35 + + - name: linux 3.12 amd64 + os: ubuntu-latest + pyver: cp312-cp312 + piparch: manylinux2014_x86_64 + numpy: numpy==2.0.1 + cython: Cython==3.0.10 skip_cothread: yes # Linux py builds x64 + # TODO: manylinux1 and 2014 are EOL, even more reason to remove these supported versions - name: linux 2.7 i686 os: ubuntu-latest pyver: cp27-cp27m @@ -151,74 +160,88 @@ jobs: numpy: numpy==1.16.2 cython: Cython==0.29.2 pre: linux32 + skip_cothread: yes - name: linux 3.8 i686 os: ubuntu-latest pyver: cp38-cp38 piparch: manylinux1_i686 - numpy: numpy==1.17.3 + numpy: numpy==1.19.5 cython: Cython==0.29.2 pre: linux32 + skip_cothread: yes - name: linux 3.9 i686 os: ubuntu-latest pyver: cp39-cp39 piparch: manylinux2010_i686 - numpy: numpy==1.19.3 + numpy: numpy==1.19.5 cython: Cython==0.29.23 pre: linux32 + skip_cothread: yes # numpy i386 wheels not built >= 3.10 # OSX py builds - name: osx 3.6 intel - os: macos-latest + os: macos-13 python: "3.6" piparch: macosx_10_9_intel numpy: numpy==1.11.3 cython: Cython==0.29.2 - name: osx 3.7 intel - os: macos-latest + os: macos-13 python: "3.7" piparch: macosx_10_9_intel numpy: numpy==1.16.2 cython: Cython==0.29.2 - - name: osx 3.8 intel + - name: osx 3.8 arm64 os: macos-latest python: "3.8" - piparch: macosx_10_9_intel - numpy: numpy==1.17.3 + piparch: macosx_11_0_universal2 + numpy: numpy==1.24.4 cython: Cython==0.29.2 + skip_cothread: yes - - name: osx 3.9 intel + - name: osx 3.9 arm64 os: macos-latest python: "3.9" - piparch: macosx_10_9_intel - numpy: numpy==1.19.3 - cython: Cython==0.29.23 + piparch: macosx_11_0_universal2 + numpy: numpy==2.0.1 + cython: Cython==3.0.10 + skip_cothread: yes - - name: osx 3.10 intel + - name: osx 3.10 arm64 os: macos-latest python: "3.10" - piparch: macosx_10_9_intel - numpy: numpy==1.22.0 - cython: Cython==0.29.23 + piparch: macosx_11_0_universal2 + numpy: numpy==2.0.1 + cython: Cython==3.0.10 + skip_cothread: yes - - name: osx 3.11 intel + - name: osx 3.11 arm64 os: macos-latest python: "3.11" - piparch: macosx_10_9_intel - numpy: numpy==1.23.5 - cython: Cython==0.29.35 + piparch: macosx_11_0_universal2 + numpy: numpy==2.0.1 + cython: Cython==3.0.10 + skip_cothread: yes + + - name: osx 3.12 arm64 + os: macos-latest + python: "3.12" + piparch: macosx_11_0_universal2 + numpy: numpy==2.0.1 + cython: Cython==3.0.10 skip_cothread: yes # Windows py builds ## missing Microsoft Visual C++ 9.0 #- os: windows-latest - # python: "2.7" + # python: "3.12" # piparch: win_amd64 - name: win64 3.5 @@ -270,6 +293,13 @@ jobs: profile: latest skip_cothread: yes + - name: win64 3.12 + os: windows-latest + python: "3.12" + piparch: win_amd64 + profile: latest + skip_cothread: yes + steps: - uses: actions/checkout@v3 with: @@ -277,11 +307,17 @@ jobs: - name: Setup native python if: matrix.python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python }} #architecture: x64 + # TLS 1.0 and 1.1 support was removed from pypi so the cached pip won't work + - name: Python 3.5 Fix + if: ${{ matrix.python == '3.5' }} + run: | + curl https://bootstrap.pypa.io/pip/3.5/get-pip.py | python + - name: Automatic core dumper analysis uses: mdavidsaver/ci-core-dumper@master @@ -358,7 +394,6 @@ jobs: python -m pip install p4p*.whl python -m ci_core_dumper exec python -m nose2 -v p4p - - name: Docker PY build if: matrix.pyver && !matrix.base && !matrix.source run: | @@ -370,7 +405,6 @@ jobs: [ -d dist ] ls dist/* export PATH="/opt/python/${{ matrix.pyver }}/bin:\$PATH" - export SETUPTOOLS_USE_DISTUTILS=stdlib which python python -m pip install -U pip python -m pip install setuptools wheel nose2 diff --git a/example/dynamicbox_server.py b/example/dynamicbox_server.py index fc389818..427b1eac 100644 --- a/example/dynamicbox_server.py +++ b/example/dynamicbox_server.py @@ -19,6 +19,7 @@ import sys import time, logging + _log = logging.getLogger(__name__) from threading import Lock diff --git a/example/monitor_meta.py b/example/monitor_meta.py index ddcaf0fe..126d7640 100644 --- a/example/monitor_meta.py +++ b/example/monitor_meta.py @@ -17,6 +17,7 @@ def cb(value): for fld in value.raw.asSet(): print(" ",fld,value.raw[fld]) + print("Create Context") with Context('pva') as ctxt: print("Subscribe to", sys.argv[1]) diff --git a/example/rpc_client.py b/example/rpc_client.py index 109eac98..2c870549 100644 --- a/example/rpc_client.py +++ b/example/rpc_client.py @@ -24,9 +24,9 @@ def getargs(): P.add_argument('prefix') P.add_argument('method') P.add_argument('args', nargs='*') - return P.parse_args() + return P, P.parse_args() -args = getargs() +P, args = getargs() logging.basicConfig(level=logging.DEBUG if args.debug else logging.INFO) diff --git a/makehelper.py b/makehelper.py index 0a97d518..f920bcc7 100644 --- a/makehelper.py +++ b/makehelper.py @@ -33,14 +33,14 @@ incdirs = [get_python_inc()] libdir = get_config_var('LIBDIR') or '' -try: - from numpy.distutils.misc_util import get_numpy_include_dirs -except ImportError: - def get_numpy_include_dirs(): - from numpy import get_include - return [get_include()] -incdirs = get_numpy_include_dirs()+incdirs +def get_numpy_include_dirs(): + from numpy import get_include + + return [get_include()] + + +incdirs = get_numpy_include_dirs() + incdirs print('TARGET_CFLAGS +=',get_config_var('BASECFLAGS'), file=out) print('TARGET_CXXFLAGS +=',get_config_var('BASECFLAGS'), file=out) diff --git a/pyproject.toml b/pyproject.toml index 4adf1d4c..767d25b6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,2 +1,14 @@ [build-system] -requires = ["setuptools", "setuptools_dso>=1.3a1", "wheel", "numpy", "Cython>=0.20", "epicscorelibs>=7.0.3.99.2.0a1", "pvxslibs"] +requires = [ + "setuptools", + "setuptools_dso>=2.7a1,<=2.10; python_version<='3.11'", + "setuptools_dso>=2.11a2; python_version>='3.12'", + "wheel", + "numpy", + "numpy>=2.0.1; python_version>='3.10'", + "Cython>=0.20", + "epicscorelibs==7.0.7.99.0.2; python_version<='3.11'", + "epicscorelibs>=7.0.7.99.1.1a2; python_version>='3.12'", + "pvxslibs==1.3.1; python_version<='3.11'", + "pvxslibs>=1.3.2a1; python_version>='3.12'", +] diff --git a/setup.py b/setup.py index b8663d5a..57af1319 100755 --- a/setup.py +++ b/setup.py @@ -8,11 +8,6 @@ from setuptools_dso import Extension, setup, cythonize import numpy -try: - from numpy.distutils.misc_util import get_numpy_include_dirs -except ImportError: - def get_numpy_include_dirs(): - return [numpy.get_include()] import epicscorelibs.path import epicscorelibs.version @@ -21,6 +16,11 @@ def get_numpy_include_dirs(): import pvxslibs.path import pvxslibs.version + +def get_numpy_include_dirs(): + return [numpy.get_include()] + + with open('src/p4p/version.py', 'r') as F: lcl = {} exec(F.read(), None, lcl) diff --git a/src/p4p/disect.py b/src/p4p/disect.py index fef5f625..3febb35d 100644 --- a/src/p4p/disect.py +++ b/src/p4p/disect.py @@ -1,7 +1,6 @@ -"""Python reference counter statistics. -""" from __future__ import print_function +"""Python reference counter statistics.""" import sys import gc diff --git a/src/p4p/test/test_value.py b/src/p4p/test/test_value.py index ab3bfd63..3296790f 100644 --- a/src/p4p/test/test_value.py +++ b/src/p4p/test/test_value.py @@ -11,6 +11,7 @@ from .. import pvdVersion from .utils import RefTestCase + class TestWrapper(RefTestCase): def testCall(self): T = Type([('ival', 'I')]) @@ -183,12 +184,12 @@ def testArray(self): ('sval', 'as'), ]), { 'ival': [1, 2, 3], - 'dval': np.asfarray([1.1, 2.2]), + 'dval': np.asarray([1.1, 2.2], dtype=np.float64), 'sval': ['a', u'b'], }) assert_aequal(V.ival, np.asarray([1, 2, 3])) - assert_aequal(V.dval, np.asfarray([1.1, 2.2])) + assert_aequal(V.dval, np.asarray([1.1, 2.2], dtype=np.float64)) self.assertListEqual(V.sval, [u'a', u'b']) # i4 <- u8 violates "safe" casting rules @@ -296,8 +297,8 @@ def testVariantUnion(self): V.x = np.asarray([1, 2]) assert_aequal(V.x, np.asarray([1, 2])) - V.x = np.asfarray([1, 2]) - assert_aequal(V.x, np.asfarray([1, 2])) + V.x = np.asarray([1, 2], dtype=np.float64) + assert_aequal(V.x, np.asarray([1, 2], dtype=np.float64)) # clearing unions is broken prior to 7.0.0 if pvdVersion() >= (7, 0, 0, 0): @@ -317,7 +318,7 @@ def testVariantUnionExplicit(self): self.assertEqual(type(V.x), float) V.x = ('ad', np.asarray([1, 2])) - assert_aequal(V.x, np.asfarray([1, 2])) + assert_aequal(V.x, np.asarray([1, 2], dtype=np.float64)) V.x = ('as', ['one', 'two']) self.assertEqual(V.x, ['one', 'two']) diff --git a/src/p4p/version.py b/src/p4p/version.py index f4ee2377..23c763b6 100644 --- a/src/p4p/version.py +++ b/src/p4p/version.py @@ -67,4 +67,4 @@ def __ge__(self, o): def __gt__(self, o): return self._cmp(o)>0 -version = Version('4.1.12') +version = Version('4.2.0a1') diff --git a/src/pvxs_value.cpp b/src/pvxs_value.cpp index 0dc47c85..4ab07a88 100644 --- a/src/pvxs_value.cpp +++ b/src/pvxs_value.cpp @@ -236,7 +236,7 @@ Value inferPy(PyObject* py) else if(PyList_Check(py)) code = TypeCode::StringA; else if(PyArray_Check(py)) { - switch(PyArray_TYPE(py)) { + switch(PyArray_TYPE((PyArrayObject*)py)) { #define CASE(NTYPE, PTYPE) case NTYPE: code = TypeCode::PTYPE; break CASE(NPY_BOOL, BoolA); // bool stored as one byte CASE(NPY_INT8, Int8A); @@ -532,12 +532,12 @@ void storePy(Value& v, PyObject* py, bool forceCast) PyRef arr(PyArray_FromAny(py, PyArray_DescrFromType(ntype), 0, 0, NPY_CARRAY_RO|NPY_ARRAY_FORCECAST, nullptr)); - if(PyArray_NDIM(arr.obj)!=1) + if(PyArray_NDIM((PyArrayObject*)arr.obj)!=1) throw std::logic_error("Only 1-d array can be assigned"); - auto dest(allocArray(v.type().arrayType(), PyArray_DIM(arr.obj, 0))); + auto dest(allocArray(v.type().arrayType(), PyArray_DIM((PyArrayObject*)arr.obj, 0))); - memcpy(dest.data(), PyArray_DATA(arr.obj), PyArray_NBYTES(arr.obj)); + memcpy(dest.data(), PyArray_DATA((PyArrayObject*)arr.obj), PyArray_NBYTES((PyArrayObject*)arr.obj)); v = dest.freeze(); return;