Skip to content

Support Python 3.12, Bump minimum support according to SPEC 0 #961

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jan 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/conda-env/build-env.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: build-env
dependencies:
- boa
- numpy !=1.23.0
- numpy
6 changes: 1 addition & 5 deletions .github/conda-env/doctest-env.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
name: test-env
name: doctest-env
dependencies:
- conda-build # for conda index
- pip
- coverage
- coveralls
- pytest
- pytest-cov
- pytest-timeout
- pytest-xvfb
- numpy
Expand Down
2 changes: 0 additions & 2 deletions .github/conda-env/test-env.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
name: test-env
dependencies:
- conda-build # for conda index
- pip
- coverage
- coveralls
- pytest
- pytest-cov
- pytest-timeout
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/control-slycot-src.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
python-version: '3.12'
- name: Install Python dependencies and test tools
run: pip install -v './python-control[test]'

Expand Down
6 changes: 2 additions & 4 deletions .github/workflows/doctest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ jobs:
- name: Setup Conda
uses: conda-incubator/setup-miniconda@v2
with:
python-version: 3.11
activate-environment: test-env
python-version: 3.12
activate-environment: doctest-env
environment-file: .github/conda-env/doctest-env.yml
miniforge-version: latest
miniforge-variant: Mambaforge
Expand All @@ -32,8 +32,6 @@ jobs:

- name: Run doctest
shell: bash -l {0}
env:
MPLBACKEND: ${{ matrix.mplbackend }}
working-directory: doc
run: |
make html
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/install_examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
--channel conda-forge \
--strict-channel-priority \
--quiet --yes \
python=3.11 pip \
python=3.12 pip \
numpy matplotlib scipy \
slycot pmw jupyter

Expand Down
23 changes: 11 additions & 12 deletions .github/workflows/os-blas-test-matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,24 @@ jobs:
- 'ubuntu'
- 'macos'
python:
- '3.8'
- '3.11'
- '3.10'
- '3.12'
bla_vendor: [ 'unset' ]
include:
- os: 'ubuntu'
python: '3.11'
python: '3.12'
bla_vendor: 'Generic'
- os: 'ubuntu'
python: '3.11'
python: '3.12'
bla_vendor: 'OpenBLAS'
- os: 'macos'
python: '3.11'
python: '3.12'
bla_vendor: 'Apple'
- os: 'macos'
python: '3.11'
python: '3.12'
bla_vendor: 'Generic'
- os: 'macos'
python: '3.11'
python: '3.12'
bla_vendor: 'OpenBLAS'

steps:
Expand Down Expand Up @@ -108,7 +108,7 @@ jobs:
- 'macos'
- 'windows'
python:
- '3.9'
# build on one, expand matrix in conda-build from the Sylcot/conda-recipe/conda_build_config.yaml
- '3.11'

steps:
Expand All @@ -133,14 +133,14 @@ jobs:
shell: bash -l {0}
run: |
set -e
numpyversion=$(python -c 'import numpy; print(numpy.version.version)')
conda mambabuild --python "${{ matrix.python }}" --numpy $numpyversion conda-recipe
conda mambabuild conda-recipe
# preserve directory structure for custom conda channel
find "${CONDA_PREFIX}/conda-bld" -maxdepth 2 -name 'slycot*.tar.bz2' | while read -r conda_pkg; do
conda_platform=$(basename $(dirname "${conda_pkg}"))
mkdir -p "slycot-conda-pkgs/${conda_platform}"
cp "${conda_pkg}" "slycot-conda-pkgs/${conda_platform}/"
done
conda index --no-progress ./slycot-conda-pkgs
- name: Save to local conda pkg channel
uses: actions/upload-artifact@v3
with:
Expand Down Expand Up @@ -247,7 +247,7 @@ jobs:
- name: Install Wheel
run: |
python -m pip install --upgrade pip
pip install matplotlib scipy pytest pytest-cov pytest-timeout coverage coveralls
pip install matplotlib scipy pytest pytest-cov pytest-timeout coverage
pip install slycot-wheels/${{ matrix.packagekey }}/slycot*.whl
pip show slycot
- name: Test with pytest
Expand Down Expand Up @@ -316,7 +316,6 @@ jobs:
echo "libblas * *mkl" >> $CONDA_PREFIX/conda-meta/pinned
;;
esac
conda index --no-progress ./slycot-conda-pkgs
mamba install -c ./slycot-conda-pkgs slycot
conda list
- name: Test with pytest
Expand Down
29 changes: 18 additions & 11 deletions .github/workflows/python-package-conda.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ jobs:
max-parallel: 5
fail-fast: false
matrix:
python-version: ['3.8', '3.11']
python-version: ['3.10', '3.12']
slycot: ["", "conda"]
pandas: [""]
cvxopt: ["", "conda"]
mplbackend: [""]
include:
- python-version: '3.11'
- python-version: '3.12'
slycot: conda
pandas: conda
cvxopt: conda
Expand Down Expand Up @@ -61,20 +61,27 @@ jobs:
shell: bash -l {0}
env:
MPLBACKEND: ${{ matrix.mplbackend }}
run: pytest -v --cov=control --cov-config=.coveragerc control/tests
run: |
pytest -v --cov=control --cov-config=.coveragerc control/tests
coverage xml

