8000 Merge pull request #759 from bnavigator/setuptools-update · steadymingha/python-control@d4c1f14 · GitHub
[go: up one dir, main page]

Skip to content

Commit d4c1f14

Browse files
authored
Merge pull request python-control#759 from bnavigator/setuptools-update
Build system and test suite update
2 parents 87a9c57 + 69fb34a commit d4c1f14

File tree

13 files changed

+112
-190
lines changed

13 files changed

+112
-190
lines changed

.github/conda-env/test-env.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ dependencies:
66
- pytest
77
- pytest-cov
88
- pytest-timeout
9+
- pytest-xvfb
910
- numpy
1011
- matplotlib
11-
- scipy
12+
- scipy

.github/workflows/control-slycot-src.yml

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,8 @@ jobs:
1313
path: python-control
1414
- name: Set up Python
1515
uses: actions/setup-python@v2
16-
- name: Install Python dependencies
17-
run: |
18-
# Set up conda
19-
echo $CONDA/bin >> $GITHUB_PATH
20-
21-
# Set up (virtual) X11
22-
sudo apt install -y xvfb
23-
24-
# Install test tools
25-
conda install pip pytest pytest-timeout
26-
27-
# Install python-control dependencies
28-
conda install numpy matplotlib scipy
16+
- name: Install Python dependencies and test tools
17+
run: pip install -v -e './python-control[test]'
2918

3019
- name: Checkout Slycot
3120
uses: actions/checkout@v3
@@ -43,11 +32,10 @@ jobs:
4332
# Install compilers, libraries, and development environment
4433
sudo apt-get -y install gfortran cmake --fix-missing
4534
sudo apt-get -y install libblas-dev liblapack-dev
46-
conda install -c conda-forge scikit-build setuptools-scm
4735
4836
# Compile and install slycot
49-
pip install -v --no-build-isolation --no-deps .
37+
pip install -v .
5038
5139
- name: Test with pytest
5240
working-directory: python-control
53-
run: xvfb-run --auto-servernum pytest control/tests
41+
run: pytest -v control/tests

.github/workflows/install_examples.yml

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: setup.py, examples
1+
name: Setup, Examples, Notebooks
22

33
on: [push, pull_request]
44

@@ -7,26 +7,23 @@ jobs:
77
runs-on: ubuntu-latest
88

99
steps:
10-
- uses: actions/checkout@v2
11-
- name: Set up Python
12-
uses: actions/setup-python@v2
13-
- name: Install Python dependencies
10+
- uses: actions/checkout@v3
11+
- name: Install Python dependencies from conda-forge
1412
run: |
15-
# Set up conda
13+
# Set up conda using the preinstalled GHA Miniconda environment
1614
echo $CONDA/bin >> $GITHUB_PATH
15+
conda config --add channels conda-forge
16+
conda config --set channel_priority strict
1717
18-
# Set up (virtual) X11
19-
sudo apt install -y xvfb
18+
# Install build tools
19+
conda install pip setuptools setuptools-scm
2020
21-
# Install test tools
22-
conda install pip pytest
21+
# Install python-control dependencies and extras
22+
conda install numpy matplotlib scipy
23+
conda install slycot pmw jupyter
2324
24-
# Install python-control dependencies
25-
conda install numpy matplotlib scipy jupyter
26-
conda install -c conda-forge slycot pmw
27-
28-
- name: In F438 stall with setup.py
29-
run: python setup.py install
25+
- name: Install from source
26+
run: pip install .
3027

3128
- name: Run examples
3229
run: |

.github/workflows/python-package-conda.yml

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,32 @@ jobs:
88
Py${{ matrix.python-version }};
99
${{ matrix.slycot || 'no' }} Slycot;
1010
${{ matrix.pandas || 'no' }} Pandas;
11-
${{ matrix.cvxopt || 'no' }} CVXOPT;
11+
${{ matrix.cvxopt || 'no' }} CVXOPT
1212
${{ matrix.array-and-matrix == 1 && '; array and matrix' || '' }}
13+
${{ matrix.mplbackend && format('; {0}', matrix.mplbackend) }}
1314
runs-on: ubuntu-latest
1415

1516
strategy:
1617
max-parallel: 5
18+
fail-fast: false
1719
matrix:
18-
python-version: [3.7, 3.9]
20+
python-version: ['3.7', '3.10']
1921
slycot: ["", "conda"]
2022
pandas: [""]
2123
cvxopt: ["", "conda"]
24+
mplbackend: [""]
2225
array-and-matrix: [0]
2326
include:
24-
- python-version: 3.9
27+
- python-version: '3.10'
2528
slycot: conda
2629
pandas: conda
30+
cvxopt: conda
31+
mplbackend: QtAgg
2732
array-and-matrix: 1
2833

2934
steps:
3035
- uses: actions/checkout@v3
3136

