mapflpy 1.1.2__tar.gz → 1.1.2rc2__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 (93) hide show
  1. mapflpy-1.1.2rc2/.github/workflows/docs.yml +78 -0
  2. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/.github/workflows/publish.yml +10 -16
  3. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/PKG-INFO +6 -11
  4. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/environment.yml +0 -4
  5. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/mapflpy/__init__.py +4 -16
  6. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/meson.build +7 -18
  7. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/noxfile.py +35 -65
  8. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/pyproject.toml +7 -13
  9. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/tests/test_module.py +0 -7
  10. mapflpy-1.1.2rc2/tools/fetch.sh +16 -0
  11. mapflpy-1.1.2rc2/tools/makedist.sh +31 -0
  12. mapflpy-1.1.2rc2/tools/makedocs.sh +29 -0
  13. mapflpy-1.1.2/.github/workflows/docs.yml +0 -94
  14. mapflpy-1.1.2/.python-version +0 -1
  15. mapflpy-1.1.2/tools/make_build.py +0 -132
  16. mapflpy-1.1.2/tools/make_docs.py +0 -60
  17. mapflpy-1.1.2/tools/make_intersphinx.py +0 -91
  18. mapflpy-1.1.2/tools/pyproject_version.py +0 -33
  19. mapflpy-1.1.2/tools/python_version.py +0 -21
  20. mapflpy-1.1.2/tools/python_versions.py +0 -85
  21. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/.f2py_f2cmap +0 -0
  22. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/.gitattributes +0 -0
  23. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/.gitignore +0 -0
  24. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/LICENSE.txt +0 -0
  25. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/README.rst +0 -0
  26. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/docs/Makefile +0 -0
  27. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/docs/make.bat +0 -0
  28. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/docs/source/_static/.gitkeep +0 -0
  29. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/docs/source/_static/assets/.gitkeep +0 -0
  30. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/docs/source/_templates/autosummary/attribute.rst +0 -0
  31. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/docs/source/_templates/autosummary/class.rst +0 -0
  32. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/docs/source/_templates/autosummary/class_method.rst +0 -0
  33. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/docs/source/_templates/autosummary/data.rst +0 -0
  34. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/docs/source/_templates/autosummary/exception.rst +0 -0
  35. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/docs/source/_templates/autosummary/function.rst +0 -0
  36. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/docs/source/_templates/autosummary/method.rst +0 -0
  37. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/docs/source/_templates/autosummary/module.rst +0 -0
  38. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/docs/source/_templates/autosummary/package.rst +0 -0
  39. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/docs/source/_templates/autosummary/property.rst +0 -0
  40. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/docs/source/_templates/autosummary/static_method.rst +0 -0
  41. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/docs/source/api/index.rst +0 -0
  42. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/docs/source/conf.py +0 -0
  43. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/docs/source/guide/development.rst +0 -0
  44. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/docs/source/guide/index.rst +0 -0
  45. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/docs/source/guide/installation.rst +0 -0
  46. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/docs/source/guide/overview.rst +0 -0
  47. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/docs/source/index.rst +0 -0
  48. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/examples/01_getting_started/GALLERY_HEADER.rst +0 -0
  49. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/examples/01_getting_started/p01_tracing_forward.py +0 -0
  50. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/examples/01_getting_started/p02_tracing_backward.py +0 -0
  51. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/examples/01_getting_started/p03_tracing_forward_backward.py +0 -0
  52. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/examples/01_getting_started/p04_adding_a_magnetogram.py +0 -0
  53. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/examples/02_using_tracer_class/GALLERY_HEADER.rst +0 -0
  54. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/examples/02_using_tracer_class/p01_using_defaults.py +0 -0
  55. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/examples/02_using_tracer_class/p02_setting_tracing_direction.py +0 -0
  56. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/examples/02_using_tracer_class/p03_adjusting_mapfl_params.py +0 -0
  57. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/examples/02_using_tracer_class/p04_manipulating_field_data.py +0 -0
  58. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/examples/03_using_tracermp_class/GALLERY_HEADER.rst +0 -0
  59. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/examples/03_using_tracermp_class/p01_using_defaults.py +0 -0
  60. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/examples/03_using_tracermp_class/p02_creating_multiple_tracermp.py +0 -0
  61. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/examples/03_using_tracermp_class/p03_magnetic_field.py +0 -0
  62. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/examples/04_advanced_examples/GALLERY_HEADER.rst +0 -0
  63. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/examples/04_advanced_examples/p01_interdomain_tracing.py +0 -0
  64. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/examples/04_advanced_examples/p02_coloring_by_polarity.py +0 -0
  65. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/examples/04_advanced_examples/p03_filtering_fieldlines.py +0 -0
  66. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/examples/GALLERY_HEADER.rst +0 -0
  67. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/mapflpy/_version.py.in +0 -0
  68. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/mapflpy/data.py +0 -0
  69. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/mapflpy/fortran/__init__.py +0 -0
  70. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/mapflpy/globals.py +0 -0
  71. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/mapflpy/py.typed +0 -0
  72. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/mapflpy/scripts.py +0 -0
  73. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/mapflpy/tracer.py +0 -0
  74. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/mapflpy/utils.py +0 -0
  75. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/src/f2py_f2cmap_mapflpy +0 -0
  76. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/src/mapfl/mapfl.f +0 -0
  77. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/src/mapfl/psi_io.f90 +0 -0
  78. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/src/mapflpy_fortran.f90 +0 -0
  79. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/tests/__init__.py +0 -0
  80. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/tests/conftest.py +0 -0
  81. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/tests/data/defaults.json +0 -0
  82. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/tests/data/reference_traces.npz +0 -0
  83. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/tests/test_tracer/__init__.py +0 -0
  84. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/tests/test_tracer/test_class_primitives.py +0 -0
  85. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/tests/test_tracer/test_fortran_calls.py +0 -0
  86. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/tests/test_tracer/test_param_editing.py +0 -0
  87. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/tests/test_tracer/test_trace_routines.py +0 -0
  88. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/tests/test_tracermp/__init__.py +0 -0
  89. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/tests/test_tracermp/test_class_primitives_.py +0 -0
  90. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/tests/test_tracermp/test_fortran_calls_.py +0 -0
  91. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/tests/test_tracermp/test_param_editing_.py +0 -0
  92. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/tests/test_tracermp/test_trace_routines_.py +0 -0
  93. {mapflpy-1.1.2 → mapflpy-1.1.2rc2}/tests/utils.py +0 -0
