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.
Files changed (135) hide show
  1. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/.github/workflows/build-wheels.yml +57 -16
  2. pyrestoolbox-3.7.0/.github/workflows/tests.yml +64 -0
  3. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/.gitignore +7 -6
  4. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/Cargo.lock +1 -1
  5. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/Cargo.toml +1 -1
  6. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/PKG-INFO +1 -1
  7. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyproject.toml +1 -1
  8. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/__init__.py +39 -7
  9. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/_accelerator.py +248 -216
  10. pyrestoolbox-3.7.0/pyrestoolbox/brine/_lib_salting_library.py +163 -0
  11. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/brine/_lib_vle_engine.py +55 -433
  12. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/brine/brine.py +1928 -1950
  13. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/classes/classes.py +3 -4
  14. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/dca/dca.py +599 -20
  15. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/brine.rst +21 -17
  16. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/changelist.rst +420 -350
  17. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/dca.rst +375 -11
  18. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/gas.rst +18 -19
  19. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/matbal.rst +423 -423
  20. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/nodal.rst +962 -962
  21. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/oil.rst +10 -8
  22. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/recommend.rst +281 -281
  23. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/simtools.rst +2 -2
  24. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/gas/_hydrate.py +24 -27
  25. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/gas/gas.py +124 -148
  26. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/layer/layer.py +1 -1
  27. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/matbal/matbal.py +5 -0
  28. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/nodal/nodal.py +135 -75
  29. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/oil/__init__.py +1 -1
  30. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/oil/_compressibility.py +12 -4
  31. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/oil/_constants.py +3 -3
  32. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/oil/_correlations.py +79 -40
  33. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/oil/_density.py +9 -3
  34. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/oil/_rate.py +35 -23
  35. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/oil/_separator.py +8 -3
  36. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/oil/_tables.py +41 -29
  37. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/oil/_utils.py +2 -1
  38. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/plyasunov/iapws_if97.py +155 -152
  39. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/recommend/recommend.py +1 -1
  40. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/shared_fns/shared_fns.py +50 -2
  41. pyrestoolbox-3.7.0/pyrestoolbox/simtools/__init__.py +56 -0
  42. pyrestoolbox-3.7.0/pyrestoolbox/simtools/_aquifer.py +197 -0
  43. pyrestoolbox-3.7.0/pyrestoolbox/simtools/_decks.py +417 -0
  44. pyrestoolbox-3.7.0/pyrestoolbox/simtools/_pvt_tables.py +360 -0
  45. pyrestoolbox-3.7.0/pyrestoolbox/simtools/_relperm.py +462 -0
  46. pyrestoolbox-3.7.0/pyrestoolbox/simtools/_vfp.py +643 -0
  47. pyrestoolbox-3.7.0/pyrestoolbox/simtools/simtools.py +58 -0
  48. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/validate/validate.py +9 -0
  49. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/gas_viscosity/mod.rs +2 -2
  50. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/lib.rs +1 -0
  51. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/spycher_pruess/solubility.rs +5 -1
  52. pyrestoolbox-3.7.0/src/vlp/constants.rs +162 -0
  53. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vlp/holdup_bb.rs +122 -116
  54. pyrestoolbox-3.7.0/src/vlp/holdup_gray.rs +67 -0
  55. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vlp/holdup_wg.rs +7 -9
  56. pyrestoolbox-3.7.0/src/vlp/march.rs +590 -0
  57. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vlp/mod.rs +146 -135
  58. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vlp/pvt_helpers.rs +4 -10
  59. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vlp/static_column.rs +5 -6
  60. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/zfactor/mod.rs +21 -19
  61. pyrestoolbox-3.5.0/pyrestoolbox/brine/_lib_salting_library.py +0 -693
  62. pyrestoolbox-3.5.0/pyrestoolbox/simtools/__init__.py +0 -1
  63. pyrestoolbox-3.5.0/pyrestoolbox/simtools/simtools.py +0 -2033
  64. pyrestoolbox-3.5.0/src/vlp/holdup_gray.rs +0 -69
  65. pyrestoolbox-3.5.0/src/vlp/holdup_hb.rs +0 -84
  66. pyrestoolbox-3.5.0/src/vlp/segment_gas.rs +0 -546
  67. pyrestoolbox-3.5.0/src/vlp/segment_oil.rs +0 -618
  68. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/LICENSE +0 -0
  69. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/MANIFEST.in +0 -0
  70. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/README.rst +0 -0
  71. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/ResToolbox/privacy_policy.md +0 -0
  72. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/benchmark_rust_vs_python.py +0 -0
  73. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/build_pure_python.py +0 -0
  74. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/brine/__init__.py +0 -0
  75. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/classes/__init__.py +0 -0
  76. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/constants/__init__.py +0 -0
  77. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/constants/constants.py +0 -0
  78. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/dca/__init__.py +0 -0
  79. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/examples.ipynb +0 -0
  80. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/img/bot.png +0 -0
  81. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/img/bot_PVTO.png +0 -0
  82. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/img/bot_img.png +0 -0
  83. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/img/dry_gas.png +0 -0
  84. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/img/grid_sat_df.png +0 -0
  85. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/img/influence.png +0 -0
  86. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/img/properties_df.png +0 -0
  87. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/img/sgof.png +0 -0
  88. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/img/swof.png +0 -0
  89. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/layer.rst +0 -0
  90. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/library.rst +0 -0
  91. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/nodal_examples.ipynb +0 -0
  92. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/nodal_hydrate_demo.ipynb +0 -0
  93. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/docs/sensitivity.rst +0 -0
  94. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/gas/__init__.py +0 -0
  95. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/layer/__init__.py +0 -0
  96. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/library/__init__.py +0 -0
  97. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/library/component_library.xlsx +0 -0
  98. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/library/library.py +0 -0
  99. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/matbal/__init__.py +0 -0
  100. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/nodal/__init__.py +0 -0
  101. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/oil/_harmonize.py +0 -0
  102. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/oil/_pvt_class.py +0 -0
  103. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/plyasunov/__init__.py +0 -0
  104. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/plyasunov/plyasunov_model.py +0 -0
  105. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/plyasunov/water_properties.py +0 -0
  106. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/recommend/__init__.py +0 -0
  107. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/sensitivity/__init__.py +0 -0
  108. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/sensitivity/sensitivity.py +0 -0
  109. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/shared_fns/__init__.py +0 -0
  110. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/pyrestoolbox/validate/__init__.py +0 -0
  111. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/setup.cfg +0 -0
  112. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/setup.py +0 -0
  113. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/bessel.rs +0 -0
  114. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/critical_properties/mod.rs +0 -0
  115. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/dca/hyperbolic.rs +0 -0
  116. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/dca/mod.rs +0 -0
  117. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/dca/ransac.rs +0 -0
  118. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/gwr.rs +0 -0
  119. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/matbal/mod.rs +0 -0
  120. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/matbal/objective.rs +0 -0
  121. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/oil/density.rs +0 -0
  122. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/oil/mod.rs +0 -0
  123. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/pseudopressure.rs +0 -0
  124. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/spycher_pruess/mod.rs +0 -0
  125. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vle/alpha.rs +0 -0
  126. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vle/bip.rs +0 -0
  127. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vle/components.rs +0 -0
  128. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vle/eos.rs +0 -0
  129. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vle/flash.rs +0 -0
  130. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vle/fugacity.rs +0 -0
  131. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vle/k_init.rs +0 -0
  132. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vle/mod.rs +0 -0
  133. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vle/rachford_rice.rs +0 -0
  134. {pyrestoolbox-3.5.0 → pyrestoolbox-3.7.0}/src/vlp/friction.rs +0 -0
  135. {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@v4
23
+ - uses: actions/checkout@v5
24
24
 
25
- - uses: actions/setup-python@v5
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 (scipy needs OpenBLAS absent in manylinux), macOS (MPFR symbol issue),
78
- # and cp38/cp39 (dependency ilt-inversion may not have matching wheels on PyPI yet)
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@v4
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@v4
98
+ - uses: actions/checkout@v5
93
99
 
94
- - uses: actions/setup-python@v5
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@v4
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@v4
127
+ - uses: actions/checkout@v5
122
128
 
123
- - uses: actions/setup-python@v5
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@v4
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@v4
149
+ - uses: actions/checkout@v5
144
150
 
145
- - uses: actions/setup-python@v5
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@v4
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 # trusted publishing
179
+ id-token: write # trusted publishing
180
+ contents: write # create the GitHub Release
174
181
  steps:
175
- - uses: actions/download-artifact@v4
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
@@ -152,7 +152,7 @@ dependencies = [
152
152
 
153
153
  [[package]]
154
154
  name = "pyrestoolbox-native"
155
- version = "0.1.0"
155
+ version = "3.7.0"
156
156
  dependencies = [
157
157
  "pyo3",
158
158
  "rug",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "pyrestoolbox-native"
3
- version = "0.1.0"
3
+ version = "3.7.0"
4
4
  edition = "2021"
5
5
  license = "GPL-3.0-or-later"
6
6
  description = "Rust acceleration extensions for pyResToolbox"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyrestoolbox
3
- Version: 3.5.0
3
+ Version: 3.7.0
4
4
  Classifier: Programming Language :: Python :: 3
5
5
  Classifier: Programming Language :: Rust
6
6
  Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "pyrestoolbox"
7
- version = "3.5.0"
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
- else:
74
- try:
75
- return globals()[name]
76
- except KeyError:
77
- raise AttributeError(
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
+ )