32-
- name: Set up (virtual) X11
33-
run: sudo apt install -y xvfb
34-
3537
- name: Setup Conda
3638
uses: conda-incubator/setup-miniconda@v2
3739
with:
@@ -55,15 +57,15 @@ jobs:
5557
mamba install pandas
5658
fi
5759
if [[ '${{matrix.cvxopt}}' == 'conda' ]]; then
58-
mamba install cvxopt
60+
mamba install cvxopt
5961
fi
6062
6163
- name: Test with pytest
6264
shell: bash -l {0}
6365
env:
6466
PYTHON_CONTROL_ARRAY_AND_MATRIX: ${{ matrix.array-and-matrix }}
65-
run: |
66-
xvfb-run --auto-servernum pytest --cov=control --cov-config=.coveragerc control/tests
67+
MPLBACKEND: ${{ matrix.mplbackend }}
68+
run: pytest -v --cov=control --cov-config=.coveragerc control/tests
6769

6870
- name: Coveralls parallel
6971
# https://github.com/coverallsapp/github-action

README.rst

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -97,17 +97,14 @@ To install using pip::
9797
If you install Slycot using pip you'll need a development environment
9898
(e.g., Python development files, C and Fortran compilers).
9999

100-
Distutils
101-
---------
100+
Installing from source
101+
----------------------
102102

103-
To install in your home directory, use::
103+
To install from source, get the source code of the desired branch or release
104+
from the github repository or archive, unpack, and run from within the
105+
toplevel `python-control` directory::
104106

105-
python setup.py install --user
106-
107-
To install for all users (on Linux or Mac OS)::
108-
109-
python setup.py build
110-
sudo python setup.py install
107+
pip install .
111108

112109

113110
Development

control/tests/config_test.py

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from math import pi, log10
99

1010
import matplotlib.pyplot as plt
11-
from matplotlib.testing.decorators import cleanup as mplcleanup
1211
import numpy as np
1312
import pytest
1413

@@ -18,7 +17,6 @@
1817
@pytest.mark.usefixtures("editsdefaults") # makes sure to reset the defaults
1918
# to the test configuration
2019
class TestConfig:
21-
2220
# Create a simple second order system to use for testing
2321
sys = ct.tf([10], [1, 2, 1])
2422

@@ -28,8 +26,7 @@ def test_set_defaults(self):
2826
assert ct.config.defaults['freqplot.deg'] == 2
2927
assert ct.config.defaults['freqplot.Hz'] is None
3028

31-
@mplcleanup
32-
def test_get_param(self):
29+
def test_get_param(self, mplcleanup):
3330
assert ct.config._get_param('freqplot', 'dB')\
3431
== ct.config.defaults['freqplot.dB']
3532
assert ct.config._get_param('freqplot', 'dB', 1) == 1
@@ -92,8 +89,7 @@ def test_default_deprecation(self):
9289
assert ct.config.defaults['bode.Hz'] \
9390
== ct.config.defaults['freqplot.Hz']
9491

95-
@mplcleanup
96-
def test_fbs_bode(self):
92+
def test_fbs_bode(self, mplcleanup):
9793
ct.use_fbs_defaults()
9894

9995
# Generate a Bode plot
@@ -137,8 +133,7 @@ def test_fbs_bode(self):
137133
phase_x, phase_y = (((plt.gcf().axes[1]).get_lines())[0]).get_data()
138134
np.testing.assert_almost_equal(phase_y[-1], -pi, decimal=2)
139135

140-
@mplcleanup
141-
def test_matlab_bode(self):
136+
def test_matlab_bode(self, mplcleanup):
142137
ct.use_matlab_defaults()
143138

144139
# Generate a Bode plot
@@ -182,8 +177,7 @@ def test_matlab_bode(self):
182177
phase_x, phase_y = (((plt.gcf().axes[1]).get_lines())[0]).get_data()
183178
np.testing.assert_almost_equal(phase_y[-1], -pi, decimal=2)
184179

185-
@mplcleanup
186-
def test_custom_bode_default(self):
180+
def test_custom_bode_default(self, mplcleanup):
187181
ct.config.defaults['freqplot.dB'] = True
188182
ct.config.defaults['freqplot.deg'] = True
189183
ct.config.defaults['freqplot.Hz'] = True
@@ -204,8 +198,7 @@ def test_custom_bode_default(self):
204198
np.testing.assert_almost_equal(mag_y[0], 20*log10(10), decimal=3)
205199
np.testing.assert_almost_equal(phase_y[-1], -pi, decimal=2)
206200