@@ -0,0 +1,78 @@
1
+ name: Publish Docs
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+ permissions:
7
+ contents: read
8
+
9
+ jobs:
10
+ build_docs:
11
+ name: Build docs
12
+ runs-on: ubuntu-latest
13
+
14
+ steps:
15
+ - uses: mamba-org/setup-micromamba@v2
16
+ with:
17
+ init-shell: bash
18
+ cache-downloads: true
19
+
20
+ - name: Checkout mapflpy
21
+ uses: actions/checkout@v4
22
+
23
+ - name: Setup Python
24
+ uses: actions/setup-python@v5
25
+ with:
26
+ python-version: 3.13
27
+
28
+ - name: Install build dependencies
29
+ run: |
30
+ python -m pip install --upgrade pip
31
+ pip install nox[pbs]
32
+
33
+ - name: Set nox conda backend
34
+ run: echo "CONDA_EXE=micromamba" >> "$GITHUB_ENV"
35
+
36
+ - name: Build wheels
37
+ run: |
38
+ nox -s build
39
+
40
+ - name: Repair wheels
41
+ run: |
42
+ nox -s repair
43
+
44
+ - name: Build docs
45
+ run: |
46
+ nox -s docs
47
+
48
+ - name: Upload docs artifact
49
+ if: always()
50
+ uses: actions/upload-artifact@v4
51
+ with:
52
+ name: docs
53
+ path: .nox/_artifacts/docs/html*/
54
+ retention-days: 7
55
+
56
+ - name: Prepare SSH
57
+ env:
58
+ SSH_HOST: ${{ secrets.DOCS_SSH_HOST }}
59
+ SSH_PORT: ${{ secrets.DOCS_SSH_PORT }}
60
+ run: |
61
+ install -m 700 -d ~/.ssh
62
+ install -m 600 /dev/null ~/.ssh/id_rsync
63
+ printf '%s\n' "${{ secrets.DOCS_SSH_KEY }}" > ~/.ssh/id_rsync
64
+ ssh-keyscan -p "${SSH_PORT:-22}" "${SSH_HOST}" >> ~/.ssh/known_hosts
65
+
66
+ - name: Rsync to server
67
+ env:
68
+ SSH_HOST: ${{ secrets.DOCS_SSH_HOST }}
69
+ SSH_USER: ${{ secrets.DOCS_SSH_USER }}
70
+ SSH_PORT: ${{ secrets.DOCS_SSH_PORT }}
71
+ REMOTE_DIR: ${{ secrets.DOCS_SSH_PATH }}
72
+ run: |
73
+ # ensure target dir exists
74
+ ssh -i ~/.ssh/id_rsync -p "${SSH_PORT:-22}" -o StrictHostKeyChecking=yes \
75
+ "${SSH_USER}@${SSH_HOST}" "mkdir -p '${REMOTE_DIR}'"
76
+ rsync -az \
77
+ -e "ssh -i ~/.ssh/id_rsync -p ${SSH_PORT:-22} -o StrictHostKeyChecking=yes" \
78
+ .nox/_artifacts/docs/html*/ "${SSH_USER}@${SSH_HOST}:${REMOTE_DIR}/"
@@ -1,13 +1,7 @@
1
- name: Publish Build
1
+ name: CICD Pipeline
2
2
 
