Skip to content

Commit

Permalink
Merge pull request #19 from tangkong/tst_basic_gha
Browse files Browse the repository at this point in the history
TST: try standard pcds build test
  • Loading branch information
tangkong authored Jan 22, 2025
2 parents 2f0e068 + 8c6d75f commit 395124d
Show file tree
Hide file tree
Showing 9 changed files with 171 additions and 61 deletions.
64 changes: 64 additions & 0 deletions .github/workflows/standard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: PCDS Standard Testing

on:
push:
pull_request:
release:
types:
- created

jobs:
pre-commit:
name: "pre-commit checks"
uses: pcdshub/pcds-ci-helpers/.github/workflows/pre-commit.yml@master
with:
args: "--all-files"

conda-test:
strategy:
fail-fast: false
matrix:
include:
- python-version: "3.9"
deploy-on-success: true
- python-version: "3.10"
- python-version: "3.11"
experimental: true
- python-version: "3.12"
experimental: true

name: "Conda"
uses: pcdshub/pcds-ci-helpers/.github/workflows/python-conda-test.yml@master
secrets: inherit
with:
package-name: "pyca"
python-version: ${{ matrix.python-version }}
experimental: ${{ matrix.experimental || false }}
deploy-on-success: ${{ matrix.deploy-on-success || false }}
testing-extras: ""
system-packages: ""
use-setuptools-scm: true

pip-test:
strategy:
fail-fast: false
matrix:
include:
- python-version: "3.9"
deploy-on-success: true
- python-version: "3.10"
- python-version: "3.11"
experimental: true
- python-version: "3.12"
experimental: true

name: "Pip"
uses: pcdshub/pcds-ci-helpers/.github/workflows/python-pip-test.yml@master
secrets: inherit
with:
package-name: "pyca"
python-version: ${{ matrix.python-version }}
experimental: ${{ matrix.experimental || false }}
deploy-on-success: ${{ matrix.deploy-on-success || false }}
system-packages: ""
testing-extras: ""
62 changes: 40 additions & 22 deletions conda-recipe/meta.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
{% set package_name = "pyca" %}
{% set import_name = "pyca" %}
{% set version = load_file_regex(load_file=os.path.join(import_name, "_version.py"), regex_pattern=".*version = '(\S+)'").group(1) %}
{% set EPICS = '3.14.12.6' %}
{% set data = load_setup_py_data() %}

package:
name: {{ package_name }}
version: {{ version }}
version: {{ data.get('version') }}

source:
path: ..
Expand All @@ -14,33 +13,52 @@ build:
number: 0
noarch: python
script: {{ PYTHON }} -m pip install . -vv


skip: true # [win]
missing_dso_whitelist:
- '*/libca.*'
- '*/libCom.*'

requirements:
build:
- python {{ PY_VER }}*
- epics-base {{ EPICS }}*
- numpy {{ NPY_VER }}*
- setuptools_scm
- pip
- epicscorelibs
- python >=3.9
- pip
- numpy
- setuptools
- setuptools_scm
host:
- python >=3.9
- epicscorelibs
- numpy
- pip
- setuptools
- setuptools_dso
- setuptools_scm
run:
- python {{ PY_VER }}*
- epics-base {{ EPICS }}*
- numpy {{ NPY_VER }}*


- python
- epicscorelibs
- numpy

test:
requires:
- pcaspy
- pcaspy
imports:
- pyca
- psp


- pyca
- psp

about:
home: https://github.com/slaclab/pyca
licence: SLAC Open Licence
summary: Python Channel Access
license: LicenseRef-BSD-3-Clause-SLAC
license_family: BSD
license_file: LICENSE.md
summary: PyCA - lightweight bindings for Python applications to access EPICS PVs.