207-
@mplcleanup
208-
def test_bode_number_of_samples(self):
201+
def test_bode_number_of_samples(self, mplcleanup):
209202
# Set the number of samples (default is 50, from np.logspace)
210203
mag_ret, phase_ret, omega_ret = ct.bode_plot(self.sys, omega_num=87)
211204
assert len(mag_ret) == 87
@@ -219,8 +212,7 @@ def test_bode_number_of_samples(self):
219212
mag_ret, phase_ret, omega_ret = ct.bode_plot(self.sys, omega_num=87)
220213
assert len(mag_ret) == 87
221214

222-
@mplcleanup
223-
def test_bode_feature_periphery_decade(self):
215+
def test_bode_feature_periphery_decade(self, mplcleanup):
224216
# Generate a sample Bode plot to figure out the range it uses
225217
ct.reset_defaults() # Make sure starting state is correct
226218
mag_ret, phase_ret, omega_ret = ct.bode_plot(self.sys, Hz=False)

control/tests/conftest.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
"""conftest.py - pytest local plugins and fixtures"""
22

33
import os
4-
import sys
54
from contextlib import contextmanager
65

76
import matplotlib as mpl
87
import numpy as np
98
import pytest
10-
import scipy as sp
119

1210
import control
1311

@@ -45,15 +43,15 @@ def control_defaults():
4543
params=[pytest.param("arrayout", marks=matrixerrorfilter),
4644
pytest.param("matrixout", marks=matrixfilter)])
4745
def matarrayout(request):
48-
"""Switch the config to use np.ndarray and np.matrix as returns"""
46+
"""Switch the config to use np.ndarray and np.matrix as returns."""
4947
restore = control.config.defaults['statesp.use_numpy_matrix']
5048
control.use_numpy_matrix(request.param == "matrixout", warn=False)
5149
yield
5250
control.use_numpy_matrix(restore, warn=False)
5351

5452

5553
def ismatarrayout(obj):
56-
"""Test if the returned object has the correct type as configured
54+
"""Test if the returned object has the correct type as configured.
5755
5856
note that isinstance(np.matrix(obj), np.ndarray) is True
5957
"""
@@ -63,15 +61,15 @@ def ismatarrayout(obj):
6361

6462

6563
def asmatarrayout(obj):
66-
"""Return a object according to the configured default"""
64+
"""Return a object according to the configured default."""
6765
use_matrix = control.config.defaults['statesp.use_numpy_matrix']
6866
matarray = np.asmatrix if use_matrix else np.asarray
6967
return matarray(obj)
7068

7169

7270
@contextmanager
7371
def check_deprecated_matrix():
74-
"""Check that a call produces a deprecation warning because of np.matrix"""
72+
"""Check that a call produces a deprecation warning because of np.matrix."""
7573
use_matrix = control.config.defaults['statesp.use_numpy_matrix']
7674
if use_matrix:
7775
with pytest.deprecated_call():
@@ -94,13 +92,13 @@ def check_deprecated_matrix():
9492
False)]
9593
if usebydefault or TEST_MATRIX_AND_ARRAY])
9694
def matarrayin(request):
97-
"""Use array and matrix to construct input data in tests"""
95+
"""Use array and matrix to construct input data in tests."""
9896
return request.param
9997

10098

10199
@pytest.fixture(scope="function")
102100
def editsdefaults():
103-
"""Make sure any changes to the defaults only last during a test"""
101+
"""Make sure any changes to the defaults only last during a test."""
104102
restore = control.config.defaults.copy()
105103
yield
106104
control.config.defaults = restore.copy()

control/tests/rlocus_test.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ def test_root_locus_neg_false_gain_nonproper(self):
8585

8686
# TODO: cover and validate negative false_gain branch in _default_gains()
8787

88+
@pytest.mark.skipif(plt.get_current_fig_manager().toolbar is None,
89+
reason="Requires the zoom toolbar")
8890
def test_root_locus_zoom(self):
8991
"""Check the zooming functionality of the Root locus plot"""
9092
system = TransferFunction([1000], [1, 25, 100, 0])

control/tests/sisotool_test.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ def sys221(self):
4646
D221 = [[1., -1.]]
4747
return StateSpace(A222, B222, C221, D221)
4848

49+
@pytest.mark.skipif(plt.get_current_fig_manager().toolbar is None,
50+
reason="Requires the zoom toolbar")
4951
def test_sisotool(self, tsys):
5052
sisotool(tsys, Hz=False)
5153
fig = plt.gcf()
@@ -114,6 +116,8 @@ def test_sisotool(self, tsys):
114116
assert_array_almost_equal(
115117
ax_step.lines[0].get_data()[1][:10], step_response_moved, 4)
116118

119+
@pytest.mark.skipif(plt.get_current_fig_manager().toolbar is None,
120+
reason="Requires the zoom toolbar")
117121
@pytest.mark.parametrize('tsys', [0, True],
118122
indirect=True, ids=['ctime', 'dtime'])
119123
def test_sisotool_tvect(self, tsys):

0 commit comments

Comments
 (0)
0