3
3
  on:
4
4
  workflow_dispatch:
5
- pull_request:
6
- push:
7
- branches:
8
- - master
9
- tags:
10
- - '*'
11
5
 
12
6
  permissions:
13
7
  actions: read
@@ -28,7 +22,7 @@ jobs:
28
22
  - name: Setup python
29
23
  uses: actions/setup-python@v5
30
24
  with:
31
- python-version-file: .python-version
25
+ python-version: 3.13
32
26
 
33
27
  - name: Install nox
34
28
  run: |
@@ -61,9 +55,9 @@ jobs:
61
55
  matrix:
62
56
  os:
63
57
  - ubuntu-24.04
64
- - ubuntu-22.04-arm
65
- - macos-15-intel
66
- - macos-15
58
+ # - ubuntu-22.04-arm
59
+ # - macos-15-intel
60
+ # - macos-15
67
61
  steps:
68
62
  - uses: mamba-org/setup-micromamba@v2
69
63
  with:
@@ -76,7 +70,7 @@ jobs:
76
70
  - name: Setup Python
77
71
  uses: actions/setup-python@v5
78
72
  with:
79
- python-version-file: .python-version
73
+ python-version: 3.13
80
74
 
81
75
  - name: Install build dependencies
82
76
  run: |
@@ -123,9 +117,9 @@ jobs:
123
117
  matrix:
124
118
  os:
125
119
  - ubuntu-24.04
126
- - ubuntu-22.04-arm
127
- - macos-15-intel
128
- - macos-15
120
+ # - ubuntu-22.04-arm
121
+ # - macos-15-intel
122
+ # - macos-15
129
123
  steps:
130
124
  - uses: mamba-org/setup-micromamba@v2
131
125
  with:
@@ -138,7 +132,7 @@ jobs:
138
132
  - name: Setup Python
139
133
  uses: actions/setup-python@v5
140
134
  with:
141
- python-version-file: .python-version
135
+ python-version: 3.13
142
136
 
143
137
  - name: Install build dependencies
144
138
  run: |
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mapflpy
3
- Version: 1.1.2
3
+ Version: 1.1.2rc2
4
4
  Summary: Python extension for tracing field lines using the Fortran tracer from MapFL
5
5
  Keywords: solar physics,space physics,heliophysics,magnetohydrodynamic,science,mas,predsci,psi,modeling,fortran
6
6
  Author: Ryder Davidson, Cooper Downs, Andres Reyes, Asher Pembroke
@@ -9,19 +9,17 @@ License-Expression: Apache-2.0
9
9
  License-File: LICENSE.txt
10
10
  Classifier: Development Status :: 4 - Beta
11
11
  Classifier: Intended Audience :: Science/Research
12
+ Classifier: Operating System :: Unix
13
+ Classifier: Operating System :: POSIX :: Linux
14
+ Classifier: Operating System :: MacOS :: MacOS X
12
15
  Classifier: Natural Language :: English
13
- Classifier: Programming Language :: Fortran
14
16
  Classifier: Programming Language :: Python
15
17
  Classifier: Programming Language :: Python :: 3
16
18
  Classifier: Programming Language :: Python :: 3.10
