Repository: OpenMDAO/dymos (language: python)

Issue:
Add support for PEP517 builds
### Summary

Using [PEP517](https://peps.python.org/pep-0517/) to build the source distribution fails, because the build system dependencies are not specified.

```bash
pip wheel --no-cache-dir --use-pep517 dymos
```

```bash
Collecting dymos
  Downloading dymos-1.10.0.tar.gz (567 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 567.3/567.3 kB 5.1 MB/s eta 0:00:00
  Installing build dependencies ... done
  Getting requirements to build wheel ... error
  error: subprocess-exited-with-error

  × Getting requirements to build wheel did not run successfully.
  │ exit code: 1
  ╰─> [17 lines of output]
      Traceback (most recent call last):
        File "PATH_TO_VIRTUAL_ENV\lib\site-packages\pip\_vendor\pyproject_hooks\_in_process\_in_process.py", line 353, in <module>
          main()
        File "PATH_TO_VIRTUAL_ENV\lib\site-packages\pip\_vendor\pyproject_hooks\_in_process\_in_process.py", line 335, in main
          json_out['return_val'] = hook(**hook_input['kwargs'])
        File "PATH_TO_VIRTUAL_ENV\lib\site-packages\pip\_vendor\pyproject_hooks\_in_process\_in_process.py", line 118, in get_requires_for_build_wheel
          return hook(config_settings)
        File "PATH_TO_TEMP\pip-build-env-p10744e1\overlay\Lib\site-packages\setuptools\build_meta.py", line 325, in get_requires_for_build_wheel
          return self._get_build_requires(config_settings, requirements=['wheel'])
        File "PATH_TO_TEMP\pip-build-env-p10744e1\overlay\Lib\site-packages\setuptools\build_meta.py", line 295, in _get_build_requires
          self.run_setup()
        File "PATH_TO_TEMP\pip-build-env-p10744e1\overlay\Lib\site-packages\setuptools\build_meta.py", line 487, in run_setup
          super().run_setup(setup_script=setup_script)
        File "PATH_TO_TEMP\pip-build-env-p10744e1\overlay\Lib\site-packages\setuptools\build_meta.py", line 311, in run_setup
          exec(code, locals())
        File "<string>", line 1, in <module>
      ModuleNotFoundError: No module named 'packaging'
      [end of output]

  note: This error originates from a subprocess, and is likely not a problem with pip.
error: subprocess-exited-with-error

× Getting requirements to build wheel did not run successfully.
│ exit code: 1
╰─> See above for output.

note: This error originates from a subprocess, and is likely not a problem with pip.
```

Support for [PEP517](https://peps.python.org/pep-0517/) is required as it is the recommended standard and dependency management systems such as [Poetry](https://python-poetry.org/) use the `--use-pep517` flag.

The error can be easily solved by adding a `pyproject.toml` file that specifies the required build dependencies. This is suggested in this pull request.

### Related Issues

None

### Backwards incompatibilities

None

### New Dependencies

None, [setuptools](https://setuptools.pypa.io/) is already required. The requirement is only specified.



Discussion / hints:

[![Coverage Status](https://coveralls.io/builds/66198074/badge)](https://coveralls.io/builds/66198074)

coverage: 92.7% (-0.1%) from 92.838%
when pulling **4dc8ed41c2a400959aad8361d6dc5130a3358368 on joel-martin:add-support-for-pep517-builds**
into **ed640d7cef5b28770a4d1958a7a9cc0b6d49811f on OpenMDAO:master**.

The specific error you showed will no longer occur as of #1027.  However if you're interested in using something like Poetry and thus need this change regardless, we'd accept it.  Is there a test you can add that verifies this change functions as you want it to?  Building a wheel or something?

Fix patch:
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 000000000..ce3cb5646
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,77 @@
+[build-system]
+requires = ["hatchling"]
+build-backend = "hatchling.build"
+
+[project]
+name = "dymos"
+dynamic = ["version"]
+description = "Open-Source Optimization of Dynamic Multidisciplinary Systems"
+license = "Apache-2.0"
+requires-python = ">=3.8"
+classifiers = [
+    "Development Status :: 5 - Production/Stable",
+    "Intended Audience :: Science/Research",
+    "License :: OSI Approved :: Apache Software License",
+    "Natural Language :: English",
+    "Operating System :: MacOS :: MacOS X",
+    "Operating System :: Microsoft :: Windows",
+    "Operating System :: POSIX :: Linux",
+    "Programming Language :: Python",
+    "Programming Language :: Python :: 3",
+    "Programming Language :: Python :: Implementation :: CPython",
+    "Topic :: Scientific/Engineering",
+]
+dependencies = [
+    "numpy",
+    "openmdao>=3.27.0",
+    "scipy",
+]
+
+[project.optional-dependencies]
+all = [
+    "dymos[docs]",
+    "dymos[notebooks]",
+    "dymos[test]",
+]
+docs = [
+    "bokeh",
+    "ipython",
+    "jax",
+    "jaxlib",
+    "jupyter",
+    "jupyter-book==0.14",
+    "matplotlib",
+    "nbconvert",
+    "notebook",
+    "numpydoc>=1.1",
+    "redbaron",
+    "tabulate",
+]
+notebooks = [
+    "ipython",
+    "notebook",
+    "tabulate",
+]
+test = [
+    "aiounittest",
+    "matplotlib",
+    "numpydoc>=1.1",
+    "packaging",
+    "playwright>=1.20",
+    "pycodestyle",
+    "testflo>=1.3.6",
+]
+
+[project.entry-points.openmdao_report]
+"dymos.linkage" = "dymos.visualization.linkage.report:_linkage_report_register"
+
+[project.urls]
+Homepage = "https://github.com/OpenMDAO/dymos"
+
+[tool.hatch.version]
+path = "dymos/__init__.py"
+
+[tool.hatch.build.targets.sdist]
+include = [
+    "/dymos",
+]
diff --git a/setup.py b/setup.py
deleted file mode 100644
index 05710be1e..000000000
--- a/setup.py
+++ /dev/null
@@ -1,88 +0,0 @@
-from setuptools import find_packages, setup
-
-# Setup optional dependencies
-optional_dependencies = {
-    'docs': [
-        'matplotlib',
-        'bokeh',
-        'jupyter',
-        'jupyter-book==0.14',
-        'nbconvert',
-        'notebook',
-        'ipython',
-        'numpydoc>=1.1',
-        'redbaron',
-        'tabulate',
-        'jaxlib',
-        'jax'
-    ],
-    'notebooks': [
-        'notebook',
-        'tabulate',
-        'ipython'
-    ],
-    'test': [
-        'packaging',
-        'pycodestyle',
-        'testflo>=1.3.6',
-        'matplotlib',
-        'numpydoc>=1.1',
-        'playwright>=1.20',
-        'aiounittest'
-    ]
-}
-
-# Add an optional dependency that concatenates all others
-optional_dependencies['all'] = sorted([
-    dependency
-    for dependencies in optional_dependencies.values()
-    for dependency in dependencies
-])
-
-
-setup(name='dymos',
-    version='1.10.1-dev',
-    description='Open-Source Optimization of Dynamic Multidisciplinary Systems',
-    long_description='''
-Dymos is a framework for the simulation and optimization of dynamical systems within the OpenMDAO Multidisciplinary Analysis and Optimization environment.
-Dymos leverages implicit and explicit simulation techniques to simulate generic dynamic systems of arbitary complexity.
-
-The software has two primary objectives:
--   Provide a generic ODE integration interface that allows for the analysis of dynamical systems.
--   Allow the user to solve optimal control problems involving dynamical multidisciplinary systems.''',
-    long_description_content_type='text/markdown',
-    url='https://github.com/OpenMDAO/dymos',
-    classifiers=[
-        'Development Status :: 5 - Production/Stable',
-        'Intended Audience :: Science/Research',
-        'License :: OSI Approved :: Apache Software License',
-        'Natural Language :: English',
-        'Operating System :: MacOS :: MacOS X',
-        'Operating System :: POSIX :: Linux',
-        'Operating System :: Microsoft :: Windows',
-        'Topic :: Scientific/Engineering',
-        'Programming Language :: Python',
-        'Programming Language :: Python :: 3',
-        'Programming Language :: Python :: Implementation :: CPython',
-    ],
-    license='Apache License',
-    packages=find_packages(),
-    python_requires=">=3.8",
-    install_requires=[
-        'openmdao>=3.27.0',
-        'numpy',
-        'scipy'
-    ],
-    extras_require=optional_dependencies,
-    zip_safe=False,
-    package_data={
-        'dymos.examples.aircraft_steady_flight.aero': ['data/CRM_aero_inputs.dat', 'data/CRM_aero_outputs.dat'],
-        'dymos.visualization.linkage': ['report_template.html', 'js/*', 'style/*'],
-        'dymos.visualization.linkage.test': ['model_data.dat']
-    },
-    entry_points = {
-        'openmdao_report': [
-            'dymos.linkage=dymos.visualization.linkage.report:_linkage_report_register'
-        ],
-    },
-)
diff --git a/travis_deploy_rsa.enc b/travis_deploy_rsa.enc
deleted file mode 100644
index 98d1a9638..000000000
Binary files a/travis_deploy_rsa.enc and /dev/null differ


Test patch:
diff --git a/.github/workflows/dymos_tests_workflow.yml b/.github/workflows/dymos_tests_workflow.yml
index 381a0cce6..480bdb3fa 100644
--- a/.github/workflows/dymos_tests_workflow.yml
+++ b/.github/workflows/dymos_tests_workflow.yml
@@ -35,6 +35,7 @@ jobs:
             PYOPTSPARSE: 'v2.9.3'
             SNOPT: 7.7
             OPENMDAO: 'latest'
+            PEP517: true
             OPTIONAL: '[all]'
             JAX: '0.4.14'
 
@@ -130,11 +131,6 @@ jobs:
         if: env.RUN_BUILD
         uses: actions/checkout@v3
 
-      - name: Fetch tags
-        if: env.RUN_BUILD
-        run: |
-          git fetch --prune --unshallow --tags
-
       - name: Setup conda
         if: env.RUN_BUILD
         uses: conda-incubator/setup-miniconda@v2
@@ -258,7 +254,16 @@ jobs:
           echo "============================================================="
           echo "Install Dymos"
           echo "============================================================="
-          pip install .${{ matrix.OPTIONAL }}
+          if [[ "${{ matrix.PEP517 }}" == "true" ]]; then
+            pip wheel --no-deps --use-pep517 .
+            WHEEL=`find dymos-*.whl`
+            echo "-----------------------------------------------------------"
+            echo "Installing from wheel: $WHEEL"
+            echo "-----------------------------------------------------------"
+            python -m pip install $WHEEL${{ matrix.OPTIONAL }}
+          else
+            python -m pip install .${{ matrix.OPTIONAL }}
+          fi
 
       - name: Display environment info
         if: env.RUN_BUILD