pyrestoolbox 3.5.0__tar.gz → 3.7.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.
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/.github/workflows/build-wheels.yml +57 -16
- pyrestoolbox-3.7.0/.github/workflows/tests.yml +64 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/.gitignore +7 -6
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/Cargo.lock +1 -1
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/Cargo.toml +1 -1
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/PKG-INFO +1 -1
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyproject.toml +1 -1
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/__init__.py +39 -7
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/_accelerator.py +248 -216
- pyrestoolbox-3.7.0/pyrestoolbox/brine/_lib_salting_library.py +163 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/brine/_lib_vle_engine.py +55 -433
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/brine/brine.py +1928 -1950
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/classes/classes.py +3 -4
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/dca/dca.py +599 -20
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/brine.rst +21 -17
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/changelist.rst +420 -350
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/dca.rst +375 -11
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/gas.rst +18 -19
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/matbal.rst +423 -423
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/nodal.rst +962 -962
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/oil.rst +10 -8
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/recommend.rst +281 -281
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/simtools.rst +2 -2
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/gas/_hydrate.py +24 -27
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/gas/gas.py +124 -148
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/layer/layer.py +1 -1
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/matbal/matbal.py +5 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/nodal/nodal.py +135 -75
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/oil/__init__.py +1 -1
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/oil/_compressibility.py +12 -4
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/oil/_constants.py +3 -3
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/oil/_correlations.py +79 -40
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/oil/_density.py +9 -3
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/oil/_rate.py +35 -23
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/oil/_separator.py +8 -3
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/oil/_tables.py +41 -29
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/oil/_utils.py +2 -1
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/plyasunov/iapws_if97.py +155 -152
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/recommend/recommend.py +1 -1
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/shared_fns/shared_fns.py +50 -2
- pyrestoolbox-3.7.0/pyrestoolbox/simtools/__init__.py +56 -0
- pyrestoolbox-3.7.0/pyrestoolbox/simtools/_aquifer.py +197 -0
- pyrestoolbox-3.7.0/pyrestoolbox/simtools/_decks.py +417 -0
- pyrestoolbox-3.7.0/pyrestoolbox/simtools/_pvt_tables.py +360 -0
- pyrestoolbox-3.7.0/pyrestoolbox/simtools/_relperm.py +462 -0
- pyrestoolbox-3.7.0/pyrestoolbox/simtools/_vfp.py +643 -0
- pyrestoolbox-3.7.0/pyrestoolbox/simtools/simtools.py +58 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/validate/validate.py +9 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/gas_viscosity/mod.rs +2 -2
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/lib.rs +1 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/spycher_pruess/solubility.rs +5 -1
- pyrestoolbox-3.7.0/src/vlp/constants.rs +162 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vlp/holdup_bb.rs +122 -116
- pyrestoolbox-3.7.0/src/vlp/holdup_gray.rs +67 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vlp/holdup_wg.rs +7 -9
- pyrestoolbox-3.7.0/src/vlp/march.rs +590 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vlp/mod.rs +146 -135
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vlp/pvt_helpers.rs +4 -10
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vlp/static_column.rs +5 -6
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/zfactor/mod.rs +21 -19
- pyrestoolbox-3.5.0/pyrestoolbox/brine/_lib_salting_library.py +0 -693
- pyrestoolbox-3.5.0/pyrestoolbox/simtools/__init__.py +0 -1
- pyrestoolbox-3.5.0/pyrestoolbox/simtools/simtools.py +0 -2033
- pyrestoolbox-3.5.0/src/vlp/holdup_gray.rs +0 -69
- pyrestoolbox-3.5.0/src/vlp/holdup_hb.rs +0 -84
- pyrestoolbox-3.5.0/src/vlp/segment_gas.rs +0 -546
- pyrestoolbox-3.5.0/src/vlp/segment_oil.rs +0 -618
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/LICENSE +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/MANIFEST.in +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/README.rst +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/ResToolbox/privacy_policy.md +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/benchmark_rust_vs_python.py +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/build_pure_python.py +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/brine/__init__.py +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/classes/__init__.py +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/constants/__init__.py +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/constants/constants.py +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/dca/__init__.py +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/examples.ipynb +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/img/bot.png +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/img/bot_PVTO.png +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/img/bot_img.png +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/img/dry_gas.png +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/img/grid_sat_df.png +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/img/influence.png +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/img/properties_df.png +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/img/sgof.png +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/img/swof.png +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/layer.rst +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/library.rst +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/nodal_examples.ipynb +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/nodal_hydrate_demo.ipynb +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/sensitivity.rst +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/gas/__init__.py +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/layer/__init__.py +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/library/__init__.py +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/library/component_library.xlsx +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/library/library.py +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/matbal/__init__.py +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/nodal/__init__.py +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/oil/_harmonize.py +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/oil/_pvt_class.py +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/plyasunov/__init__.py +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/plyasunov/plyasunov_model.py +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/plyasunov/water_properties.py +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/recommend/__init__.py +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/sensitivity/__init__.py +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/sensitivity/sensitivity.py +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/shared_fns/__init__.py +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/validate/__init__.py +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/setup.cfg +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/setup.py +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/bessel.rs +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/critical_properties/mod.rs +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/dca/hyperbolic.rs +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/dca/mod.rs +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/dca/ransac.rs +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/gwr.rs +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/matbal/mod.rs +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/matbal/objective.rs +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/oil/density.rs +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/oil/mod.rs +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/pseudopressure.rs +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/spycher_pruess/mod.rs +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vle/alpha.rs +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vle/bip.rs +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vle/components.rs +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vle/eos.rs +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vle/flash.rs +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vle/fugacity.rs +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vle/k_init.rs +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vle/mod.rs +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vle/rachford_rice.rs +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vlp/friction.rs +0 -0
- {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vlp/ift.rs +0 -0
|
@@ -20,9 +20,9 @@ jobs:
|
|
|
20
20
|
matrix:
|
|
21
21
|
os: [ubuntu-latest, macos-14, windows-latest]
|
|
22
22
|
steps:
|
|
23
|
-
- uses: actions/checkout@
|
|
23
|
+
- uses: actions/checkout@v5
|
|
24
24
|
|
|
25
|
-
- uses: actions/setup-python@
|
|
25
|
+
- uses: actions/setup-python@v6
|
|
26
26
|
with:
|
|
27
27
|
python-version: "3.12"
|
|
28
28
|
|
|
@@ -74,11 +74,17 @@ jobs:
|
|
|
74
74
|
CIBW_TEST_COMMAND: >
|
|
75
75
|
python -c "from pyrestoolbox._accelerator import get_status; s = get_status(); print(s); assert s['rust_available'], f'Rust not loaded: {s}'"
|
|
76
76
|
CIBW_TEST_REQUIRES: "numpy"
|
|
77
|
-
# Skip tests on Linux
|
|
78
|
-
#
|
|
77
|
+
# Skip tests on Linux: installing the wheel in the manylinux test
|
|
78
|
+
# container pulls scipy, whose binary wheels need a newer glibc than
|
|
79
|
+
# the container has, so pip builds scipy from source and fails on
|
|
80
|
+
# missing OpenBLAS (this broke the v3.6.0 first build attempt - the
|
|
81
|
+
# skip is load-bearing, do not remove it). Linux import + full-suite
|
|
82
|
+
# coverage lives in .github/workflows/tests.yml instead.
|
|
83
|
+
# Also skip macOS (MPFR symbol issue) and cp38/cp39 (dependency
|
|
84
|
+
# ilt-inversion may not have matching wheels on PyPI yet).
|
|
79
85
|
CIBW_TEST_SKIP: "*-manylinux* *-macosx* cp38-* cp39-*"
|
|
80
86
|
|
|
81
|
-
- uses: actions/upload-artifact@
|
|
87
|
+
- uses: actions/upload-artifact@v6
|
|
82
88
|
with:
|
|
83
89
|
name: wheels-${{ matrix.os }}
|
|
84
90
|
path: ./wheelhouse/*.whl
|
|
@@ -89,9 +95,9 @@ jobs:
|
|
|
89
95
|
runs-on: macos-13
|
|
90
96
|
if: false # Enable when macos-13 runners are available, or use cross-compilation
|
|
91
97
|
steps:
|
|
92
|
-
- uses: actions/checkout@
|
|
98
|
+
- uses: actions/checkout@v5
|
|
93
99
|
|
|
94
|
-
- uses: actions/setup-python@
|
|
100
|
+
- uses: actions/setup-python@v6
|
|
95
101
|
with:
|
|
96
102
|
python-version: "3.12"
|
|
97
103
|
|
|
@@ -108,7 +114,7 @@ jobs:
|
|
|
108
114
|
python -c "from pyrestoolbox._accelerator import get_status; s = get_status(); print(s); assert s['rust_available'], f'Rust not loaded: {s}'"
|
|
109
115
|
CIBW_TEST_REQUIRES: "numpy"
|
|
110
116
|
|
|
111
|
-
- uses: actions/upload-artifact@
|
|
117
|
+
- uses: actions/upload-artifact@v6
|
|
112
118
|
with:
|
|
113
119
|
name: wheels-macos-x86
|
|
114
120
|
path: ./wheelhouse/*.whl
|
|
@@ -118,9 +124,9 @@ jobs:
|
|
|
118
124
|
name: Build pure-Python wheel
|
|
119
125
|
runs-on: ubuntu-latest
|
|
120
126
|
steps:
|
|
121
|
-
- uses: actions/checkout@
|
|
127
|
+
- uses: actions/checkout@v5
|
|
122
128
|
|
|
123
|
-
- uses: actions/setup-python@
|
|
129
|
+
- uses: actions/setup-python@v6
|
|
124
130
|
with:
|
|
125
131
|
python-version: "3.12"
|
|
126
132
|
|
|
@@ -130,7 +136,7 @@ jobs:
|
|
|
130
136
|
- name: Build pure-Python wheel
|
|
131
137
|
run: python build_pure_python.py
|
|
132
138
|
|
|
133
|
-
- uses: actions/upload-artifact@
|
|
139
|
+
- uses: actions/upload-artifact@v6
|
|
134
140
|
with:
|
|
135
141
|
name: wheels-pure-python
|
|
136
142
|
path: ./dist/*.whl
|
|
@@ -140,9 +146,9 @@ jobs:
|
|
|
140
146
|
name: Build source distribution
|
|
141
147
|
runs-on: ubuntu-latest
|
|
142
148
|
steps:
|
|
143
|
-
- uses: actions/checkout@
|
|
149
|
+
- uses: actions/checkout@v5
|
|
144
150
|
|
|
145
|
-
- uses: actions/setup-python@
|
|
151
|
+
- uses: actions/setup-python@v6
|
|
146
152
|
with:
|
|
147
153
|
python-version: "3.12"
|
|
148
154
|
|
|
@@ -155,7 +161,7 @@ jobs:
|
|
|
155
161
|
- name: Build sdist
|
|
156
162
|
run: maturin sdist --out dist
|
|
157
163
|
|
|
158
|
-
- uses: actions/upload-artifact@
|
|
164
|
+
- uses: actions/upload-artifact@v6
|
|
159
165
|
with:
|
|
160
166
|
name: sdist
|
|
161
167
|
path: ./dist/*.tar.gz
|
|
@@ -170,9 +176,10 @@ jobs:
|
|
|
170
176
|
name: pypi
|
|
171
177
|
url: https://pypi.org/project/pyrestoolbox/
|
|
172
178
|
permissions:
|
|
173
|
-
id-token: write
|
|
179
|
+
id-token: write # trusted publishing
|
|
180
|
+
contents: write # create the GitHub Release
|
|
174
181
|
steps:
|
|
175
|
-
- uses: actions/download-artifact@
|
|
182
|
+
- uses: actions/download-artifact@v7
|
|
176
183
|
with:
|
|
177
184
|
path: dist
|
|
178
185
|
merge-multiple: true
|
|
@@ -181,3 +188,37 @@ jobs:
|
|
|
181
188
|
uses: pypa/gh-action-pypi-publish@release/v1
|
|
182
189
|
with:
|
|
183
190
|
packages-dir: dist/
|
|
191
|
+
|
|
192
|
+
# ── Create a notes-only GitHub Release (no binaries; PyPI is canonical) ──
|
|
193
|
+
- uses: actions/checkout@v5
|
|
194
|
+
|
|
195
|
+
- name: Extract release notes from changelist
|
|
196
|
+
run: |
|
|
197
|
+
VERSION="${GITHUB_REF_NAME#v}"
|
|
198
|
+
python3 - "$VERSION" > release_notes.md <<'PY'
|
|
199
|
+
import sys, re
|
|
200
|
+
ver = sys.argv[1]
|
|
201
|
+
out, capture = [], False
|
|
202
|
+
for ln in open('pyrestoolbox/docs/changelist.rst', encoding='utf-8').read().splitlines():
|
|
203
|
+
if ln.startswith('Changelist in '):
|
|
204
|
+
if capture:
|
|
205
|
+
break
|
|
206
|
+
capture = (ln.strip() == f'Changelist in {ver}:')
|
|
207
|
+
continue
|
|
208
|
+
if capture:
|
|
209
|
+
out.append(ln)
|
|
210
|
+
body = '\n'.join(out).strip()
|
|
211
|
+
# Light RST -> Markdown cleanup so it renders on the Releases page
|
|
212
|
+
body = re.sub(r'\\?\s?:sub:`([^`]*)`(?:\\ )?', r'\1', body) # S\ :sub:`hvf`\ -> Shvf
|
|
213
|
+
body = re.sub(r'``([^`]+)``', r'`\1`', body) # ``x`` -> `x`
|
|
214
|
+
body = body.replace('\\ ', ' ')
|
|
215
|
+
if not body:
|
|
216
|
+
body = f'Release {ver}. See docs/changelist.rst for details.'
|
|
217
|
+
print(body)
|
|
218
|
+
PY
|
|
219
|
+
|
|
220
|
+
- name: Create GitHub Release
|
|
221
|
+
uses: softprops/action-gh-release@v3
|
|
222
|
+
with:
|
|
223
|
+
name: ${{ github.ref_name }}
|
|
224
|
+
body_path: release_notes.md
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
# ── Pure-Python test suite (no Rust extension) ───────────────────────
|
|
14
|
+
test-pure-python:
|
|
15
|
+
name: Pure Python (PYRESTOOLBOX_NO_RUST=1)
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v5
|
|
19
|
+
|
|
20
|
+
- uses: actions/setup-python@v6
|
|
21
|
+
with:
|
|
22
|
+
python-version: "3.10"
|
|
23
|
+
|
|
24
|
+
- name: Install dependencies
|
|
25
|
+
run: pip install numpy scipy pandas tabulate openpyxl mpmath ilt-inversion pytest
|
|
26
|
+
|
|
27
|
+
- name: Run test suite (pure Python)
|
|
28
|
+
env:
|
|
29
|
+
PYRESTOOLBOX_NO_RUST: "1"
|
|
30
|
+
run: python3 -m pytest pyrestoolbox/tests/ -q
|
|
31
|
+
|
|
32
|
+
# ── Full test suite with Rust extension (includes parity tests) ──────
|
|
33
|
+
test-with-rust:
|
|
34
|
+
name: Rust-accelerated (parity tests)
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v5
|
|
38
|
+
|
|
39
|
+
- uses: actions/setup-python@v6
|
|
40
|
+
with:
|
|
41
|
+
python-version: "3.10"
|
|
42
|
+
|
|
43
|
+
- name: Install Rust toolchain
|
|
44
|
+
uses: dtolnay/rust-toolchain@stable
|
|
45
|
+
|
|
46
|
+
- name: Install m4 (needed by gmp-mpfr-sys for the rug crate)
|
|
47
|
+
run: sudo apt-get update -qq && sudo apt-get install -y -qq m4
|
|
48
|
+
|
|
49
|
+
- name: Install dependencies
|
|
50
|
+
run: pip install numpy scipy pandas tabulate openpyxl mpmath ilt-inversion pytest maturin
|
|
51
|
+
|
|
52
|
+
- name: Build Rust extension wheel
|
|
53
|
+
run: maturin build --release --out dist
|
|
54
|
+
|
|
55
|
+
# Tests import the repo source tree, so the compiled extension must
|
|
56
|
+
# live inside it for the Rust paths to load.
|
|
57
|
+
- name: Copy extension into source tree
|
|
58
|
+
run: unzip -o dist/*.whl "pyrestoolbox/_native*" -d .
|
|
59
|
+
|
|
60
|
+
- name: Verify Rust extension loads
|
|
61
|
+
run: python3 -c "from pyrestoolbox._accelerator import get_status; s = get_status(); print(s); assert s['rust_available'], s"
|
|
62
|
+
|
|
63
|
+
- name: Run full test suite (Rust + parity)
|
|
64
|
+
run: python3 -m pytest pyrestoolbox/tests/ -q
|
|
@@ -18,6 +18,7 @@ __pycache__/
|
|
|
18
18
|
# Claude Code
|
|
19
19
|
.claude/
|
|
20
20
|
CLAUDE.md
|
|
21
|
+
HANDOFF.md
|
|
21
22
|
|
|
22
23
|
# Jupyter checkpoints
|
|
23
24
|
.ipynb_checkpoints/
|
|
@@ -36,9 +37,9 @@ target/
|
|
|
36
37
|
*.rtf
|
|
37
38
|
*.VFP
|
|
38
39
|
*.png
|
|
39
|
-
|
|
40
|
-
# Standalone ILT development (lives in ilt-inversion repo)
|
|
41
|
-
ilt/
|
|
42
|
-
benchmark_ilt.py
|
|
43
|
-
benchmark_rust.py
|
|
44
|
-
BUILD_INSTRUCTIONS.txt
|
|
40
|
+
|
|
41
|
+
# Standalone ILT development (lives in ilt-inversion repo)
|
|
42
|
+
ilt/
|
|
43
|
+
benchmark_ilt.py
|
|
44
|
+
benchmark_rust.py
|
|
45
|
+
BUILD_INSTRUCTIONS.txt
|
|
@@ -4,7 +4,7 @@ build-backend = "maturin"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pyrestoolbox"
|
|
7
|
-
version = "3.
|
|
7
|
+
version = "3.7.0"
|
|
8
8
|
description = "pyResToolbox - A collection of Reservoir Engineering Utilities"
|
|
9
9
|
license = {text = "GPL-3.0-or-later"}
|
|
10
10
|
authors = [{name = "Mark W. Burgoyne", email = "mark.w.burgoyne@gmail.com"}]
|
|
@@ -67,13 +67,45 @@ def __dir__():
|
|
|
67
67
|
return __all__
|
|
68
68
|
|
|
69
69
|
|
|
70
|
+
def _get_version():
|
|
71
|
+
"""Resolve the package version lazily.
|
|
72
|
+
|
|
73
|
+
A repo checkout has pyproject.toml next to the package directory; read it
|
|
74
|
+
so the version matches the imported code even when a different release is
|
|
75
|
+
installed in site-packages. Installed packages have no adjacent
|
|
76
|
+
pyproject.toml and use distribution metadata instead.
|
|
77
|
+
"""
|
|
78
|
+
import os
|
|
79
|
+
import re
|
|
80
|
+
pyproject = os.path.join(
|
|
81
|
+
os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
|
|
82
|
+
'pyproject.toml',
|
|
83
|
+
)
|
|
84
|
+
try:
|
|
85
|
+
with open(pyproject, encoding='utf-8') as f:
|
|
86
|
+
text = f.read()
|
|
87
|
+
if re.search(r'^name\s*=\s*"pyrestoolbox"', text, re.M):
|
|
88
|
+
match = re.search(r'^version\s*=\s*"([^"]+)"', text, re.M)
|
|
89
|
+
if match:
|
|
90
|
+
return match.group(1)
|
|
91
|
+
except OSError:
|
|
92
|
+
pass
|
|
93
|
+
try:
|
|
94
|
+
from importlib.metadata import version, PackageNotFoundError
|
|
95
|
+
try:
|
|
96
|
+
return version('pyrestoolbox')
|
|
97
|
+
except PackageNotFoundError:
|
|
98
|
+
pass
|
|
99
|
+
except ImportError: # Python < 3.8 has no importlib.metadata
|
|
100
|
+
pass
|
|
101
|
+
return 'unknown'
|
|
102
|
+
|
|
103
|
+
|
|
70
104
|
def __getattr__(name):
|
|
71
105
|
if name in submodules:
|
|
72
106
|
return importlib.import_module(f'pyrestoolbox.{name}')
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
f"Module 'pyrestoolbox' has no attribute '{name}'"
|
|
79
|
-
)
|
|
107
|
+
if name == '__version__':
|
|
108
|
+
return _get_version()
|
|
109
|
+
raise AttributeError(
|
|
110
|
+
f"Module 'pyrestoolbox' has no attribute '{name}'"
|
|
111
|
+
)
|