From a583fc5da1e3df9b2e4792a32b64e7c72e5f9db3 Mon Sep 17 00:00:00 2001 From: Oliver Copping Date: Tue, 16 Apr 2024 15:59:16 +0100 Subject: [PATCH 1/4] Update to support Python 3.12 Minor formatting changes Add PyArrayObject cast to some lines --- .github/workflows/build.yml | 33 +++++++++++++++++++++++++++++---- example/dynamicbox_server.py | 1 + example/monitor_meta.py | 1 + example/rpc_client.py | 4 ++-- makehelper.py | 14 +++++++------- setup.py | 10 +++++----- src/p4p/disect.py | 3 +-- src/p4p/test/test_value.py | 11 ++++++----- src/pvxs_value.cpp | 8 ++++---- 9 files changed, 56 insertions(+), 29 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 79ffdea6..76dd9182 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -43,7 +43,7 @@ jobs: # Check build from .tar - name: Source os: ubuntu-latest - python: "3.9" + python: "3.12" source: true # Linux py builds x64 @@ -109,6 +109,13 @@ 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==1.26.4 + cython: Cython==3.0.10 skip_cothread: yes # Linux py builds x64 @@ -163,9 +170,13 @@ jobs: - name: linux 3.9 i686 os: ubuntu-latest pyver: cp39-cp39 + + - name: linux 3.12 i686 + os: ubuntu-latest + pyver: cp312-cp312 piparch: manylinux2010_i686 - numpy: numpy==1.19.3 - cython: Cython==0.29.23 + numpy: numpy==1.26.4 + cython: Cython==3.0.10 pre: linux32 # numpy i386 wheels not built >= 3.10 @@ -212,13 +223,20 @@ jobs: piparch: macosx_10_9_intel numpy: numpy==1.23.5 cython: Cython==0.29.35 + + - name: osx 3.12 intel + os: macos-latest + python: "3.12" + piparch: macosx_10_9_intel + numpy: numpy==1.26.4 + 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 +288,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: 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/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/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; From e4a6f15b9078a7a1f0a2d2cae06961b3d9454159 Mon Sep 17 00:00:00 2001 From: Ollie Copping Date: Mon, 5 Aug 2024 08:18:35 +0100 Subject: [PATCH 2/4] Update versions of dependencies, inc. Python 3.12 supported ones --- pyproject.toml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) 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'", +] From 14a193def87c44ec21dbc44a2fbed9d480108da7 Mon Sep 17 00:00:00 2001 From: Ollie Copping Date: Mon, 5 Aug 2024 08:55:24 +0100 Subject: [PATCH 3/4] Update architectures/dependencies in GHA workflow Add Python 3.5 build fix for TLS deprecation Bump setup-python version to v5 Fix MacOS builds (now arm64) Remove SETUPTOOLS_USE_DISTUTILS export as deprecated in Python 3.12 --- .github/workflows/build.yml | 71 +++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 31 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 76dd9182..481a8221 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -47,6 +47,7 @@ jobs: 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 @@ -114,11 +115,12 @@ jobs: os: ubuntu-latest pyver: cp312-cp312 piparch: manylinux2014_x86_64 - numpy: numpy==1.26.4 + 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 @@ -158,77 +160,80 @@ 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 - - - name: linux 3.12 i686 - os: ubuntu-latest - pyver: cp312-cp312 piparch: manylinux2010_i686 - numpy: numpy==1.26.4 - cython: Cython==3.0.10 + 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 intel + - name: osx 3.12 arm64 os: macos-latest python: "3.12" - piparch: macosx_10_9_intel - numpy: numpy==1.26.4 + piparch: macosx_11_0_universal2 + numpy: numpy==2.0.1 cython: Cython==3.0.10 skip_cothread: yes @@ -302,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 @@ -383,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: | @@ -395,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 From 677306e478b69b079e21eccce3635718d3563ede Mon Sep 17 00:00:00 2001 From: Ollie Copping Date: Wed, 7 Aug 2024 14:42:42 +0100 Subject: [PATCH 4/4] Bump version to 4.2.0a1 --- src/p4p/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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')