Repository: fsciortino/Aurora (language: python)

Issue:
Fix CI: teach setuptools that the build needs numpy
Recent versions of setuptools need the build requirements
to be specified in the pyproject.toml, see
https://setuptools.pypa.io/en/latest/userguide/dependency_management.html#build-system-requirement

Editable installs are still not working, so this patch temporarily
disables them in order to bring the CI back to green.
The issue with editable installs is tracked at #98.
Re-enable testing of editable installs
It is currently broken, as per https://github.com/fsciortino/Aurora/pull/96, because of issues with the deprecated numpy.distutils.

@fsciortino please assign this issue to me :)


Discussion / hints:
Ok so this fixes installation of the package except for `--editable` installations. I'll see what I can do about that :)
@fsciortino see new PR description: I propose to disable editable installs for now so you get a green CI back (although one that does not test editable installs, for now).

I'll propose a larger refactoring of the building of the fortran extension modules soon that should bring editable installs back.


Fix patch:
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 00000000..e15fac24
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,43 @@
+cmake_minimum_required(VERSION 3.17.2...3.26)
+project(${SKBUILD_PROJECT_NAME} LANGUAGES C Fortran)
+
+find_package(
+  Python
+  COMPONENTS Interpreter Development.Module NumPy
+  REQUIRED)
+
+# F2PY headers
+execute_process(
+  COMMAND "${PYTHON_EXECUTABLE}" -c
+          "import numpy.f2py; print(numpy.f2py.get_include())"
+  OUTPUT_VARIABLE F2PY_INCLUDE_DIR
+  OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+add_library(fortranobject OBJECT "${F2PY_INCLUDE_DIR}/fortranobject.c")
+target_link_libraries(fortranobject PUBLIC Python::NumPy)
+target_include_directories(fortranobject PUBLIC "${F2PY_INCLUDE_DIR}")
+set_property(TARGET fortranobject PROPERTY POSITION_INDEPENDENT_CODE ON)
+
+add_custom_command(
+  OUTPUT _auroramodule.c example-f2pywrappers.f
+  DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/aurora/main.f90"
+          "${CMAKE_CURRENT_SOURCE_DIR}/aurora/impden.f90"
+          "${CMAKE_CURRENT_SOURCE_DIR}/aurora/math.f90"
+          "${CMAKE_CURRENT_SOURCE_DIR}/aurora/grids.f90"
+  VERBATIM
+  COMMAND "${Python_EXECUTABLE}" -m numpy.f2py
+          "${CMAKE_CURRENT_SOURCE_DIR}/aurora/main.f90"
+          "${CMAKE_CURRENT_SOURCE_DIR}/aurora/impden.f90"
+          "${CMAKE_CURRENT_SOURCE_DIR}/aurora/math.f90"
+          "${CMAKE_CURRENT_SOURCE_DIR}/aurora/grids.f90"
+          -m _aurora --lower)
+
+python_add_library(_aurora MODULE "${CMAKE_CURRENT_BINARY_DIR}/_auroramodule.c"
+                   "${CMAKE_CURRENT_SOURCE_DIR}/aurora/main.f90"
+                   "${CMAKE_CURRENT_SOURCE_DIR}/aurora/impden.f90"
+                   "${CMAKE_CURRENT_SOURCE_DIR}/aurora/math.f90"
+                   "${CMAKE_CURRENT_SOURCE_DIR}/aurora/grids.f90"
+                   WITH_SOABI)
+target_link_libraries(_aurora PRIVATE fortranobject)
+
+install(TARGETS _aurora DESTINATION aurora/)
diff --git a/makefile b/makefile
deleted file mode 100644
index dbb6f7da..00000000
--- a/makefile
+++ /dev/null
@@ -1,43 +0,0 @@
-# Usage:
-# make aurora           # generate aurora shared-object library
-# make clean             # delete previous versions of the aurora shared-object library
-# make julia              # create Julia sysimage -- requires Julia to be available on system!
-# make clean_julia     # delete Julia sysimage
-#
-# To create Fortran libraries for Aurora, make sure to select the correct compiler option at the top of this makefile.
-
-.PHONY: all aurora clean
-
-# option #1: basic gnu95 compiler (no flags is fine)
-flags=
-fcompiler=gnu95
-
-# option #2: if Intel compilers are available, use this option:
-#flags="-fast"
-#fcompiler=intelem
-
-
-############
-
-all: aurora
-
-aurora :
-	@echo "Generating aurora shared-object library"
-	@echo "compiler " $(fcompiler) " flags: " ${flags}
-	f2py3 -c --fcompiler=${fcompiler} -m _aurora aurora/main.f90 aurora/impden.f90 aurora/math.f90 aurora/grids.f90 --opt=${flags}
-	mv _aurora.cpython*.so aurora/
-
-julia :
-	julia -e 'import Pkg; Pkg.develop(path="aurora.jl/"); Pkg.add("PackageCompiler"); Pkg.add("PyCall"); Pkg.build("PyCall")'
-	python3 -m pip install --user julia
-	python3 -c "import julia; julia.install()"
-	python3 -m julia.sysimage aurora.jl/sysimage.so
-
-
-clean :
-	@echo "Eliminating Aurora shared-object library"
-	rm aurora/_aurora*.so
-
-clean_julia :
-	@echo "Eliminating Aurora Julia sysimage"
-	rm aurora.jl/sysimage.so
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 00000000..9933ce32
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,53 @@
+[project]
+name = "aurorafusion"
+dynamic = ["version"]
+description = "Aurora package for particle transport, radiation and neutrals in magnetically-confined plasmas"
+authors = [
+    { name = "F. Sciortino", email = "sciortino@psfc.mit.edu" },
+]
+urls = { "Homepage" = "https://github.com/fsciortino/Aurora" }
+keywords = ["particle and impurity transport, neutrals, radiation, magnetic confinement fusion"]
+classifiers = [
+    "Programming Language :: Python :: 3",
+]
+dependencies = [
+    "matplotlib",
+    "numpy",
+    "omfit_classes",
+    "pandas",
+    "pexpect",
+    "requests",
+    "scipy",
+    # transitive dependencies of omfit_classes
+    # that omfit_classes does not advertise
+    "fortranformat",
+    "netCDF4",
+    "uncertainties",
+    "omas",
+    # omfit_classes will have issues with newer versions
+    # of xarray for two different reasons:
+    # 1. because of a recently-introduced xarray bug that
+    #    will be fixed in the next release after v2024.02.0
+    #    (this commit: https://github.com/pydata/xarray/commit/a241845c0dfcb8a5a0396f5ef7602e9dae6155c0).
+    #    This constrains xarray<=v2023.07.0.
+    # 2. because omfit_classes uses xarray.plot.plot, which has
+    #    been removed/renamed by a commit from October 2022.
+    #    This constrains xarray<=v2022.09.0
+    "xarray==v2022.09.0",
+    # omfit_classes has issues with newer versions of
+    # matplotlib, see https://github.com/gafusion/OMFIT-source/issues/6784
+    "matplotlib<=3.5",
+]
+
+[build-system]
+requires = ["scikit-build-core", "numpy"]
+build-backend = "scikit_build_core.build"
+
+[tool.scikit-build]
+ninja.minimum-version = "1.10"
+cmake.minimum-version = "3.17.2"
+wheel.packages = ["aurora"]
+
+[tool.scikit-build.metadata.version]
+provider = "scikit_build_core.metadata.regex"
+input = "aurora/__init__.py"
diff --git a/requirements.txt b/requirements.txt
deleted file mode 100644
index 0f2c9bab..00000000
--- a/requirements.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-numpy
-scipy
-matplotlib
-pexpect
-omfit_classes
-requests
-pandas
diff --git a/setup.cfg b/setup.cfg
deleted file mode 100644
index 84e07596..00000000
--- a/setup.cfg
+++ /dev/null
@@ -1,2 +0,0 @@
-[metadata]
-version = attr: aurora.__version__
\ No newline at end of file
diff --git a/setup.py b/setup.py
deleted file mode 100644
index 95f6f25b..00000000
--- a/setup.py
+++ /dev/null
@@ -1,97 +0,0 @@
-"""
-Setup for Aurora package. Basic call (install in editable mode)
-pip install -e .
-
-To install with a different Fortran compiler, use e.g.
-python3 setup.py build --fcompiler=gnu95
-or
-python3 setup.py build --fcompiler=intelem 
-
-It should be possible to pass any f2py flags via the command line, e.g. using
-python3 setup.py build --fcompiler=intelem --opt="-fast"
-
-"""
-
-import os, sys, subprocess
-
-# need to import setuptools first and then also numpy.distutils to get Extension to work, see
-# https://stackoverflow.com/questions/51681438/numpy-distutils-not-recognizing-fortran-file-types
-import setuptools
-from numpy.distutils.core import setup, Extension
-
-package_name = "aurorafusion"
-
-
-def get_version(relpath):
-    """read version info from file without importing it"""
-    from os.path import dirname, join
-
-    for line in open(join(dirname(__file__), relpath)):
-        if "__version__" in line:
-            if '"' in line:
-                return line.split('"')[1]
-            elif "'" in line:
-                return line.split("'")[1]
-
-
-# with open('README.rst', 'r') as fh:
-#    long_description = fh.read()
-# long_description='See documentation at https://aurora-fusion.readthedocs.io'
-
-####
-with open("README.rst") as f:
-    long_description = "\n" + "\n".join(f.read().strip().split("\n")[2:])
-
-# Package adas_data and subdirectories together with license and readme
-package_data = ["../USER_AGREEMENT.txt", "../README.rst", "*"]
-for root, dir, files in os.walk("aurora"):
-    if root == "aurora":
-        continue
-    if "__pycache__" in root:
-        continue
-    package_data.append(root[len("aurora") + 1 :] + os.sep + "*")
-
-# For Fortran code:
-wrapper = Extension(
-    name="aurora._aurora",
-    sources=[
-        "aurora/main.f90",
-        "aurora/grids.f90",
-        "aurora/impden.f90",
-        "aurora/math.f90",
-    ],
-)
-
-install_requires = open("requirements.txt").read().split("\n")
-
-setup(
-    name=package_name,
-    version=get_version("aurora/__init__.py"),
-    description="Aurora package for particle transport, radiation and neutrals in magnetically-confined plasmas",
-    long_description=long_description,
-    # long_description_content_type='text/markdown',
-    url="https://github.com/fsciortino/Aurora",
-    author="F. Sciortino",
-    author_email="sciortino@psfc.mit.edu",
-    packages=["aurora"],
-    keywords="particle and impurity transport, neutrals, radiation, magnetic confinement fusion",
-    package_dir={"aurora": "aurora"},
-    package_data={"aurora": package_data},
-    data_files=[
-        (
-            "aurora_examples",
-            [
-                "examples/basic.py",
-                "examples/frac_abundances.py",
-                "examples/example.gfile",
-                "examples/example.input.gacode",
-            ],
-        )
-    ],
-    install_requires=install_requires,
-    ext_modules=[wrapper],
-    classifiers=[
-        "Programming Language :: Python :: 3",
-        #"Operating System :: OS Independent",
-    ],
-)


Test patch:
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 09f03ab2..882bf5d7 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -11,11 +11,9 @@ jobs:
     runs-on: ubuntu-latest
     strategy:
       matrix:
-        build_command: ["python setup.py develop",
-                        "pip install .",
-                        "pip install --editable .",
-                        "python setup.py install",
-                        # "echo 'no operation'",  # how to test this one?
+        build_command: [
+          "pip install .",
+          "pip install --editable .",
         ]
       fail-fast: false
 
@@ -25,15 +23,15 @@ jobs:
       uses: actions/setup-python@v2
       with:
         python-version: '3.9'
-    - name: Install dependencies
-      run: |
-        python -m pip install -r requirements.txt
     - name: Install Aurora
       run: ${{ matrix.build_command }}
     - name: Move to root and try importing Aurora
       run: |
         cd /
         python -c "import aurora; print(aurora.__version__)"
+    - name: Run test_basic.py
+      run: |
+        python examples/test_basic.py
 #    - name: Test with pytest and coverage
 #      run: |
 #        pip install pytest