17
19
  Classifier: Programming Language :: Python :: 3.11
18
20
  Classifier: Programming Language :: Python :: 3.12
19
21
  Classifier: Programming Language :: Python :: 3.13
20
- Classifier: Programming Language :: Python :: 3 :: Only
21
- Classifier: Operating System :: Unix
22
- Classifier: Operating System :: POSIX :: Linux
23
- Classifier: Operating System :: MacOS :: MacOS X
24
- Classifier: Typing :: Typed
22
+ Classifier: Programming Language :: Fortran
25
23
  Classifier: Topic :: Scientific/Engineering :: Astronomy
26
24
  Classifier: Topic :: Scientific/Engineering :: Physics
27
25
  Project-URL: homepage, https://predsci.com/
@@ -38,7 +36,6 @@ Requires-Dist: matplotlib==3.10.7; extra == "data"
38
36
  Requires-Dist: scipy; extra == "data"
39
37
  Provides-Extra: build
40
38
  Requires-Dist: python-build; extra == "build"
41
- Requires-Dist: packaging; extra == "build"
42
39
  Provides-Extra: test
43
40
  Requires-Dist: pytest>=8.4.0; extra == "test"
44
41
  Requires-Dist: pytest-cov; extra == "test"
@@ -55,10 +52,8 @@ Requires-Dist: pooch==1.8.2; extra == "docs"
55
52
  Requires-Dist: matplotlib==3.10.7; extra == "docs"
56
53
  Requires-Dist: scipy; extra == "docs"
57
54
  Requires-Dist: pthree==1.0.1; extra == "docs"
58
- Provides-Extra: dev
59
- Requires-Dist: nox>=2025.11.12; extra == "dev"
60
55
  Provides-Extra: all
61
- Requires-Dist: mapflpy[build,data,dev,docs,hdf4,lint,test,types]; extra == "all"
56
+ Requires-Dist: mapflpy[build,data,docs,hdf4,lint,test,types]; extra == "all"
62
57
  Description-Content-Type: text/x-rst
63
58
 
64
59
  mapflpy
@@ -40,13 +40,9 @@ dependencies:
40
40
  - pooch
41
41
  - scipy
42
42
 
43
- # -------- Scripts --------
44
- - packaging
45
-
46
43
  # -------- Publish --------
47
44
  - twine
48
45
 
49
- # -------- Pip installs --------
50
46
  - pip
51
47
  - pip:
52
48
  - psi-io # Python runtime package
@@ -7,27 +7,15 @@ allow users a high-level interface to the underlying Fortran routines, as well a
7
7
  visualizing and analyzing the traced fieldlines.
