dynaplex 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dynaplex-0.2.0/.github/workflows/pypi_publish.yaml +93 -0
- dynaplex-0.2.0/.github/workflows/sdist.yaml +46 -0
- dynaplex-0.2.0/.github/workflows/test_pypi_publish.yaml +96 -0
- dynaplex-0.2.0/.github/workflows/wheels.yaml +76 -0
- dynaplex-0.2.0/.gitignore +43 -0
- dynaplex-0.2.0/CMakeLists.txt +33 -0
- dynaplex-0.2.0/CMakePresets.json +14 -0
- dynaplex-0.2.0/PKG-INFO +52 -0
- dynaplex-0.2.0/README.md +40 -0
- dynaplex-0.2.0/include/dynaplex/hello.h +14 -0
- dynaplex-0.2.0/pyproject.toml +33 -0
- dynaplex-0.2.0/python/dynaplex/__init__.py +9 -0
- dynaplex-0.2.0/python/dynaplex/ops.py +2 -0
- dynaplex-0.2.0/python/dynaplex/utils.py +4 -0
- dynaplex-0.2.0/python/examples/example.py +3 -0
- dynaplex-0.2.0/src/bindings.cpp +11 -0
- dynaplex-0.2.0/src/hello.cpp +7 -0
- dynaplex-0.2.0/tests/test_basic.py +13 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
name: Publish (PyPI – reuse artifacts)
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: [ "v*" ] # e.g. v0.1.0
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
id-token: write
|
|
10
|
+
contents: read
|
|
11
|
+
actions: read
|
|
12
|
+
|
|
13
|
+
concurrency:
|
|
14
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
15
|
+
cancel-in-progress: true
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
fetch-and-publish:
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
environment: pypi
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v4
|
|
23
|
+
|
|
24
|
+
- name: Set up Python
|
|
25
|
+
uses: actions/setup-python@v5
|
|
26
|
+
with:
|
|
27
|
+
python-version: "3.12"
|
|
28
|
+
cache: "pip"
|
|
29
|
+
|
|
30
|
+
# Wheels from wheels workflow (download all OS-specific artifacts)
|
|
31
|
+
- name: Download wheel artifacts
|
|
32
|
+
uses: dawidd6/action-download-artifact@v3
|
|
33
|
+
with:
|
|
34
|
+
workflow: wheels.yaml
|
|
35
|
+
commit: ${{ github.sha }}
|
|
36
|
+
name: wheels-.*
|
|
37
|
+
name_is_regexp: true # match wheels-ubuntu, wheels-macos, wheels-windows
|
|
38
|
+
path: dist
|
|
39
|
+
workflow_conclusion: success
|
|
40
|
+
|
|
41
|
+
# sdist from sdist workflow
|
|
42
|
+
- name: Download sdist artifact
|
|
43
|
+
uses: dawidd6/action-download-artifact@v3
|
|
44
|
+
with:
|
|
45
|
+
workflow: sdist.yaml
|
|
46
|
+
commit: ${{ github.sha }}
|
|
47
|
+
name: sdist
|
|
48
|
+
path: dist
|
|
49
|
+
workflow_conclusion: success
|
|
50
|
+
|
|
51
|
+
# Flatten nested artifact dirs into a single folder for upload
|
|
52
|
+
- name: Collect distributions
|
|
53
|
+
run: |
|
|
54
|
+
mkdir -p dist_flat
|
|
55
|
+
find dist -type f \( -name "*.whl" -o -name "*.tar.gz" \) -exec cp {} dist_flat/ \;
|
|
56
|
+
echo "Contents to publish:"
|
|
57
|
+
ls -l dist_flat
|
|
58
|
+
|
|
59
|
+
# Optional: verify tag matches project version
|
|
60
|
+
- name: Check tag matches pyproject version
|
|
61
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
62
|
+
run: |
|
|
63
|
+
python - <<'PY'
|
|
64
|
+
import os, sys
|
|
65
|
+
try:
|
|
66
|
+
import tomllib
|
|
67
|
+
except Exception:
|
|
68
|
+
import tomli as tomllib
|
|
69
|
+
with open("pyproject.toml","rb") as f:
|
|
70
|
+
data = tomllib.load(f)
|
|
71
|
+
version = data["project"]["version"]
|
|
72
|
+
tag = os.environ["GITHUB_REF_NAME"].lstrip("v")
|
|
73
|
+
if version != tag:
|
|
74
|
+
print(f"ERROR: tag v{tag} != pyproject version {version}")
|
|
75
|
+
sys.exit(1)
|
|
76
|
+
print(f"OK: tag v{tag} matches pyproject version {version}")
|
|
77
|
+
PY
|
|
78
|
+
|
|
79
|
+
# Fail early if nothing was collected
|
|
80
|
+
- name: Ensure distributions exist
|
|
81
|
+
run: |
|
|
82
|
+
shopt -s nullglob
|
|
83
|
+
files=(dist_flat/*.whl dist_flat/*.tar.gz)
|
|
84
|
+
if [ ${#files[@]} -eq 0 ]; then
|
|
85
|
+
echo "No distributions found in dist_flat/"
|
|
86
|
+
exit 1
|
|
87
|
+
fi
|
|
88
|
+
|
|
89
|
+
- name: Publish to PyPI (OIDC)
|
|
90
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
91
|
+
with:
|
|
92
|
+
packages-dir: dist_flat
|
|
93
|
+
skip-existing: true
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
name: Build sdist
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
tags: [ 'v*' ]
|
|
7
|
+
paths:
|
|
8
|
+
- "src/**"
|
|
9
|
+
- "include/**"
|
|
10
|
+
- "CMakeLists.txt"
|
|
11
|
+
- "pyproject.toml"
|
|
12
|
+
- ".github/workflows/**"
|
|
13
|
+
pull_request:
|
|
14
|
+
paths:
|
|
15
|
+
- "src/**"
|
|
16
|
+
- "include/**"
|
|
17
|
+
- "CMakeLists.txt"
|
|
18
|
+
- "pyproject.toml"
|
|
19
|
+
- ".github/workflows/**"
|
|
20
|
+
|
|
21
|
+
concurrency:
|
|
22
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
23
|
+
cancel-in-progress: true
|
|
24
|
+
|
|
25
|
+
jobs:
|
|
26
|
+
sdist:
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
steps:
|
|
29
|
+
- uses: actions/checkout@v4
|
|
30
|
+
- uses: actions/setup-python@v5
|
|
31
|
+
with:
|
|
32
|
+
python-version: "3.12"
|
|
33
|
+
cache: "pip"
|
|
34
|
+
- name: Build sdist
|
|
35
|
+
run: |
|
|
36
|
+
python -m pip install --upgrade pip build
|
|
37
|
+
python -m build --sdist
|
|
38
|
+
ls -l dist || true
|
|
39
|
+
- name: Upload sdist
|
|
40
|
+
if: ${{ hashFiles('dist/*.tar.gz') != '' }}
|
|
41
|
+
uses: actions/upload-artifact@v4
|
|
42
|
+
with:
|
|
43
|
+
name: sdist
|
|
44
|
+
path: dist/*.tar.gz
|
|
45
|
+
if-no-files-found: error
|
|
46
|
+
retention-days: 7
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
name: Publish (TestPyPI – reuse artifacts)
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: [ "v*" ] # e.g. v0.1.0
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
# Needed to read other workflows' runs/artifacts
|
|
9
|
+
permissions:
|
|
10
|
+
actions: read
|
|
11
|
+
contents: read
|
|
12
|
+
|
|
13
|
+
concurrency:
|
|
14
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
15
|
+
cancel-in-progress: true
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
fetch-and-publish:
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v4
|
|
22
|
+
|
|
23
|
+
- name: Set up Python
|
|
24
|
+
uses: actions/setup-python@v5
|
|
25
|
+
with:
|
|
26
|
+
python-version: "3.12"
|
|
27
|
+
cache: "pip"
|
|
28
|
+
|
|
29
|
+
# Wheels from wheels workflow (download all OS-specific artifacts)
|
|
30
|
+
- name: Download wheel artifacts
|
|
31
|
+
uses: dawidd6/action-download-artifact@v3
|
|
32
|
+
with:
|
|
33
|
+
workflow: wheels.yaml
|
|
34
|
+
commit: ${{ github.sha }}
|
|
35
|
+
name: wheels-.*
|
|
36
|
+
name_is_regexp: true # match wheels-ubuntu, wheels-macos, wheels-windows
|
|
37
|
+
path: dist
|
|
38
|
+
workflow_conclusion: success
|
|
39
|
+
|
|
40
|
+
# sdist from sdist workflow
|
|
41
|
+
- name: Download sdist artifact
|
|
42
|
+
uses: dawidd6/action-download-artifact@v3
|
|
43
|
+
with:
|
|
44
|
+
workflow: sdist.yaml
|
|
45
|
+
commit: ${{ github.sha }}
|
|
46
|
+
name: sdist
|
|
47
|
+
path: dist
|
|
48
|
+
workflow_conclusion: success
|
|
49
|
+
|
|
50
|
+
# Flatten nested artifact dirs into a single folder for upload
|
|
51
|
+
- name: Collect distributions
|
|
52
|
+
run: |
|
|
53
|
+
mkdir -p dist_flat
|
|
54
|
+
find dist -type f \( -name "*.whl" -o -name "*.tar.gz" \) -exec cp {} dist_flat/ \;
|
|
55
|
+
echo "Contents to publish:"
|
|
56
|
+
ls -l dist_flat
|
|
57
|
+
|
|
58
|
+
# Optional: verify tag matches project version
|
|
59
|
+
- name: Check tag matches pyproject version
|
|
60
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
61
|
+
run: |
|
|
62
|
+
python - <<'PY'
|
|
63
|
+
import os, sys
|
|
64
|
+
try:
|
|
65
|
+
import tomllib
|
|
66
|
+
except Exception:
|
|
67
|
+
import tomli as tomllib
|
|
68
|
+
with open("pyproject.toml","rb") as f:
|
|
69
|
+
data = tomllib.load(f)
|
|
70
|
+
version = data["project"]["version"]
|
|
71
|
+
tag = os.environ["GITHUB_REF_NAME"].lstrip("v")
|
|
72
|
+
if version != tag:
|
|
73
|
+
print(f"ERROR: tag v{tag} != pyproject version {version}")
|
|
74
|
+
sys.exit(1)
|
|
75
|
+
print(f"OK: tag v{tag} matches pyproject version {version}")
|
|
76
|
+
PY
|
|
77
|
+
|
|
78
|
+
# Fail early if nothing was collected
|
|
79
|
+
- name: Ensure distributions exist
|
|
80
|
+
run: |
|
|
81
|
+
shopt -s nullglob
|
|
82
|
+
files=(dist_flat/*.whl dist_flat/*.tar.gz)
|
|
83
|
+
if [ ${#files[@]} -eq 0 ]; then
|
|
84
|
+
echo "No distributions found in dist_flat/"
|
|
85
|
+
exit 1
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
# Publish to TestPyPI
|
|
89
|
+
- name: Publish to TestPyPI
|
|
90
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
91
|
+
with:
|
|
92
|
+
repository-url: https://test.pypi.org/legacy/
|
|
93
|
+
user: __token__
|
|
94
|
+
password: ${{ secrets.TEST_PYPI_API_TOKEN }}
|
|
95
|
+
packages-dir: dist_flat
|
|
96
|
+
skip-existing: true
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
name: Build wheels
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
tags: [ 'v*' ]
|
|
7
|
+
paths:
|
|
8
|
+
- "src/**"
|
|
9
|
+
- "include/**"
|
|
10
|
+
- "tests/**"
|
|
11
|
+
- "CMakeLists.txt"
|
|
12
|
+
- "pyproject.toml"
|
|
13
|
+
- ".github/workflows/**"
|
|
14
|
+
pull_request:
|
|
15
|
+
paths:
|
|
16
|
+
- "src/**"
|
|
17
|
+
- "include/**"
|
|
18
|
+
- "tests/**"
|
|
19
|
+
- "CMakeLists.txt"
|
|
20
|
+
- "pyproject.toml"
|
|
21
|
+
- ".github/workflows/**"
|
|
22
|
+
|
|
23
|
+
concurrency:
|
|
24
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
25
|
+
cancel-in-progress: true
|
|
26
|
+
|
|
27
|
+
jobs:
|
|
28
|
+
wheels:
|
|
29
|
+
name: Wheels • ${{ matrix.os }}
|
|
30
|
+
runs-on: ${{ matrix.os }}
|
|
31
|
+
strategy:
|
|
32
|
+
fail-fast: false
|
|
33
|
+
matrix:
|
|
34
|
+
os: [ubuntu-latest, windows-latest] # , macos-latest, windows-latest]
|
|
35
|
+
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v4
|
|
38
|
+
|
|
39
|
+
- name: Set up Python (runner)
|
|
40
|
+
uses: actions/setup-python@v5
|
|
41
|
+
with:
|
|
42
|
+
python-version: "3.12"
|
|
43
|
+
cache: "pip"
|
|
44
|
+
|
|
45
|
+
- name: Install build tooling
|
|
46
|
+
run: |
|
|
47
|
+
python -m pip install --upgrade pip
|
|
48
|
+
python -m pip install cibuildwheel==2.*
|
|
49
|
+
|
|
50
|
+
- name: Build wheels with cibuildwheel
|
|
51
|
+
env:
|
|
52
|
+
# Target CPython versions
|
|
53
|
+
CIBW_BUILD: "cp313-*" # cp310-* cp311-* cp312-*
|
|
54
|
+
CIBW_SKIP: "pp* *-musllinux_*"
|
|
55
|
+
# Run tests inside wheel env
|
|
56
|
+
CIBW_TEST_REQUIRES: "pytest"
|
|
57
|
+
CIBW_TEST_COMMAND: "pytest -q {project}/tests"
|
|
58
|
+
# Architectures
|
|
59
|
+
CIBW_ARCHS_LINUX: "x86_64"
|
|
60
|
+
CIBW_ARCHS_MACOS: "universal2"
|
|
61
|
+
# Install ccache in build envs
|
|
62
|
+
CIBW_BEFORE_BUILD_LINUX: "yum -y install ccache || true"
|
|
63
|
+
CIBW_BEFORE_BUILD_MACOS: "brew install ccache || true"
|
|
64
|
+
CIBW_BEFORE_BUILD_WINDOWS: "choco install -y ccache || ver>NUL"
|
|
65
|
+
# Speed up CMake builds
|
|
66
|
+
CIBW_ENVIRONMENT: >
|
|
67
|
+
CMAKE_BUILD_PARALLEL_LEVEL=4
|
|
68
|
+
CMAKE_CXX_COMPILER_LAUNCHER=ccache
|
|
69
|
+
run: python -m cibuildwheel --output-dir wheelhouse
|
|
70
|
+
|
|
71
|
+
- name: Upload wheels
|
|
72
|
+
uses: actions/upload-artifact@v4
|
|
73
|
+
with:
|
|
74
|
+
name: wheels-${{ matrix.os }}
|
|
75
|
+
path: wheelhouse/*.whl
|
|
76
|
+
retention-days: 7
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.pyc
|
|
3
|
+
build/
|
|
4
|
+
cmake-build*/
|
|
5
|
+
CMakeCache.txt
|
|
6
|
+
CMakeFiles/
|
|
7
|
+
*.egg-info/
|
|
8
|
+
install/
|
|
9
|
+
.dist/
|
|
10
|
+
dist/
|
|
11
|
+
wheelhouse/
|
|
12
|
+
out/
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# Visual Studio user-specific files
|
|
16
|
+
.vs/
|
|
17
|
+
*.suo
|
|
18
|
+
*.user
|
|
19
|
+
*.userosscache
|
|
20
|
+
*.sln.docstates
|
|
21
|
+
|
|
22
|
+
# Visual Studio database/cache
|
|
23
|
+
*.db
|
|
24
|
+
*.db-shm
|
|
25
|
+
*.db-wal
|
|
26
|
+
*.opendb
|
|
27
|
+
*.VC.db
|
|
28
|
+
*.VC.opendb
|
|
29
|
+
|
|
30
|
+
# Visual Studio project/solution if auto-generated
|
|
31
|
+
*.vcxproj*
|
|
32
|
+
*.vcproj*
|
|
33
|
+
*.vcxproj.filters
|
|
34
|
+
|
|
35
|
+
# Other IDE clutter
|
|
36
|
+
*.log
|
|
37
|
+
*.tmp
|
|
38
|
+
.idea
|
|
39
|
+
CMakeUserPresets.json
|
|
40
|
+
|
|
41
|
+
#virtual environments:
|
|
42
|
+
.venv/
|
|
43
|
+
venv/
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
cmake_minimum_required(VERSION 3.21)
|
|
2
|
+
project(dynaplex LANGUAGES CXX)
|
|
3
|
+
|
|
4
|
+
if(NOT CMAKE_BUILD_TYPE)
|
|
5
|
+
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
|
|
6
|
+
endif()
|
|
7
|
+
|
|
8
|
+
set(CMAKE_CXX_STANDARD 20)
|
|
9
|
+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
10
|
+
|
|
11
|
+
find_package(pybind11 CONFIG REQUIRED)
|
|
12
|
+
|
|
13
|
+
# Create the Python extension module named exactly "_core"
|
|
14
|
+
pybind11_add_module(_core
|
|
15
|
+
src/bindings.cpp
|
|
16
|
+
src/hello.cpp
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
target_include_directories(_core PRIVATE include)
|
|
20
|
+
|
|
21
|
+
# Put the compiled extension inside the Python package directory "dynaplex/"
|
|
22
|
+
install(TARGETS _core
|
|
23
|
+
LIBRARY DESTINATION dynaplex
|
|
24
|
+
RUNTIME DESTINATION dynaplex
|
|
25
|
+
ARCHIVE DESTINATION dynaplex
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
# Ship the pure-Python files as part of the package
|
|
29
|
+
install(FILES
|
|
30
|
+
python/dynaplex/__init__.py
|
|
31
|
+
python/dynaplex/ops.py
|
|
32
|
+
DESTINATION dynaplex
|
|
33
|
+
)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 4,
|
|
3
|
+
"configurePresets": [
|
|
4
|
+
{
|
|
5
|
+
"name": "x64-release",
|
|
6
|
+
"displayName": "x64 release (MSVC)",
|
|
7
|
+
"generator": "Ninja",
|
|
8
|
+
"binaryDir": "${sourceDir}/out/${presetName}",
|
|
9
|
+
"cacheVariables": {
|
|
10
|
+
"CMAKE_BUILD_TYPE": "Release"
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
]
|
|
14
|
+
}
|
dynaplex-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: dynaplex
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: DynaPlex toolbox
|
|
5
|
+
Author: Willem van Jaarsveld
|
|
6
|
+
Classifier: Programming Language :: Python
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Programming Language :: C++
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Requires-Python: >=3.10
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
|
|
13
|
+
# DynaPlex
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
Minimal C++ extension (pybind11 + CMake) packaged as a Python wheel.
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
## Build (local, tested on Windhoos)
|
|
20
|
+
|
|
21
|
+
Assumes a python installation (below assumes regular, not Conda python), and a c++ toolchain.
|
|
22
|
+
|
|
23
|
+
Create venv:
|
|
24
|
+
```bash
|
|
25
|
+
python -m venv .venv
|
|
26
|
+
.\.venv\Scripts\activate.bat
|
|
27
|
+
python -m pip install --upgrade pip
|
|
28
|
+
python -m pip install build scikit-build-core pybind11 pytest
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Build wheels:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
python -m build # creates sdist and wheel in dist/ folder
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Install the wheel:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
python -m pip install dist/dynaplex-*.whl
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
If the wheel cannot be found (Windows) use this command instead:
|
|
44
|
+
```bash
|
|
45
|
+
for %f in (dist\dynaplex-*.whl) do python -m pip install --force-reinstall "%f"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Run tests:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pytest -q
|
|
52
|
+
```
|
dynaplex-0.2.0/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# DynaPlex
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
Minimal C++ extension (pybind11 + CMake) packaged as a Python wheel.
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
## Build (local, tested on Windhoos)
|
|
8
|
+
|
|
9
|
+
Assumes a python installation (below assumes regular, not Conda python), and a c++ toolchain.
|
|
10
|
+
|
|
11
|
+
Create venv:
|
|
12
|
+
```bash
|
|
13
|
+
python -m venv .venv
|
|
14
|
+
.\.venv\Scripts\activate.bat
|
|
15
|
+
python -m pip install --upgrade pip
|
|
16
|
+
python -m pip install build scikit-build-core pybind11 pytest
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Build wheels:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
python -m build # creates sdist and wheel in dist/ folder
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Install the wheel:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
python -m pip install dist/dynaplex-*.whl
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
If the wheel cannot be found (Windows) use this command instead:
|
|
32
|
+
```bash
|
|
33
|
+
for %f in (dist\dynaplex-*.whl) do python -m pip install --force-reinstall "%f"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Run tests:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pytest -q
|
|
40
|
+
```
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = [
|
|
3
|
+
"scikit-build-core>=0.10",
|
|
4
|
+
"pybind11>=2.11",
|
|
5
|
+
"setuptools_scm>=8",
|
|
6
|
+
]
|
|
7
|
+
build-backend = "scikit_build_core.build"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
[project]
|
|
11
|
+
name = "dynaplex"
|
|
12
|
+
version = "0.2.0"
|
|
13
|
+
description = "DynaPlex toolbox"
|
|
14
|
+
readme = "README.md"
|
|
15
|
+
authors = [{ name = "Willem van Jaarsveld" }]
|
|
16
|
+
requires-python = ">=3.10"
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Programming Language :: Python",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: C++",
|
|
21
|
+
"Operating System :: OS Independent",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
[tool.setuptools_scm]
|
|
26
|
+
version_scheme = "no-guess-dev"
|
|
27
|
+
local_scheme = "no-local-version"
|
|
28
|
+
|
|
29
|
+
#note: .github/workflows/wheels.yaml drives the matrix, below is ignored when publishing:
|
|
30
|
+
[tool.cibuildwheel]
|
|
31
|
+
skip = "pp* cp37* cp38* cp39*"
|
|
32
|
+
build = "cp313-*"
|
|
33
|
+
test-command = "pytest -q {project}/tests"
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#include <pybind11/pybind11.h>
|
|
2
|
+
#include "dynaplex/hello.h"
|
|
3
|
+
|
|
4
|
+
namespace py = pybind11;
|
|
5
|
+
|
|
6
|
+
PYBIND11_MODULE(_core, m) {
|
|
7
|
+
m.doc() = "dynaplex hybrid C++ core";
|
|
8
|
+
m.def("hello", []() { return dynaplex::hello(); }, "Return a friendly greeting");
|
|
9
|
+
|
|
10
|
+
m.def("goodbye", []() { return dynaplex::goodbye(); }, "Return a friendly farewell");
|
|
11
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import dynaplex as dp
|
|
2
|
+
|
|
3
|
+
def test_hello():
|
|
4
|
+
assert dp.hello() == "Hello from DynaPlex!"
|
|
5
|
+
|
|
6
|
+
def test_goodbye():
|
|
7
|
+
assert dp.goodbye() == "Goodbye from DynaPlex!"
|
|
8
|
+
|
|
9
|
+
def test_greet():
|
|
10
|
+
assert "Hello from DynaPlex!" in dp.greet("World")
|
|
11
|
+
|
|
12
|
+
def test_add():
|
|
13
|
+
assert dp.add(2, 3) == 5
|