pyflightstream 0.2.0__tar.gz → 0.3.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.
- pyflightstream-0.3.0/PKG-INFO +191 -0
- pyflightstream-0.3.0/README.md +146 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/pyproject.toml +27 -2
- pyflightstream-0.3.0/src/pyflightstream/__init__.py +79 -0
- pyflightstream-0.3.0/src/pyflightstream/_deprecations.py +121 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/cases/__init__.py +3 -3
- pyflightstream-0.3.0/src/pyflightstream/cases/cli.py +165 -0
- pyflightstream-0.3.0/src/pyflightstream/cases/matrix.py +747 -0
- pyflightstream-0.3.0/src/pyflightstream/cases/matrix_legacy.py +40 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/commands/__init__.py +43 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/commands/advanced_settings.yaml +4 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/commands/boundary_conditions.yaml +153 -153
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/commands/motion_definitions.yaml +1 -1
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/commands/solver_analysis.yaml +3 -2
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/commands/solver_settings.yaml +8 -2
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/commands/streamlines.yaml +1 -1
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/commands/surface_sections.yaml +4 -4
- pyflightstream-0.3.0/src/pyflightstream/exceptions.py +91 -0
- pyflightstream-0.3.0/src/pyflightstream/files/__init__.py +31 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/fsi/__init__.py +57 -57
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/fsi/driver.py +4 -9
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/fsi/state.py +194 -181
- pyflightstream-0.3.0/src/pyflightstream/options.py +334 -0
- pyflightstream-0.3.0/src/pyflightstream/overview.py +292 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/probes/geometry.py +3 -1
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/qa/cli.py +405 -364
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/qa/physics.py +43 -3
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/reference.py +319 -9
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/results/__init__.py +36 -0
- pyflightstream-0.3.0/src/pyflightstream/results/tables.py +574 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/run/__init__.py +347 -15
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/script/__init__.py +167 -67
- pyflightstream-0.3.0/src/pyflightstream/script/entities.py +444 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/script/helpers.py +469 -51
- pyflightstream-0.3.0/src/pyflightstream/script/solver_setup.py +441 -0
- pyflightstream-0.3.0/src/pyflightstream/testing.py +176 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/versions.py +28 -2
- {pyflightstream-0.2.0/src/pyflightstream/files → pyflightstream-0.3.0/src/pyflightstream/workspace}/__init__.py +189 -11
- pyflightstream-0.3.0/src/pyflightstream/workspace/cli.py +60 -0
- pyflightstream-0.3.0/src/pyflightstream/workspace/inputs.py +532 -0
- pyflightstream-0.3.0/src/pyflightstream/workspace/naming.py +265 -0
- pyflightstream-0.3.0/src/pyflightstream.egg-info/PKG-INFO +191 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream.egg-info/SOURCES.txt +33 -3
- pyflightstream-0.3.0/src/pyflightstream.egg-info/entry_points.txt +5 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream.egg-info/requires.txt +2 -1
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_command_db.py +32 -0
- pyflightstream-0.3.0/tests/test_conventions.py +135 -0
- pyflightstream-0.3.0/tests/test_deprecation_deadline.py +142 -0
- pyflightstream-0.3.0/tests/test_error_messages.py +169 -0
- pyflightstream-0.3.0/tests/test_examples_isolation.py +61 -0
- pyflightstream-0.3.0/tests/test_exceptions_catalog.py +105 -0
- pyflightstream-0.3.0/tests/test_matrix.py +224 -0
- pyflightstream-0.3.0/tests/test_matrix_cli.py +154 -0
- pyflightstream-0.3.0/tests/test_matrix_run.py +337 -0
- pyflightstream-0.3.0/tests/test_metadata_currency.py +77 -0
- pyflightstream-0.3.0/tests/test_options.py +174 -0
- pyflightstream-0.3.0/tests/test_overview.py +110 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_package_imports.py +2 -2
- pyflightstream-0.3.0/tests/test_public_api.py +173 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_qa_physics.py +39 -1
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_reference.py +51 -0
- pyflightstream-0.3.0/tests/test_registry_hygiene.py +63 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_run_campaign.py +189 -2
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_script.py +1 -1
- pyflightstream-0.3.0/tests/test_script_entities.py +220 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_script_helpers.py +10 -4
- pyflightstream-0.3.0/tests/test_solver_setup.py +329 -0
- pyflightstream-0.3.0/tests/test_tables.py +292 -0
- pyflightstream-0.3.0/tests/test_testing.py +92 -0
- pyflightstream-0.3.0/tests/test_workspace.py +426 -0
- pyflightstream-0.2.0/PKG-INFO +0 -88
- pyflightstream-0.2.0/README.md +0 -55
- pyflightstream-0.2.0/src/pyflightstream/__init__.py +0 -27
- pyflightstream-0.2.0/src/pyflightstream/cases/matrix_legacy.py +0 -337
- pyflightstream-0.2.0/src/pyflightstream.egg-info/PKG-INFO +0 -88
- pyflightstream-0.2.0/src/pyflightstream.egg-info/entry_points.txt +0 -3
- pyflightstream-0.2.0/tests/test_files.py +0 -144
- pyflightstream-0.2.0/tests/test_matrix_legacy.py +0 -106
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/LICENSE +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/setup.cfg +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/commands/_meta.yaml +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/commands/actuators.yaml +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/commands/aeroelastic_coupling.yaml +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/commands/ccs_wing_mesh.yaml +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/commands/coordinate_systems.yaml +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/commands/file_io.yaml +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/commands/mesh_import_export.yaml +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/commands/probe_points.yaml +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/commands/runtime_settings.yaml +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/commands/scenes.yaml +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/commands/script_controls.yaml +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/commands/simulation_controls.yaml +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/commands/solver_export.yaml +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/commands/solver_initialization.yaml +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/commands/sweeper.yaml +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/commands/unsteady_solver.yaml +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/commands/volume_sections.yaml +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/farfield/__init__.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/fsi/beam.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/fsi/centrifugal.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/fsi/cli.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/fsi/config.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/fsi/kinematics.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/fsi/loads.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/fsi/nodes.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/post/__init__.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/post/writers.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/probes/__init__.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/probes/planar.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/qa/__init__.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/qa/compat.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/qa/drift.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/qa/geometry.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/qa/probes.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/qa/references/PHY-01.yaml +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/qa/references/PHY-02.yaml +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/qa/references/PHY-05.yaml +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/qa/references/PHY-06.yaml +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/qa/references/SMI-01.yaml +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/qa/references/SMI-02.yaml +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream/qa/specs.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream.egg-info/dependency_links.txt +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/src/pyflightstream.egg-info/top_level.txt +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_cases.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_farfield.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_fsi_beam.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_fsi_centrifugal.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_fsi_cli.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_fsi_config.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_fsi_driver.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_fsi_kinematics.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_fsi_loads.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_fsi_sources.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_fsi_wing.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_house_style.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_post_writers.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_probes.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_probes_geometry.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_probes_planar.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_qa_compat.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_qa_drift.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_qa_geometry.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_qa_probes.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_results.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_run.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_run_preproc.py +0 -0
- {pyflightstream-0.2.0 → pyflightstream-0.3.0}/tests/test_versions.py +0 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyflightstream
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Version-aware, didactic Python driver for the FlightStream panel-method solver
|
|
5
|
+
Author: Geovana Neves
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Repository, https://github.com/nevesgeovana/pyflightstream
|
|
8
|
+
Project-URL: Documentation, https://nevesgeovana.github.io/pyflightstream/
|
|
9
|
+
Project-URL: Changelog, https://github.com/nevesgeovana/pyflightstream/blob/main/CHANGELOG.md
|
|
10
|
+
Project-URL: Issues, https://github.com/nevesgeovana/pyflightstream/issues
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
19
|
+
Requires-Python: >=3.11
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: numpy
|
|
23
|
+
Requires-Dist: pandas
|
|
24
|
+
Requires-Dist: pydantic
|
|
25
|
+
Requires-Dist: pyyaml
|
|
26
|
+
Requires-Dist: xarray
|
|
27
|
+
Provides-Extra: plot
|
|
28
|
+
Requires-Dist: matplotlib; extra == "plot"
|
|
29
|
+
Provides-Extra: geom
|
|
30
|
+
Requires-Dist: trimesh; extra == "geom"
|
|
31
|
+
Requires-Dist: rtree; extra == "geom"
|
|
32
|
+
Requires-Dist: scipy; extra == "geom"
|
|
33
|
+
Provides-Extra: fsi
|
|
34
|
+
Requires-Dist: PyNiteFEA>=3.0; extra == "fsi"
|
|
35
|
+
Provides-Extra: dev
|
|
36
|
+
Requires-Dist: pytest; extra == "dev"
|
|
37
|
+
Requires-Dist: sybil; extra == "dev"
|
|
38
|
+
Requires-Dist: ruff; extra == "dev"
|
|
39
|
+
Requires-Dist: pre-commit; extra == "dev"
|
|
40
|
+
Requires-Dist: properdocs; extra == "dev"
|
|
41
|
+
Requires-Dist: mkdocs-material; extra == "dev"
|
|
42
|
+
Requires-Dist: mkdocs-gen-files; extra == "dev"
|
|
43
|
+
Requires-Dist: mkdocs-literate-nav; extra == "dev"
|
|
44
|
+
Dynamic: license-file
|
|
45
|
+
|
|
46
|
+
# pyflightstream
|
|
47
|
+
|
|
48
|
+
[](https://github.com/nevesgeovana/pyflightstream/actions/workflows/ci.yml)
|
|
49
|
+
[](https://pypi.org/project/pyflightstream/)
|
|
50
|
+
[](https://doi.org/10.5281/zenodo.21482925)
|
|
51
|
+
|
|
52
|
+
Version-aware, didactic Python driver for the FlightStream panel-method
|
|
53
|
+
solver. Successor of the author's legacy research scripts. MIT licensed.
|
|
54
|
+
|
|
55
|
+
Status: v0.2.0 is public on [PyPI](https://pypi.org/project/pyflightstream/)
|
|
56
|
+
with the archived release on Zenodo (DOI recorded in CITATION.cff).
|
|
57
|
+
Development continues toward v0.3.0; CHANGELOG.md carries the release
|
|
58
|
+
history.
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
pip install pyflightstream
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
A first taste, no solver required (build time is where errors surface):
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
from pyflightstream.commands import CommandNotInVersionError
|
|
68
|
+
from pyflightstream.script import Script
|
|
69
|
+
|
|
70
|
+
script = Script(version="26.12") # the FlightStream version is explicit input
|
|
71
|
+
script.emit("NEW_SIMULATION")
|
|
72
|
+
script.emit("IMPORT", "METER", "STL", "wing.stl", clear=True)
|
|
73
|
+
script.emit("SOLVER_SET_AOA", 4.0)
|
|
74
|
+
script.emit("START_SOLVER")
|
|
75
|
+
print(script.render()) # validated ASCII script, ready for the solver
|
|
76
|
+
|
|
77
|
+
try:
|
|
78
|
+
Script(version="26.0").emit("SOLVER_SET_AOA", 4.0)
|
|
79
|
+
except CommandNotInVersionError as error:
|
|
80
|
+
print(error) # refused: no recorded evidence for that version
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The worked examples in `examples/` take it from here to executed
|
|
84
|
+
polars, campaigns, and coupled aeroelastic runs.
|
|
85
|
+
|
|
86
|
+
Optional extras: `[fsi]` (aeroelastic coupling, PyNiteFEA), `[geom]`
|
|
87
|
+
(probe-survey geometry gating, trimesh/rtree/scipy), `[plot]`
|
|
88
|
+
(matplotlib for the plotting examples).
|
|
89
|
+
|
|
90
|
+
## Why this package
|
|
91
|
+
|
|
92
|
+
FlightStream is scripted through an ASCII command file, and the solver
|
|
93
|
+
is under active development: the FlightStream team is responsive to
|
|
94
|
+
user requests and works with intermediate hotfix builds that
|
|
95
|
+
consolidate into stable releases. A fast-moving solver naturally means
|
|
96
|
+
a scripting command set that evolves from version to version, faster
|
|
97
|
+
than any single document can track. This package makes the
|
|
98
|
+
FlightStream version an explicit input: every command it emits is
|
|
99
|
+
validated against a per-version command database, and old versions are
|
|
100
|
+
only ever added, never dropped, so campaigns stay reproducible across
|
|
101
|
+
that evolution.
|
|
102
|
+
|
|
103
|
+
Every database entry carries a manual page citation, and its status per
|
|
104
|
+
version (documented, verified, broken) can only be promoted by citing a
|
|
105
|
+
committed probe report from a licensed machine. Nothing is guessed; the
|
|
106
|
+
honest gaps are reported as such.
|
|
107
|
+
|
|
108
|
+
## What ships
|
|
109
|
+
|
|
110
|
+
- Command database with per-version evidence and a manual citation on
|
|
111
|
+
every entry, browsable offline via `pyflightstream.help()` (including
|
|
112
|
+
a manual-coverage section) and as a generated docs site; the
|
|
113
|
+
compatibility matrix carries the live counts.
|
|
114
|
+
- Validating script builder with curated helpers: phase ordering,
|
|
115
|
+
didactic refusals at build time, entity labels (recipes can name
|
|
116
|
+
frames, actuators, motions, and boundaries instead of raw indices),
|
|
117
|
+
and a solver-setup provenance snapshot recording the effective value
|
|
118
|
+
of every solver flag per run.
|
|
119
|
+
- Campaign workspace: an input-artifact library (references, solver
|
|
120
|
+
presets, boundary groups, geometries, profiles, executables by build
|
|
121
|
+
id), a run manifest as the single identity authority, output naming
|
|
122
|
+
templates, campaign pre-flight with zero solver time, and resumable
|
|
123
|
+
incremental sweeps.
|
|
124
|
+
- Runner and parsers: headless execution, anchor-based parsers for the
|
|
125
|
+
solver outputs, and a pandas table layer (per-result tables, one wide
|
|
126
|
+
row per run, whole-sweep DataFrame straight from the manifest).
|
|
127
|
+
- Run-matrix support as a first-class interface: read, convert,
|
|
128
|
+
pre-flight, and run the pipe-delimited 15-column matrix format.
|
|
129
|
+
- Far-field probe surveys (planar grids, geometry gating, VTK/Tecplot
|
|
130
|
+
writers, conservation ledgers on xarray) and an aeroelastic coupling
|
|
131
|
+
subpackage (structural beam, coupled driver, replay harness).
|
|
132
|
+
- Architecture overview from the live module docstrings via
|
|
133
|
+
`pyflightstream.overview()`.
|
|
134
|
+
- Predictable surfaces: a declared-options registry
|
|
135
|
+
(`pyflightstream.options`), one public exception catalog
|
|
136
|
+
(`pyflightstream.exceptions`), test assertions with quantified
|
|
137
|
+
reports (`pyflightstream.testing`), and the house conventions
|
|
138
|
+
rendered by `help()`.
|
|
139
|
+
|
|
140
|
+
## Command-line tools
|
|
141
|
+
|
|
142
|
+
| Tool | Purpose |
|
|
143
|
+
|---|---|
|
|
144
|
+
| `pyfs-qa` | Tier 2 command-validity probes, Tier 3 physics regression and cross-version drift, status promotion from committed reports |
|
|
145
|
+
| `pyfs-workspace` | Initialize the managed campaign workspace tree |
|
|
146
|
+
| `pyfs-matrix` | Convert and pre-flight run matrices |
|
|
147
|
+
| `pyfs-fsi` | The structural executable of the aeroelastic coupling loop |
|
|
148
|
+
|
|
149
|
+
## Supported FlightStream versions
|
|
150
|
+
|
|
151
|
+
Registered: 26.000, 26.100, 26.120 (canonical 26.XXX scheme; the last
|
|
152
|
+
digit indexes vendor hotfix builds). The ordered list in
|
|
153
|
+
`src/pyflightstream/commands/_meta.yaml` is the only ordering
|
|
154
|
+
authority. Evidence is strongest on 26.120 (probed on a licensed
|
|
155
|
+
machine); 26.100 is partially backfilled from the manuals; the 26.000
|
|
156
|
+
column is honestly empty until probed. The compatibility matrix in the
|
|
157
|
+
docs is generated from the database at build time.
|
|
158
|
+
|
|
159
|
+
## What is each folder?
|
|
160
|
+
|
|
161
|
+
| Folder | Purpose in plain language |
|
|
162
|
+
|---|---|
|
|
163
|
+
| `src/pyflightstream/` | The package, one subpackage per pipeline stage (versions, commands, script, results, cases, run, workspace, post, qa, plus fsi, probes, farfield) |
|
|
164
|
+
| `src/pyflightstream/commands/` | The command database: what exists in which FlightStream version, with manual page citations |
|
|
165
|
+
| `tests/` | Tier 1 tests, runnable anywhere, no FlightStream needed |
|
|
166
|
+
| `reports/` | Committed evidence from licensed machines: command validity (compat), physics regression, drift, and research cards |
|
|
167
|
+
| `docs/` | Documentation source (ProperDocs); reference pages are generated from the database, never committed |
|
|
168
|
+
| `examples/` | Runnable example scripts in percent format |
|
|
169
|
+
| `guide/` | LaTeX source of the user guide (the built pdf never enters Git) |
|
|
170
|
+
| `deprecated/` | Discontinued public items, grouped here instead of scattered at the top level |
|
|
171
|
+
| `.claude/skills/` | Maintenance procedures (version updates, command additions, QA runs, releases) |
|
|
172
|
+
| `_private/` | Local only, never committed: FlightStream manuals, executables, research geometry |
|
|
173
|
+
|
|
174
|
+
## Development setup
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
pip install -e .[dev,fsi,geom]
|
|
178
|
+
pre-commit install
|
|
179
|
+
pytest
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Tier 1 (the pytest suite) runs anywhere. Tier 2 (command validity
|
|
183
|
+
probes) and Tier 3 (physics regression) require a local FlightStream
|
|
184
|
+
license and are documented in CONTRIBUTING.md. The docs build with
|
|
185
|
+
`properdocs build --strict`.
|
|
186
|
+
|
|
187
|
+
## License
|
|
188
|
+
|
|
189
|
+
MIT. Contributions must be original or MIT-compatible; code derived
|
|
190
|
+
from the AGPL pyFlightscript package is not accepted. See
|
|
191
|
+
CONTRIBUTING.md.
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# pyflightstream
|
|
2
|
+
|
|
3
|
+
[](https://github.com/nevesgeovana/pyflightstream/actions/workflows/ci.yml)
|
|
4
|
+
[](https://pypi.org/project/pyflightstream/)
|
|
5
|
+
[](https://doi.org/10.5281/zenodo.21482925)
|
|
6
|
+
|
|
7
|
+
Version-aware, didactic Python driver for the FlightStream panel-method
|
|
8
|
+
solver. Successor of the author's legacy research scripts. MIT licensed.
|
|
9
|
+
|
|
10
|
+
Status: v0.2.0 is public on [PyPI](https://pypi.org/project/pyflightstream/)
|
|
11
|
+
with the archived release on Zenodo (DOI recorded in CITATION.cff).
|
|
12
|
+
Development continues toward v0.3.0; CHANGELOG.md carries the release
|
|
13
|
+
history.
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
pip install pyflightstream
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
A first taste, no solver required (build time is where errors surface):
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
from pyflightstream.commands import CommandNotInVersionError
|
|
23
|
+
from pyflightstream.script import Script
|
|
24
|
+
|
|
25
|
+
script = Script(version="26.12") # the FlightStream version is explicit input
|
|
26
|
+
script.emit("NEW_SIMULATION")
|
|
27
|
+
script.emit("IMPORT", "METER", "STL", "wing.stl", clear=True)
|
|
28
|
+
script.emit("SOLVER_SET_AOA", 4.0)
|
|
29
|
+
script.emit("START_SOLVER")
|
|
30
|
+
print(script.render()) # validated ASCII script, ready for the solver
|
|
31
|
+
|
|
32
|
+
try:
|
|
33
|
+
Script(version="26.0").emit("SOLVER_SET_AOA", 4.0)
|
|
34
|
+
except CommandNotInVersionError as error:
|
|
35
|
+
print(error) # refused: no recorded evidence for that version
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The worked examples in `examples/` take it from here to executed
|
|
39
|
+
polars, campaigns, and coupled aeroelastic runs.
|
|
40
|
+
|
|
41
|
+
Optional extras: `[fsi]` (aeroelastic coupling, PyNiteFEA), `[geom]`
|
|
42
|
+
(probe-survey geometry gating, trimesh/rtree/scipy), `[plot]`
|
|
43
|
+
(matplotlib for the plotting examples).
|
|
44
|
+
|
|
45
|
+
## Why this package
|
|
46
|
+
|
|
47
|
+
FlightStream is scripted through an ASCII command file, and the solver
|
|
48
|
+
is under active development: the FlightStream team is responsive to
|
|
49
|
+
user requests and works with intermediate hotfix builds that
|
|
50
|
+
consolidate into stable releases. A fast-moving solver naturally means
|
|
51
|
+
a scripting command set that evolves from version to version, faster
|
|
52
|
+
than any single document can track. This package makes the
|
|
53
|
+
FlightStream version an explicit input: every command it emits is
|
|
54
|
+
validated against a per-version command database, and old versions are
|
|
55
|
+
only ever added, never dropped, so campaigns stay reproducible across
|
|
56
|
+
that evolution.
|
|
57
|
+
|
|
58
|
+
Every database entry carries a manual page citation, and its status per
|
|
59
|
+
version (documented, verified, broken) can only be promoted by citing a
|
|
60
|
+
committed probe report from a licensed machine. Nothing is guessed; the
|
|
61
|
+
honest gaps are reported as such.
|
|
62
|
+
|
|
63
|
+
## What ships
|
|
64
|
+
|
|
65
|
+
- Command database with per-version evidence and a manual citation on
|
|
66
|
+
every entry, browsable offline via `pyflightstream.help()` (including
|
|
67
|
+
a manual-coverage section) and as a generated docs site; the
|
|
68
|
+
compatibility matrix carries the live counts.
|
|
69
|
+
- Validating script builder with curated helpers: phase ordering,
|
|
70
|
+
didactic refusals at build time, entity labels (recipes can name
|
|
71
|
+
frames, actuators, motions, and boundaries instead of raw indices),
|
|
72
|
+
and a solver-setup provenance snapshot recording the effective value
|
|
73
|
+
of every solver flag per run.
|
|
74
|
+
- Campaign workspace: an input-artifact library (references, solver
|
|
75
|
+
presets, boundary groups, geometries, profiles, executables by build
|
|
76
|
+
id), a run manifest as the single identity authority, output naming
|
|
77
|
+
templates, campaign pre-flight with zero solver time, and resumable
|
|
78
|
+
incremental sweeps.
|
|
79
|
+
- Runner and parsers: headless execution, anchor-based parsers for the
|
|
80
|
+
solver outputs, and a pandas table layer (per-result tables, one wide
|
|
81
|
+
row per run, whole-sweep DataFrame straight from the manifest).
|
|
82
|
+
- Run-matrix support as a first-class interface: read, convert,
|
|
83
|
+
pre-flight, and run the pipe-delimited 15-column matrix format.
|
|
84
|
+
- Far-field probe surveys (planar grids, geometry gating, VTK/Tecplot
|
|
85
|
+
writers, conservation ledgers on xarray) and an aeroelastic coupling
|
|
86
|
+
subpackage (structural beam, coupled driver, replay harness).
|
|
87
|
+
- Architecture overview from the live module docstrings via
|
|
88
|
+
`pyflightstream.overview()`.
|
|
89
|
+
- Predictable surfaces: a declared-options registry
|
|
90
|
+
(`pyflightstream.options`), one public exception catalog
|
|
91
|
+
(`pyflightstream.exceptions`), test assertions with quantified
|
|
92
|
+
reports (`pyflightstream.testing`), and the house conventions
|
|
93
|
+
rendered by `help()`.
|
|
94
|
+
|
|
95
|
+
## Command-line tools
|
|
96
|
+
|
|
97
|
+
| Tool | Purpose |
|
|
98
|
+
|---|---|
|
|
99
|
+
| `pyfs-qa` | Tier 2 command-validity probes, Tier 3 physics regression and cross-version drift, status promotion from committed reports |
|
|
100
|
+
| `pyfs-workspace` | Initialize the managed campaign workspace tree |
|
|
101
|
+
| `pyfs-matrix` | Convert and pre-flight run matrices |
|
|
102
|
+
| `pyfs-fsi` | The structural executable of the aeroelastic coupling loop |
|
|
103
|
+
|
|
104
|
+
## Supported FlightStream versions
|
|
105
|
+
|
|
106
|
+
Registered: 26.000, 26.100, 26.120 (canonical 26.XXX scheme; the last
|
|
107
|
+
digit indexes vendor hotfix builds). The ordered list in
|
|
108
|
+
`src/pyflightstream/commands/_meta.yaml` is the only ordering
|
|
109
|
+
authority. Evidence is strongest on 26.120 (probed on a licensed
|
|
110
|
+
machine); 26.100 is partially backfilled from the manuals; the 26.000
|
|
111
|
+
column is honestly empty until probed. The compatibility matrix in the
|
|
112
|
+
docs is generated from the database at build time.
|
|
113
|
+
|
|
114
|
+
## What is each folder?
|
|
115
|
+
|
|
116
|
+
| Folder | Purpose in plain language |
|
|
117
|
+
|---|---|
|
|
118
|
+
| `src/pyflightstream/` | The package, one subpackage per pipeline stage (versions, commands, script, results, cases, run, workspace, post, qa, plus fsi, probes, farfield) |
|
|
119
|
+
| `src/pyflightstream/commands/` | The command database: what exists in which FlightStream version, with manual page citations |
|
|
120
|
+
| `tests/` | Tier 1 tests, runnable anywhere, no FlightStream needed |
|
|
121
|
+
| `reports/` | Committed evidence from licensed machines: command validity (compat), physics regression, drift, and research cards |
|
|
122
|
+
| `docs/` | Documentation source (ProperDocs); reference pages are generated from the database, never committed |
|
|
123
|
+
| `examples/` | Runnable example scripts in percent format |
|
|
124
|
+
| `guide/` | LaTeX source of the user guide (the built pdf never enters Git) |
|
|
125
|
+
| `deprecated/` | Discontinued public items, grouped here instead of scattered at the top level |
|
|
126
|
+
| `.claude/skills/` | Maintenance procedures (version updates, command additions, QA runs, releases) |
|
|
127
|
+
| `_private/` | Local only, never committed: FlightStream manuals, executables, research geometry |
|
|
128
|
+
|
|
129
|
+
## Development setup
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
pip install -e .[dev,fsi,geom]
|
|
133
|
+
pre-commit install
|
|
134
|
+
pytest
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Tier 1 (the pytest suite) runs anywhere. Tier 2 (command validity
|
|
138
|
+
probes) and Tier 3 (physics regression) require a local FlightStream
|
|
139
|
+
license and are documented in CONTRIBUTING.md. The docs build with
|
|
140
|
+
`properdocs build --strict`.
|
|
141
|
+
|
|
142
|
+
## License
|
|
143
|
+
|
|
144
|
+
MIT. Contributions must be original or MIT-compatible; code derived
|
|
145
|
+
from the AGPL pyFlightscript package is not accepted. See
|
|
146
|
+
CONTRIBUTING.md.
|
|
@@ -4,12 +4,26 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pyflightstream"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.0"
|
|
8
8
|
description = "Version-aware, didactic Python driver for the FlightStream panel-method solver"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "MIT"}
|
|
11
11
|
authors = [{name = "Geovana Neves"}]
|
|
12
12
|
requires-python = ">=3.11"
|
|
13
|
+
# PyPA well-known metadata (audit 2026-07-23). The SPDX license
|
|
14
|
+
# expression form is deferred with the VCS-versioning item: it needs a
|
|
15
|
+
# setuptools floor bump, and the build toolchain does not move in a
|
|
16
|
+
# release week (PLN-024).
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Development Status :: 4 - Beta",
|
|
19
|
+
"Intended Audience :: Science/Research",
|
|
20
|
+
"License :: OSI Approved :: MIT License",
|
|
21
|
+
"Operating System :: OS Independent",
|
|
22
|
+
"Programming Language :: Python :: 3",
|
|
23
|
+
"Programming Language :: Python :: 3.11",
|
|
24
|
+
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Topic :: Scientific/Engineering :: Physics",
|
|
26
|
+
]
|
|
13
27
|
# xarray confirmed as a runtime dependency by the author's far-field
|
|
14
28
|
# extraction instruction of 2026-07-21 (PLN-006 closed): the farfield
|
|
15
29
|
# ledgers live on labeled (station, r, psi) arrays.
|
|
@@ -31,10 +45,16 @@ geom = ["trimesh", "rtree", "scipy"]
|
|
|
31
45
|
fsi = ["PyNiteFEA>=3.0"]
|
|
32
46
|
dev = [
|
|
33
47
|
"pytest",
|
|
48
|
+
# Executable examples in CI: docstring doctests and markdown code
|
|
49
|
+
# blocks (INB-006 item 1e, decision Q-007). Config in conftest.py.
|
|
50
|
+
"sybil",
|
|
34
51
|
"ruff",
|
|
35
52
|
"pre-commit",
|
|
53
|
+
# Docs build tool (license evidence: reports/RPT-009). The material
|
|
54
|
+
# theme and the nav plugins keep their mkdocs package names and
|
|
55
|
+
# still pull the mkdocs library during the ecosystem transition.
|
|
56
|
+
"properdocs",
|
|
36
57
|
"mkdocs-material",
|
|
37
|
-
"mkdocstrings[python]",
|
|
38
58
|
"mkdocs-gen-files",
|
|
39
59
|
"mkdocs-literate-nav",
|
|
40
60
|
]
|
|
@@ -42,9 +62,14 @@ dev = [
|
|
|
42
62
|
[project.scripts]
|
|
43
63
|
pyfs-qa = "pyflightstream.qa.cli:main"
|
|
44
64
|
pyfs-fsi = "pyflightstream.fsi.cli:main"
|
|
65
|
+
pyfs-workspace = "pyflightstream.workspace.cli:main"
|
|
66
|
+
pyfs-matrix = "pyflightstream.cases.cli:main"
|
|
45
67
|
|
|
46
68
|
[project.urls]
|
|
47
69
|
Repository = "https://github.com/nevesgeovana/pyflightstream"
|
|
70
|
+
Documentation = "https://nevesgeovana.github.io/pyflightstream/"
|
|
71
|
+
Changelog = "https://github.com/nevesgeovana/pyflightstream/blob/main/CHANGELOG.md"
|
|
72
|
+
Issues = "https://github.com/nevesgeovana/pyflightstream/issues"
|
|
48
73
|
|
|
49
74
|
[tool.setuptools.packages.find]
|
|
50
75
|
where = ["src"]
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""pyflightstream: version-aware, didactic Python driver for FlightStream.
|
|
2
|
+
|
|
3
|
+
The package automates the FlightStream panel-method solver through its
|
|
4
|
+
ASCII scripting interface. The FlightStream version is an explicit
|
|
5
|
+
input: every command emitted is validated against the per-version
|
|
6
|
+
command database in ``pyflightstream.commands``, where each entry
|
|
7
|
+
carries a manual page citation and, when probed on a licensed machine,
|
|
8
|
+
empirical evidence of its status. The script builder refuses at build
|
|
9
|
+
time what the solver would reject (or silently ignore) at run time.
|
|
10
|
+
|
|
11
|
+
Pipeline layers, dependencies flowing strictly downward:
|
|
12
|
+
|
|
13
|
+
- ``versions``: canonical 26.XXX version identifiers and ordering.
|
|
14
|
+
- ``commands``: the evidence-backed per-version command database.
|
|
15
|
+
- ``script``: the validating ASCII script builder.
|
|
16
|
+
- ``results``: anchor-based parsers for solver output files.
|
|
17
|
+
- ``cases``: simulation and campaign definitions.
|
|
18
|
+
- ``run`` and ``workspace``: execution, run manifest, and the managed
|
|
19
|
+
workspace (input-artifact library plus run layout); the old
|
|
20
|
+
``files`` name survives as a deprecation shim.
|
|
21
|
+
- ``post``: results into engineering data (sweep assembly, exports).
|
|
22
|
+
- ``qa``: probe harness and physics regression tooling.
|
|
23
|
+
|
|
24
|
+
Side packages follow the same downward-only rule:
|
|
25
|
+
|
|
26
|
+
- ``fsi``: the structural executable of the aeroelastic coupling loop.
|
|
27
|
+
- ``probes`` and ``farfield``: probe lattices for far-field surveys and
|
|
28
|
+
the conservation ledgers computed on them.
|
|
29
|
+
- ``reference``: the command reference renderer behind ``help()``.
|
|
30
|
+
|
|
31
|
+
Cross-cutting support modules, importable from any layer:
|
|
32
|
+
|
|
33
|
+
- ``options``: the declared, validated machine and QA knobs
|
|
34
|
+
(``get_option``/``set_option`` also re-exported here at top level).
|
|
35
|
+
- ``exceptions``: the single catalog of every exception and warning.
|
|
36
|
+
- ``testing``: public assertions with quantified violation reports.
|
|
37
|
+
|
|
38
|
+
Where to start:
|
|
39
|
+
|
|
40
|
+
- :func:`pyflightstream.help` opens the offline HTML command reference,
|
|
41
|
+
rendered from the installed command database.
|
|
42
|
+
- :func:`pyflightstream.overview` opens the offline HTML architecture
|
|
43
|
+
overview, rendered from the live module docstrings.
|
|
44
|
+
- The published docs site carries the same reference and overview plus
|
|
45
|
+
the compatibility matrix and worked examples.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
from importlib import metadata
|
|
49
|
+
|
|
50
|
+
try:
|
|
51
|
+
__version__ = metadata.version("pyflightstream")
|
|
52
|
+
except metadata.PackageNotFoundError:
|
|
53
|
+
# Source tree imported without an installation (for example a
|
|
54
|
+
# checkout placed on sys.path): no distribution metadata exists, so
|
|
55
|
+
# the version is honestly unknown instead of a stale hardcoded
|
|
56
|
+
# string. Install the package (pip install -e .) to expose the real
|
|
57
|
+
# version.
|
|
58
|
+
__version__ = "0.0.0+uninstalled"
|
|
59
|
+
|
|
60
|
+
from pyflightstream.options import ( # noqa: E402
|
|
61
|
+
describe_option,
|
|
62
|
+
get_option,
|
|
63
|
+
option_context,
|
|
64
|
+
reset_option,
|
|
65
|
+
set_option,
|
|
66
|
+
)
|
|
67
|
+
from pyflightstream.overview import overview # noqa: E402
|
|
68
|
+
from pyflightstream.reference import help # noqa: E402
|
|
69
|
+
|
|
70
|
+
__all__ = [
|
|
71
|
+
"__version__",
|
|
72
|
+
"describe_option",
|
|
73
|
+
"get_option",
|
|
74
|
+
"help",
|
|
75
|
+
"option_context",
|
|
76
|
+
"overview",
|
|
77
|
+
"reset_option",
|
|
78
|
+
"set_option",
|
|
79
|
+
]
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"""Deprecation ledger: every shim's recorded removal promise.
|
|
2
|
+
|
|
3
|
+
Pipeline role: cross-cutting support module (no solver semantics). A
|
|
4
|
+
deprecation is a versioned promise: the old name keeps working until a
|
|
5
|
+
stated package version and disappears at that version, never silently
|
|
6
|
+
later. This module is the single home of those promises; the shim
|
|
7
|
+
modules build their DeprecationWarning text from their ledger entry, so
|
|
8
|
+
the message users see and the deadline the Tier 1 guard enforces
|
|
9
|
+
(``tests/test_deprecation_deadline.py``) can never disagree (NFR-11).
|
|
10
|
+
|
|
11
|
+
Lifecycle of an entry: it is added in the commit that creates the shim,
|
|
12
|
+
its ``removal_version`` is cited by the shim's warning, and the entry
|
|
13
|
+
is deleted together with the shim in the release that reaches that
|
|
14
|
+
version. The Tier 1 guard fails the suite when a shim survives past its
|
|
15
|
+
promise, so a release cannot ship an expired shim unnoticed.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
from dataclasses import dataclass
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def parse_version(version: str) -> tuple[int, int, int]:
|
|
24
|
+
"""Parse a plain SemVer string into a comparable tuple.
|
|
25
|
+
|
|
26
|
+
Parameters
|
|
27
|
+
----------
|
|
28
|
+
version : str
|
|
29
|
+
A ``MAJOR.MINOR.PATCH`` string with integer fields, as used by
|
|
30
|
+
``pyproject.toml``. Pre-release or local suffixes are not
|
|
31
|
+
accepted: removal promises are made against plain releases.
|
|
32
|
+
|
|
33
|
+
Returns
|
|
34
|
+
-------
|
|
35
|
+
tuple of int
|
|
36
|
+
``(major, minor, patch)``, ordered like SemVer precedence.
|
|
37
|
+
|
|
38
|
+
Raises
|
|
39
|
+
------
|
|
40
|
+
ValueError
|
|
41
|
+
If the string is not three dot-separated integers.
|
|
42
|
+
"""
|
|
43
|
+
parts = version.split(".")
|
|
44
|
+
if len(parts) != 3 or not all(part.isdigit() for part in parts):
|
|
45
|
+
raise ValueError(
|
|
46
|
+
f"Expected a plain MAJOR.MINOR.PATCH version, got {version!r}; "
|
|
47
|
+
"deprecation promises are recorded against plain SemVer releases."
|
|
48
|
+
)
|
|
49
|
+
major, minor, patch = (int(part) for part in parts)
|
|
50
|
+
return (major, minor, patch)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@dataclass(frozen=True)
|
|
54
|
+
class DeprecatedModule:
|
|
55
|
+
"""One deprecated module and its recorded removal promise.
|
|
56
|
+
|
|
57
|
+
Attributes
|
|
58
|
+
----------
|
|
59
|
+
module : str
|
|
60
|
+
Dotted name of the shim module (the old import path).
|
|
61
|
+
replacement : str
|
|
62
|
+
Dotted name of the module that supersedes it.
|
|
63
|
+
deprecated_since : str
|
|
64
|
+
Package version (SemVer) whose release introduced the shim.
|
|
65
|
+
removal_version : str
|
|
66
|
+
First package version (SemVer) that must no longer carry the
|
|
67
|
+
shim. The Tier 1 deadline guard fails once ``pyproject.toml``
|
|
68
|
+
reaches this version with the shim still present.
|
|
69
|
+
extra : str
|
|
70
|
+
Optional extra sentence appended to the warning message, for
|
|
71
|
+
renames that involve more than the module path.
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
module: str
|
|
75
|
+
replacement: str
|
|
76
|
+
deprecated_since: str
|
|
77
|
+
removal_version: str
|
|
78
|
+
extra: str = ""
|
|
79
|
+
|
|
80
|
+
def message(self) -> str:
|
|
81
|
+
"""Render the DeprecationWarning text emitted by the shim.
|
|
82
|
+
|
|
83
|
+
Returns
|
|
84
|
+
-------
|
|
85
|
+
str
|
|
86
|
+
One message stating the rename, the version that made the
|
|
87
|
+
promise, and the exact version that removes the old name.
|
|
88
|
+
"""
|
|
89
|
+
text = (
|
|
90
|
+
f"{self.module} was renamed to {self.replacement} in "
|
|
91
|
+
f"v{self.deprecated_since} and will be removed in "
|
|
92
|
+
f"v{self.removal_version}; update the import to "
|
|
93
|
+
f"{self.replacement}."
|
|
94
|
+
)
|
|
95
|
+
if self.extra:
|
|
96
|
+
text = f"{text} {self.extra}"
|
|
97
|
+
return text
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
#: Every live deprecation shim of the package, one entry each. The
|
|
101
|
+
#: Tier 1 deadline guard iterates this tuple; an empty tuple means the
|
|
102
|
+
#: package currently makes no deprecation promises.
|
|
103
|
+
DEPRECATED_MODULES: tuple[DeprecatedModule, ...] = (
|
|
104
|
+
DeprecatedModule(
|
|
105
|
+
module="pyflightstream.files",
|
|
106
|
+
replacement="pyflightstream.workspace",
|
|
107
|
+
deprecated_since="0.3.0",
|
|
108
|
+
removal_version="0.4.0",
|
|
109
|
+
extra="The API is unchanged.",
|
|
110
|
+
),
|
|
111
|
+
DeprecatedModule(
|
|
112
|
+
module="pyflightstream.cases.matrix_legacy",
|
|
113
|
+
replacement="pyflightstream.cases.matrix",
|
|
114
|
+
deprecated_since="0.3.0",
|
|
115
|
+
removal_version="0.4.0",
|
|
116
|
+
extra=(
|
|
117
|
+
"LegacyMatrixError is now MatrixError and LegacyRow is now "
|
|
118
|
+
"MatrixRow; everything else is unchanged."
|
|
119
|
+
),
|
|
120
|
+
),
|
|
121
|
+
)
|
|
@@ -5,9 +5,9 @@ by ``sim_id``) is one solver configuration with its sweep; a
|
|
|
5
5
|
:class:`Campaign` groups cases with the FlightStream version and the
|
|
6
6
|
executable path, both required and explicit: nothing is read from
|
|
7
7
|
environment variables or guessed (SAD Section 5). Native persistence
|
|
8
|
-
is ``campaign.toml``; the
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
is ``campaign.toml``; the pipe-delimited ``matrix.fs`` run matrix
|
|
9
|
+
is read unchanged, forever, by the matrix reader
|
|
10
|
+
(:mod:`pyflightstream.cases.matrix`, FR-10).
|
|
11
11
|
|
|
12
12
|
Script recipes are explicitly imported functions satisfying the
|
|
13
13
|
:class:`ScriptRecipe` protocol: ``build(case, script) -> None``. The
|