- name: Coveralls parallel
# https://github.com/coverallsapp/github-action
uses: AndreMiras/coveralls-python-action@develop
- name: report coverage
uses: coverallsapp/github-action@v2
with:
flag-name: conda-pytest_py${{ matrix.python-version }}_${{ matrix.slycot || 'no' }}-Slycot_${{ matrix.pandas || 'no' }}-Pandas_${{ matrix.cvxopt || 'no' }}_CVXOPT-${{ matrix.mplbackend && format('; {0}', matrix.mplbackend) }}
parallel: true
file: coverage.xml

coveralls:
name: coveralls completion
needs: test-linux-conda
coveralls-final:
name: Finalize parallel coveralls
if: always()
needs:
- test-linux-conda
runs-on: ubuntu-latest
steps:
- name: Coveralls Finished
uses: AndreMiras/coveralls-python-action@develop
uses: coverallsapp/github-action@v2
with:
parallel-finished: true
parallel-finished: true


14 changes: 14 additions & 0 deletions control/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,20 @@ def __missing__(self, key):
else:
raise KeyError(key)

# New get function for Python 3.12+ to replicate old behavior
def get(self, key, defval=None):
# If the key exists, return it
if self.__contains__(key):
return self[key]

# If not, see if it is deprecated
repl = self._check_deprecation(key)
if self.__contains__(repl):
return self.get(repl, defval)

# Otherwise, call the usual dict.get() method
return super().get(key, defval)

def _check_deprecation(self, key):
if self.__contains__(f"deprecated.{key}"):
repl = self[f"deprecated.{key}"]
Expand Down
8 changes: 4 additions & 4 deletions control/tests/interconnect_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -409,16 +409,16 @@ def test_linear_interconnect():
ct.StateSpace)

# Interconnections with nonliner I/O systems should not be linear
assert ~isinstance(
assert not isinstance(
ct.interconnect([nl_ctrl, ss_plant, sumblk], inputs='r', outputs='y'),
ct.StateSpace)
assert ~isinstance(
assert not isinstance(
ct.interconnect([nl_ctrl, tf_plant, sumblk], inputs='r', outputs='y'),
ct.StateSpace)
assert ~isinstance(
assert not isinstance(
ct.interconnect([ss_ctrl, nl_plant, sumblk], inputs='r', outputs='y'),
ct.StateSpace)
assert ~isinstance(
assert not isinstance(
ct.interconnect([tf_ctrl, nl_plant, sumblk], inputs='r', outputs='y'),
ct.StateSpace)

Expand Down
12 changes: 6 additions & 6 deletions control/tests/iosys_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1579,12 +1579,12 @@ def test_linear_interconnection():
assert isinstance(ss_siso*ss_siso, ct.StateSpace)
assert isinstance(tf_siso*ss_siso, ct.TransferFunction)
assert isinstance(ss_siso*tf_siso, ct.StateSpace)
assert ~isinstance(ss_siso*nl_siso, ct.StateSpace)
assert ~isinstance(nl_siso*ss_siso, ct.StateSpace)
assert ~isinstance(nl_siso*nl_siso, ct.StateSpace)
assert ~isinstance(tf_siso*nl_siso, ct.StateSpace)
assert ~isinstance(nl_siso*tf_siso, ct.StateSpace)
assert ~isinstance(nl_siso*nl_siso, ct.StateSpace)
assert not isinstance(ss_siso*nl_siso, ct.StateSpace)
assert not isinstance(nl_siso*ss_siso, ct.StateSpace)
assert not isinstance(nl_siso*nl_siso, ct.StateSpace)
assert not isinstance(tf_siso*nl_siso, ct.StateSpace)
assert not isinstance(nl_siso*tf_siso, ct.StateSpace)
assert not isinstance(nl_siso*nl_siso, ct.StateSpace)


def predprey(t, x, u, params={}):
Expand Down
11 changes: 5 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,21 @@ classifiers = [
"Intended Audience :: Developers",
"License :: OSI Approved :: BSD License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Software Development",
"Topic :: Scientific/Engineering",
"Operating System :: Microsoft :: Windows",
"Operating System :: POSIX",
"Operating System :: Unix",
"Operating System :: MacOS",
]
requires-python = ">=3.8"
requires-python = ">=3.10"
dependencies = [
"numpy",
"scipy>=1.3",
"matplotlib",
"numpy>=1.23",
"scipy>=1.8",
"matplotlib>=3.6",
]
dynamic = ["version"]

Expand Down