description: |
PyCA (Python Channel Access) is a module that offers lightweight
bindings for Python applications to access EPICS PVs. It acts as
a channel access client, much like pyepics. The intention of the
module is to provide better performance for embedded applications,
rather than to provide an interactive interface. The most significant
gains will be found when monitoring large waveforms that need to be
processed before exposing them the Python layer.
dev_url: https://github.com/slaclab/pyca
1 change: 1 addition & 0 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pcaspy
pytest
4 changes: 3 additions & 1 deletion pyca/getfunctions.hh
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "p3compat.h"
// #include "npy_2_compat.h"
// Channel access GET template functions
static inline PyObject* _pyca_get(const dbr_string_t value)
{
Expand Down Expand Up @@ -107,7 +108,8 @@ PyObject* _pyca_get_value(capv* pv, const T* dbrv, long count)
npy_intp dims[1] = {count};
int typenum = _numpy_array_type(&(dbrv->value));
PyObject* nparray = PyArray_EMPTY(1, dims, typenum, 0);
memcpy(PyArray_DATA(nparray), &(dbrv->value), count*sizeof(dbrv->value));
PyArrayObject *arr = (PyArrayObject *)PyArray_FROM_O(nparray);
memcpy(PyArray_DATA(arr), &(dbrv->value), count*sizeof(dbrv->value));
return nparray;
} else {
PyObject* pytup = PyTuple_New(count);
Expand Down
14 changes: 9 additions & 5 deletions pyca/putfunctions.hh
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,16 @@ void _pyca_put_value(capv* pv, PyObject* pyvalue, T** buf, long count)
}
T* buffer = reinterpret_cast<T*>(pv->putbuffer);
if (count == 1) {
// if we only want to put the first element
if (PyTuple_Check(pyvalue)) {
PyObject* pyval = PyTuple_GetItem(pyvalue, 0);
_pyca_put(pyval, buffer);
} else if (PyArray_Check(pyvalue)) {
void* npdata = PyArray_GETPTR1(pyvalue, 0);
// Convert to array
PyArrayObject *arr = (PyArrayObject *)PyArray_FROM_O(pyvalue);
char* npdata = static_cast<char*>(PyArray_GETPTR1(arr, 0));
if (PyArray_IsPythonScalar(pyvalue)) {
PyObject* pyval = PyArray_GETITEM(pyvalue, npdata);
PyObject* pyval = PyArray_GETITEM(arr, npdata);
_pyca_put(pyval, buffer);
} else {
_pyca_put_np(npdata, buffer);
Expand All @@ -85,11 +88,12 @@ void _pyca_put_value(capv* pv, PyObject* pyvalue, T** buf, long count)
_pyca_put(pyval, buffer+i);
}
} else if (PyArray_Check(pyvalue)) {
bool py_type = PyArray_IsPythonScalar(pyvalue);
PyArrayObject *arr2 = (PyArrayObject *)PyArray_FROM_O(pyvalue);
bool py_type = PyArray_IsPythonScalar(arr2);
for (long i=0; i<count; i++) {
void* npdata = PyArray_GETPTR1(pyvalue, i);
char* npdata = static_cast<char*>(PyArray_GETPTR1(arr2, i));
if (py_type) {
PyObject* pyval = PyArray_GETITEM(pyvalue, npdata);
PyObject* pyval = PyArray_GETITEM(arr2, npdata);
_pyca_put(pyval, buffer+i);
} else {
_pyca_put_np(npdata, buffer+i);
Expand Down
4 changes: 3 additions & 1 deletion pyca/pyca.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#include <Python.h>
// We apparently use deprecated API, but I can't find which bits to update
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include <numpy/arrayobject.h>
#include <stdio.h>
#include <structmember.h>
Expand Down Expand Up @@ -785,7 +787,7 @@ extern "C" {
Py_INCREF(pyca_caexc);
PyModule_AddObject(module, "caexc", pyca_caexc);

PyEval_InitThreads();
// PyEval_InitThreads();
if (!has_proc_context()) {
int result = ca_context_create(ca_enable_preemptive_callback);
if (result != ECA_NORMAL) {
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[build-system]
build-backend = "setuptools.build_meta"
requires = [ "setuptools>=45", "setuptools_scm[toml]>=6.2", "numpy"]
requires = [ "setuptools>=45", "setuptools_scm[toml]>=6.2", "setuptools_dso", "numpy>1.23", "epicscorelibs"]

[project]
classifiers = [ "Development Status :: 2 - Pre-Alpha", "Natural Language :: English", "Programming Language :: Python :: 3",]
Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
numpy
epicscorelibs
numpy>1.23
78 changes: 48 additions & 30 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,50 @@
import os
import sys

import numpy as np
from setuptools import Extension, setup

if sys.platform == 'darwin':
libsrc = 'Darwin'
compiler = 'clang'
elif sys.platform.startswith('linux'):
libsrc = 'Linux'
compiler = 'gcc'
else:
libsrc = None

epics_inc = os.getenv("EPICS_BASE") + "/include"
epics_lib = os.getenv("EPICS_BASE") + "/lib/" + os.getenv("EPICS_HOST_ARCH")
numpy_inc = np.get_include()
numpy_lib = np.__path__[0]

pyca = Extension('pyca',
language='c++',
sources=['pyca/pyca.cc'],
include_dirs=['pyca', epics_inc,
epics_inc + '/os/' + libsrc,
epics_inc + '/compiler/' + compiler,
numpy_inc],
library_dirs=[epics_lib, numpy_lib],
runtime_library_dirs=[epics_lib, numpy_lib],
libraries=['Com', 'ca'])

setup(ext_modules=[pyca,])
import numpy
import platform
from setuptools_dso import Extension, setup

from numpy import get_include
def get_numpy_include_dirs():
return [get_include()]

import epicscorelibs.path
import epicscorelibs.version
from epicscorelibs.config import get_config_var


extra = []
if sys.platform=='linux2':
extra += ['-v']
elif platform.system()=='Darwin':
# avoid later failure where install_name_tool may run out of space.
# install_name_tool: changing install names or rpaths can't be redone for:
# ... because larger updated load commands do not fit (the program must be relinked,
# and you may need to use -headerpad or -headerpad_max_install_names)
extra += ['-Wl,-headerpad_max_install_names']


pyca = Extension(
name='pyca',
sources=['pyca/pyca.cc'],
include_dirs= get_numpy_include_dirs()+[epicscorelibs.path.include_path],
define_macros = get_config_var('CPPFLAGS'),
extra_compile_args = get_config_var('CXXFLAGS'),
extra_link_args = get_config_var('LDFLAGS')+extra,
dsos = ['epicscorelibs.lib.ca',
'epicscorelibs.lib.Com'
],
libraries=get_config_var('LDADD'),
)

setup(
name='pyca',
description='python channel access library',
packages=['psp', 'pyca'],
ext_modules=[pyca],
install_requires = [
epicscorelibs.version.abi_requires(),
'numpy >=%s'%numpy.version.short_version,
],
zip_safe=False,
)

0 comments on commit 395124d

Please # to comment.