8
8
  """
9
9
 
10
-
11
10
  # mapflpy/__init__.py
12
11
  try:
13
12
  # If Meson generated this file:
14
13
  from ._version import __version__ # type: ignore[attr-defined]
15
- except ModuleNotFoundError as e:
14
+ except Exception:
16
15
  try:
17
- from importlib.metadata import version as _pkg_version
18
- from importlib.metadata import PackageNotFoundError
19
- from pathlib import Path
20
16
  # Fallback to installed metadata (wheel/sdist)
17
+ from importlib.metadata import version as _pkg_version
21
18
  __version__ = _pkg_version("mapflpy") # type: ignore[assignment]
22
- except PackageNotFoundError as e: # dev/editable without metadata
23
- try:
24
- import tomllib # Python 3.11+
25
- except ModuleNotFoundError: # pragma: no cover
26
- import tomli as tomllib # pip install tomli
27
-
28
- pyproject = Path(__file__).parents[1].resolve() / 'pyproject.toml'
29
- data = tomllib.loads(pyproject.read_text())
19
+ except Exception: # dev/editable without metadata
20
+ __version__ = "0+unknown" # type: ignore[assignment]
30
21
 
31
- project_version = data.get("project", {}).get("version", "0+unknown")
32
- project_version = project_version.replace('"', '').replace("'", '')
33
- __version__ = project_version
@@ -1,14 +1,11 @@
1
1
 
2
2
  project(
3
3
  'mapflpy',
4
- 'c', 'cpp', 'fortran',
5
- version: run_command(['tools/pyproject_version.py'], check: true).stdout().strip(),
4
+ ['c', 'fortran'],
5
+ version : '1.1.2.pre2',
6
6
  license : 'Apache-2.0',
7
7
  meson_version : '>=1.1.0',
8
- default_options : [
9
- 'warning_level=1',
10
- 'buildtype=release'
11
- ],
8
+ default_options : ['warning_level=1', 'buildtype=release'],
12
9
  )
13
10
 
14
11
  # ---- Compilers / platform niceties
@@ -95,7 +92,10 @@ py.extension_module(
95
92
  install : true,
96
93
  )
97
94
 
98
- # ---- Generate mapflpy/_version.py
95
+ # ---- Install the pure-Python package tree (future-proof)
96
+ install_subdir('mapflpy', install_dir : py.get_install_dir())
97
+
98
+ # ---- Generate mapflpy/_version.py with Meson project version
99
99
  conf = configuration_data()
100
100
  conf.set('VERSION', meson.project_version())
101
101
  configure_file(
@@ -105,14 +105,3 @@ configure_file(
105
105
  install : true,
106
106
  install_dir : py.get_install_dir() / 'mapflpy',
107
107
  )
108
-
109
- # ---- Install the pure-Python package tree
110
- install_subdir(
111
- 'mapflpy',
112
- install_dir : py.get_install_dir(),
113
- exclude_files: [
114
- '_version.py.in',
115
- '__pycache__',
116
- '*.pyc',
117
- ]
118
- )
@@ -2,32 +2,34 @@
2
2
  from __future__ import annotations
3
3
 
4
4
  import os
5
- import re
6
5
  import json
7
6
  import platform
8
7
  import subprocess
9
8
  from pathlib import Path
10
9
  import nox
11
10
 
12
- nox.options.reuse_existing_virtualenvs = True
13
- pyproject = nox.project.load_toml()
11
+ # Speed up reruns; reuse envs when deps unchanged
12
+ nox.options.reuse_existing_virtualenvs = False
14
13
 
15
- PY_VERSIONS = nox.project.python_versions(pyproject)
16
- try:
17
- txt = Path('.python-version').read_text(encoding="utf-8").strip().splitlines()[0]
18
- m = re.search(r"(\d+)\.(\d+)", txt) # grab major.minor; ignore patch/suffix
19
- SYS_PYTHON = f"{m.group(1)}.{m.group(2)}" if m else PY_VERSIONS[-1]
20
- except FileNotFoundError as e:
21
- SYS_PYTHON = PY_VERSIONS[-1]
22
14
 
23
- PROJECT_NAME = pyproject["project"]["name"]
15
+ PY_VERSIONS = [
16
+ # "3.10",
17
+ # "3.11",
18
+ # "3.12",
19
+ "3.13",
20
+ ]
21
+ PY_TARGET = PY_VERSIONS[-1]
22
+
24
23
  PROJECT_NAME_PATH = Path(__file__).parent.resolve()
25
- _ARTIFACTS = PROJECT_NAME_PATH / ".nox" / "_artifacts"
24
+ ARTIFACTS = PROJECT_NAME_PATH / ".nox" / "_artifacts"
25
+ WHEEL_DIR = ARTIFACTS / "wheels"
26
+ SDIST_DIR = ARTIFACTS / "sdist"
27
+ WHEELHOUSE_DIR = ARTIFACTS / "wheelhouse"
28
+ DOCDIST_DIR = ARTIFACTS / "docs"
26
29
 
27
- WHEEL_DIR = _ARTIFACTS / "wheels"
28
- SDIST_DIR = _ARTIFACTS / "sdist"
29
- WHEELHOUSE_DIR = _ARTIFACTS / "wheelhouse"
30
- DOCDIST_DIR = _ARTIFACTS / "docs"
30
+ pyproject = nox.project.load_toml("pyproject.toml")
31
+ PROJECT_NAME = pyproject["project"]["name"]
32
+ CONDA_ENV_BUILD_COMPILERS = pyproject["tool"][PROJECT_NAME].get("conda", [])
31
33
 
32
34
  REPAIR_TOOLS: dict[str, list[str]] = {
33
35
  "linux": ["auditwheel"],
@@ -35,7 +37,6 @@ REPAIR_TOOLS: dict[str, list[str]] = {
35
37
  "windows": ["delvewheel"],
36
38
  }
37
39
 
38
- SDIST_DIR.mkdir(parents=True, exist_ok=True)
39
40
  WHEEL_DIR.mkdir(parents=True, exist_ok=True)
40
41
  WHEELHOUSE_DIR.mkdir(parents=True, exist_ok=True)
41
42
  DOCDIST_DIR.mkdir(parents=True, exist_ok=True)
@@ -48,6 +49,15 @@ def _darwin_sdk_env() -> dict[str, str]:
48
49
  # Prefer already-set values; otherwise best-effort defaults
49
50
  env = {}
50
51
  env.setdefault("MACOSX_DEPLOYMENT_TARGET", os.environ.get("MACOSX_DEPLOYMENT_TARGET", "11.0"))
52
+ # SDKPROJECT_NAME_PATH may be needed for clang/gfortran during Meson sanity checks
53
+ # if "SDKPROJECT_NAME_PATH" not in os.environ:
54
+ # try:
55
+ # import subprocess
56
+ # sdk = subprocess.check_output(["xcrun", "--show-sdk-path"], text=True).strip()
57
+ # env["SDKPROJECT_NAME_PATH"] = sdk
58
+ # except Exception:
59
+ # pass
60
+ # return env
51
61
  try:
52
62
  sdk = subprocess.check_output(
53
63
  ["xcrun", "--sdk", "macosx", "--show-sdk-path"],
@@ -67,7 +77,7 @@ def _darwin_sdk_env() -> dict[str, str]:
67
77
  def _build_env(session: nox.Session) -> Path:
68
78
  """Build a wheel into ./dist and return its path."""
69
79
  session.conda_install(
70
- *pyproject["tool"][PROJECT_NAME].get("conda", []),
80
+ *CONDA_ENV_BUILD_COMPILERS,
71
81
  channel="conda-forge"
72
82
  )
73
83
  session.env.update(_darwin_sdk_env())
@@ -102,8 +112,7 @@ def build(session: nox.Session) -> None:
102
112
  external=False
103
113
  )
104
114
 
105
-
106
- @nox.session(python=SYS_PYTHON)
115
+ @nox.session(python=PY_TARGET)
107
116
  def repair(session: nox.Session) -> None:
108
117
  """Repair wheels in dist/ into wheelhouse/ using the OS-specific tool."""
109
118
  platform_id = platform.system().lower()
@@ -132,6 +141,8 @@ def test(session: nox.Session) -> None:
132
141
  """Build the wheel (with compilers), install it, then run pytest from a temp dir."""
133
142
  # Build wheel
134
143
  _dist_env(session)
144
+
145
+ # Runtime/test deps
135
146
  session.install(*pyproject["project"].get("optional-dependencies", {}).get("test", []))
136
147
 
137
148
  tmp = session.create_tmp()
@@ -140,8 +151,7 @@ def test(session: nox.Session) -> None:
140
151
  # Pytest
141
152
  session.run("pytest", PROJECT_NAME_PATH.as_posix())
142
153
 
143
-
144
- @nox.session(venv_backend='conda|mamba|micromamba', python=SYS_PYTHON)
154
+ @nox.session(venv_backend='conda|mamba|micromamba', python=PY_TARGET)
145
155
  def sdist(session: nox.Session) -> None:
146
156
  """Build the package wheel (with compilers)."""
147
157
  _build_env(session)
@@ -156,16 +166,14 @@ def sdist(session: nox.Session) -> None:
156
166
  external=False
157
167
  )
158
168
 
159
-
160
- @nox.session(python=SYS_PYTHON)
169
+ @nox.session(python=PY_TARGET)
161
170
  def types(session: nox.Session) -> None:
162
171
  """Mypy type checking (analyzes source tree)."""
163
172
  session.install(*pyproject["project"].get("optional-dependencies", {}).get("types", []))
164
173
 
165
174
  session.run("mypy")
166
175
 
167
-
168
- @nox.session(python=SYS_PYTHON)
176
+ @nox.session(python=PY_TARGET)
169
177
  def lint(session: nox.Session) -> None:
170
178
  """Ruff lint + format check."""
171
179
  session.install(*pyproject["project"].get("optional-dependencies", {}).get("lint", []))
@@ -173,8 +181,7 @@ def lint(session: nox.Session) -> None:
173
181
  session.run("ruff", "check", PROJECT_NAME)
174
182
  session.run("ruff", "format", "--check", PROJECT_NAME)
175
183
 
176
-
177
- @nox.session(python=SYS_PYTHON)
184
+ @nox.session(python=PY_TARGET)
178
185
  def docs(session: nox.Session) -> None:
179
186
  """Build Sphinx docs against the installed wheel."""
180
187
  _dist_env(session)
@@ -200,40 +207,3 @@ def docs(session: nox.Session) -> None:
200
207
  out_dir = DOCDIST_DIR / f"html-{tag.get('tags', ['none'])[0]}"
201
208
  src_dir = PROJECT_NAME_PATH / "docs" / "source"
202
209
  session.run("sphinx-build", src_dir.as_posix(), out_dir.as_posix(), *args)
203
-
204
-
205
- @nox.session(python=SYS_PYTHON)
206
- def build_matrix(session: nox.Session) -> None:
207
- """Build, repair, and test in order (single entrypoint)."""
208
- session.notify("sdist")
209
- session.notify("build")
210
- session.notify("repair")
211
- session.notify("test")
212
-
213
-
214
- @nox.session(python=SYS_PYTHON)
215
- def build_target(session: nox.Session) -> None:
216
- """Build, repair, and test in order (single entrypoint)."""
217
- session.notify("sdist")
218
- session.notify(f"build-{session.python}")
219
- session.notify("repair")
220
- session.notify(f"test-{session.python}")
221
-
222
-
223
- @nox.session(python=SYS_PYTHON)
224
- def build_docs(session: nox.Session) -> None:
225
- """Build, repair, and test in order (single entrypoint)."""
226
- session.notify("build_target")
227
- session.notify("docs")
228
-
229
-
230
- @nox.session(python=SYS_PYTHON)
231
- def build_qa(session: nox.Session) -> None:
232
- """Build, repair, and test in order (single entrypoint)."""
233
- session.notify("build_target")
234
- session.notify(f"types")
235
- session.notify(f"lint")
236
-
237
-
238
- if __name__ == "__main__":
239
- nox.main()
@@ -16,7 +16,7 @@ requires = [
16
16
  # ----------------
17
17
  [project]
18
18
  name = "mapflpy"
19
- version = "1.1.2"
19
+ dynamic = ["version"]
20
20
  description = "Python extension for tracing field lines using the Fortran tracer from MapFL"
21
21
  authors = [
22
22
  {name = "Predictive Science Inc.", email = "webmaster@predsci.com"},
@@ -34,19 +34,17 @@ keywords = [
34
34
  classifiers = [
35
35
  "Development Status :: 4 - Beta",
36
36
  "Intended Audience :: Science/Research",
37
+ "Operating System :: Unix",
38
+ "Operating System :: POSIX :: Linux",
39
+ "Operating System :: MacOS :: MacOS X",
37
40
  "Natural Language :: English",
38
- "Programming Language :: Fortran",
39
41
  "Programming Language :: Python",
40
42
  "Programming Language :: Python :: 3",
41
43
  "Programming Language :: Python :: 3.10",
42
44
  "Programming Language :: Python :: 3.11",
43
45
  "Programming Language :: Python :: 3.12",
44
46
  "Programming Language :: Python :: 3.13",
45
- "Programming Language :: Python :: 3 :: Only",
46
- "Operating System :: Unix",
47
- "Operating System :: POSIX :: Linux",
48
- "Operating System :: MacOS :: MacOS X",
49
- "Typing :: Typed",
47
+ "Programming Language :: Fortran",
50
48
  "Topic :: Scientific/Engineering :: Astronomy",
51
49
  "Topic :: Scientific/Engineering :: Physics",
52
50
  ]
@@ -75,8 +73,7 @@ data = [
75
73
  "scipy"
76
74
  ]
77
75
  build = [
78
- "python-build",
79
- "packaging"
76
+ "python-build"
80
77
  ]
81
78
  test = [
82
79
  "pytest>=8.4.0",
@@ -98,11 +95,8 @@ docs = [
98
95
  "scipy",
99
96
  "pthree==1.0.1"
100
97
  ]
101
- dev = [
102
- "nox>=2025.11.12",
103
- ]
104
98
  all = [
105
- "mapflpy[hdf4,data,build,test,types,lint,docs,dev]",
99
+ "mapflpy[hdf4,data,build,test,types,lint,docs]",
106
100
  ]
107
101
 
108
102
  # Tools & Extensions
@@ -2,13 +2,6 @@
2
2
  import json
3
3
 
4
4
 
5
- def test_version():
6
- from mapflpy import __version__
7
- assert isinstance(__version__, str)
8
- assert len(__version__) > 0
9
- assert __version__ != "0+unknown"
10
-
11
-
12
5
  def test_shared_object():
13
6
  from tests.utils import check_shared_object
14
7
  location = check_shared_object()
@@ -0,0 +1,16 @@
1
+ #!/bin/bash
2
+
3
+ SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd -P)"
4
+ PARENT_DIR="$(dirname "$SCRIPT_DIR")"
5
+ TARGET_DIR="$PARENT_DIR/docs/_intersphinx"
6
+ if [ ! -d "$TARGET_DIR" ]; then
7
+ mkdir -p "$TARGET_DIR"
8
+ fi
9
+ # this script updates the intersphinx files here
10
+ # make sure to follow potential redirects
11
+ curl -L https://docs.python.org/3/objects.inv > "${TARGET_DIR}"/python-objects.inv
12
+ curl -L https://docs.scipy.org/doc/scipy/objects.inv > "${TARGET_DIR}"/scipy-objects.inv
13
+ curl -L https://numpy.org/doc/stable/objects.inv > "${TARGET_DIR}"/numpy-objects.inv
14
+ curl -L https://matplotlib.org/stable/objects.inv > "${TARGET_DIR}"/matplotlib-objects.inv
15
+ curl -L https://docs.pytest.org/en/stable/objects.inv > "${TARGET_DIR}"/pytest-objects.inv
16
+ curl -L https://www.fatiando.org/pooch/latest/objects.inv > "${TARGET_DIR}"/pooch-objects.inv
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
4
+ PARENT_DIR="$(dirname "$SCRIPT_DIR")"
5
+
6
+ rm -rf "$PARENT_DIR/dist" \
7
+ "$PARENT_DIR/build" \
8
+ "$PARENT_DIR/"*.egg-info \
9
+ "$PARENT_DIR/mapflpy_fortran-f2pywrappers2.f90" \
10
+ "$PARENT_DIR/mapflpy_fortranmodule.c" \
11
+ "$PARENT_DIR/mapflpy/fortran/"*.so \
12
+ "$PARENT_DIR/.pytest_cache" \
13
+
14
+ python -m build "$PARENT_DIR"
15
+
16
+ # pick the wheel
17
+ wheel="$(ls "$PARENT_DIR"/dist/*.whl | head -n1)"
18
+
19
+ # list members and select the .so you want
20
+ member="$(unzip -Z1 "$wheel" 'mapflpy/fortran/*.so' | head -n1)"
21
+
22
+ # extract that single file to the desired path
23
+ unzip -p "$wheel" "$member" > "$PARENT_DIR/mapflpy/fortran/$(basename "$member")"
24
+
25
+ rm -rf "$PARENT_DIR/dist" \
26
+ "$PARENT_DIR/build" \
27
+ "$PARENT_DIR/"*.egg-info \
28
+ "$PARENT_DIR/mapflpy_fortran-f2pywrappers2.f90" \
29
+ "$PARENT_DIR/mapflpy_fortranmodule.c"
30
+
31
+ python -m pytest "$PARENT_DIR/tests"
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
4
+ PARENT_DIR="$(dirname "$SCRIPT_DIR")"
5
+
6
+ fetch=0
7
+ remove=0
8
+ while getopts ":fr" name
9
+ do
10
+ case $name in
11
+ f) fetch=1;;
12
+ r) remove=1;;
13
+ \?) printf 'Usage: %s [-f] [-r]\n' "$0"; exit 2 ;;
14
+ esac
15
+ done
16
+
17
+ if (( remove )); then
18
+ rm -rf "$PARENT_DIR/docs/_build" \
19
+ "$PARENT_DIR/docs/source/autodoc" \
20
+ "$PARENT_DIR/docs/source/gallery"
21
+ fi
22
+
23
+ if (( fetch )); then
24
+ rm -rf "$PARENT_DIR/docs/_intersphinx"
25
+ chmod +x "$PARENT_DIR/docs/fetch.sh"
26
+ "$PARENT_DIR/docs/fetch.sh"
27
+ fi
28
+
29
+ make -C "$PARENT_DIR/docs" html