Skip to content

Commit d4ee3be

Browse files
committed
clean from old scipyy<1.3 and python2 code
1 parent e3ae8ed commit d4ee3be

7 files changed

Lines changed: 15 additions & 48 deletions

File tree

control/tests/conftest.py

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

33
from contextlib import contextmanager
4-
from distutils.version import StrictVersion
54
import os
65
import sys
76

@@ -18,10 +17,6 @@
1817
# pytest.param(marks=)
1918
slycotonly = pytest.mark.skipif(not control.exception.slycot_check(),
2019
reason="slycot not installed")
21-
noscipy0 = pytest.mark.skipif(StrictVersion(sp.__version__) < "1.0",
22-
reason="requires SciPy 1.0 or greater")
23-
nopython2 = pytest.mark.skipif(sys.version_info < (3, 0),
24-
reason="requires Python 3+")
2520
matrixfilter = pytest.mark.filterwarnings("ignore:.*matrix subclass:"
2621
"PendingDeprecationWarning")
2722
matrixerrorfilter = pytest.mark.filterwarnings("error:.*matrix subclass:"
@@ -110,10 +105,10 @@ def editsdefaults():
110105

111106
@pytest.fixture(scope="function")
112107
def mplcleanup():
113-
"""Workaround for python2
114-
115-
python 2 does not like to mix the original mpl decorator with pytest
116-
fixtures. So we roll our own.
108+
"""Clean up any plots and changes a test may have made to matplotlib.
109+
110+
compare matplotlib.testing.decorators.cleanup() but as a fixture instead
111+
of a decorator.
117112
"""
118113
save = mpl.units.registry.copy()
119114
try:

control/tests/flatsys_test.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
created for that purpose.
99
"""
1010

11-
from distutils.version import StrictVersion
12-
1311
import numpy as np
1412
import pytest
1513
import scipy as sp
@@ -118,11 +116,10 @@ def test_kinematic_car(self, vehicle_flat, poly):
118116
resp = ct.input_output_response(vehicle_flat, T, ud, x0)
119117
np.testing.assert_array_almost_equal(resp.states, xd, decimal=2)
120118

121-
# For SciPy 1.0+, integrate equations and compare to desired
122-
if StrictVersion(sp.__version__) >= "1.0":
123-
t, y, x = ct.input_output_response(
124-
vehicle_flat, T, ud, x0, return_x=True)
125-
np.testing.assert_allclose(x, xd, atol=0.01, rtol=0.01)
119+
# integrate equations and compare to desired
120+
t, y, x = ct.input_output_response(
121+
vehicle_flat, T, ud, x0, return_x=True)
122+
np.testing.assert_allclose(x, xd, atol=0.01, rtol=0.01)
126123

127124
def test_flat_default_output(self, vehicle_flat):
128125
# Construct a flat system with the default outputs

control/tests/iosys_test.py

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
import control as ct
1717
from control import iosys as ios
18-
from control.tests.conftest import noscipy0, matrixfilter
18+
from control.tests.conftest import matrixfilter
1919

2020
class TestIOSys:
2121

@@ -46,7 +46,6 @@ class TSys:
4646

4747
return T
4848

49-
@noscipy0
5049
def test_linear_iosys(self, tsys):
5150
# Create an input/output system from the linear system
5251
linsys = tsys.siso_linsys
@@ -65,7 +64,6 @@ def test_linear_iosys(self, tsys):
6564
np.testing.assert_array_almost_equal(lti_t, ios_t)
6665
np.testing.assert_allclose(lti_y, ios_y, atol=0.002, rtol=0.)
6766

68-
@noscipy0
6967
def test_tf2io(self, tsys):
7068
# Create a transfer function from the state space system
7169
linsys = tsys.siso_linsys
@@ -129,7 +127,6 @@ def test_iosys_print(self, tsys, capsys):
129127
ios_linearized = ios.linearize(ios_unspecified, [0, 0], [0])
130128
print(ios_linearized)
131129

132-
@noscipy0
133130
@pytest.mark.parametrize("ss", [ios.NonlinearIOSystem, ct.ss])
134131
def test_nonlinear_iosys(self, tsys, ss):
135132
# Create a simple nonlinear I/O system
@@ -236,7 +233,6 @@ def test_linearize_named_signals(self, kincar):
236233
assert lin_nocopy.find_output('x') is None
237234
assert lin_nocopy.find_state('x') is None
238235

239-
@noscipy0
240236
def test_connect(self, tsys):
241237
# Define a couple of (linear) systems to interconnection
242238
linsys1 = tsys.siso_linsys
@@ -294,7 +290,6 @@ def test_connect(self, tsys):
294290
np.testing.assert_array_almost_equal(lti_t, ios_t)
295291
np.testing.assert_allclose(lti_y, ios_y,atol=0.002,rtol=0.)
296292

297-
@noscipy0
298293
@pytest.mark.parametrize(
299294
"connections, inplist, outlist",
300295
[pytest.param([[(1, 0), (0, 0, 1)]], [[(0, 0, 1)]], [[(1, 0, 1)]],
@@ -338,7 +333,6 @@ def test_connect_spec_variants(self, tsys, connections, inplist, outlist):
338333
np.testing.assert_array_almost_equal(lti_t, ios_t)
339334
np.testing.assert_allclose(lti_y, ios_y, atol=0.002, rtol=0.)
340335

341-
@noscipy0
342336
@pytest.mark.parametrize(
343337
"connections, inplist, outlist",
344338
[pytest.param([['sys2.u[0]', 'sys1.y[0]']],
@@ -375,7 +369,6 @@ def test_connect_spec_warnings(self, tsys, connections, inplist, outlist):
375369
np.testing.assert_array_almost_equal(lti_t, ios_t)
376370
np.testing.assert_allclose(lti_y, ios_y, atol=0.002, rtol=0.)
377371

378-
@noscipy0
379372
def test_static_nonlinearity(self, tsys):
380373
# Linear dynamical system
381374
linsys = tsys.siso_linsys
@@ -400,7 +393,6 @@ def test_static_nonlinearity(self, tsys):
400393
np.testing.assert_array_almost_equal(lti_y, ios_y, decimal=2)
401394

402395

403-
@noscipy0
404396
@pytest.mark.filterwarnings("ignore:Duplicate name::control.iosys")
405397
def test_algebraic_loop(self, tsys):
406398
# Create some linear and nonlinear systems to play with
@@ -470,7 +462,6 @@ def test_algebraic_loop(self, tsys):
470462
with pytest.raises(RuntimeError):
471463
ios.input_output_response(*args)
472464

473-
@noscipy0
474465
def test_summer(self, tsys):
475466
# Construct a MIMO system for testing
476467
linsys = tsys.mimo_linsys1
@@ -489,7 +480,6 @@ def test_summer(self, tsys):
489480
ios_t, ios_y = ios.input_output_response(iosys_parallel, T, U, X0)
490481
np.testing.assert_allclose(ios_y, lin_y,atol=0.002,rtol=0.)
491482

492-
@noscipy0
493483
def test_rmul(self, tsys):
494484
# Test right multiplication
495485
# TODO: replace with better tests when conversions are implemented
@@ -510,7 +500,6 @@ def test_rmul(self, tsys):
510500
lti_t, lti_y = ct.forced_response(ioslin, T, U*U, X0)
511501
np.testing.assert_array_almost_equal(ios_y, lti_y*lti_y, decimal=3)
512502

513-
@noscipy0
514503
def test_neg(self, tsys):
515504
"""Test negation of a system"""
516505

@@ -533,7 +522,6 @@ def test_neg(self, tsys):
533522
lti_t, lti_y = ct.forced_response(ioslin, T, U*U, X0)
534523
np.testing.assert_array_almost_equal(ios_y, -lti_y, decimal=3)
535524

536-
@noscipy0
537525
def test_feedback(self, tsys):
538526
# Set up parameters for simulation
539527
T, U, X0 = tsys.T, tsys.U, tsys.X0
@@ -549,7 +537,6 @@ def test_feedback(self, tsys):
549537
lti_t, lti_y = ct.forced_response(linsys, T, U, X0)
550538
np.testing.assert_allclose(ios_y, lti_y,atol=0.002,rtol=0.)
551539

552-
@noscipy0
553540
def test_bdalg_functions(self, tsys):
554541
"""Test block diagram functions algebra on I/O systems"""
555542
# Set up parameters for simulation
@@ -596,7 +583,6 @@ def test_bdalg_functions(self, tsys):
596583
ios_t, ios_y = ios.input_output_response(iosys_feedback, T, U, X0)
597584
np.testing.assert_allclose(ios_y, lin_y,atol=0.002,rtol=0.)
598585

599-
@noscipy0
600586
def test_algebraic_functions(self, tsys):
601587
"""Test algebraic operations on I/O systems"""
602588
# Set up parameters for simulation
@@ -648,7 +634,6 @@ def test_algebraic_functions(self, tsys):
648634
ios_t, ios_y = ios.input_output_response(iosys_negate, T, U, X0)
649635
np.testing.assert_allclose(ios_y, lin_y,atol=0.002,rtol=0.)
650636

651-
@noscipy0
652637
def test_nonsquare_bdalg(self, tsys):
653638
# Set up parameters for simulation
654639
T = tsys.T
@@ -699,7 +684,6 @@ def test_nonsquare_bdalg(self, tsys):
699684
with pytest.raises(ValueError):
700685
ct.series(*args)
701686

702-
@noscipy0
703687
def test_discrete(self, tsys):
704688
"""Test discrete time functionality"""
705689
# Create some linear and nonlinear systems to play with
@@ -868,7 +852,6 @@ def test_find_eqpts(self, tsys):
868852
assert xeq is None
869853
assert ueq is None
870854

871-
@noscipy0
872855
def test_params(self, tsys):
873856
# Start with the default set of parameters
874857
ios_secord_default = ios.NonlinearIOSystem(

control/tests/timeresp_test.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
"""timeresp_test.py - test time response functions"""
22

33
from copy import copy
4-
from distutils.version import StrictVersion
54

65
import numpy as np
76
import pytest
@@ -521,8 +520,6 @@ def test_impulse_response_mimo(self, tsystem):
521520
_t, yy = impulse_response(sys, T=t, input=0)
522521
np.testing.assert_array_almost_equal(yy[:,0,:], yref_notrim, decimal=4)
523522

524-
@pytest.mark.skipif(StrictVersion(sp.__version__) < "1.3",
525-
reason="requires SciPy 1.3 or greater")
526523
@pytest.mark.parametrize("tsystem", ["siso_tf1"], indirect=True)
527524
def test_discrete_time_impulse(self, tsystem):
528525
# discrete time impulse sampled version should match cont time
@@ -998,9 +995,6 @@ def test_time_series_data_convention_2D(self, tsystem):
998995
[6, 2, 2, False, (2, 2, 8), (2, 8)],
999996
])
1000997
def test_squeeze(self, fcn, nstate, nout, ninp, squeeze, shape1, shape2):
1001-
# Figure out if we have SciPy 1+
1002-
scipy0 = StrictVersion(sp.__version__) < '1.0'
1003-
1004998
# Define the system
1005999
if fcn == ct.tf and (nout > 1 or ninp > 1) and not slycot_check():
10061000
pytest.skip("Conversion of MIMO systems to transfer functions "
@@ -1077,7 +1071,7 @@ def test_squeeze(self, fcn, nstate, nout, ninp, squeeze, shape1, shape2):
10771071
assert yvec.shape == (8, )
10781072

10791073
# For InputOutputSystems, also test input/output response
1080-
if isinstance(sys, ct.InputOutputSystem) and not scipy0:
1074+
if isinstance(sys, ct.InputOutputSystem):
10811075
_, yvec = ct.input_output_response(sys, tvec, uvec, squeeze=squeeze)
10821076
assert yvec.shape == shape2
10831077

@@ -1108,7 +1102,7 @@ def test_squeeze(self, fcn, nstate, nout, ninp, squeeze, shape1, shape2):
11081102
assert yvec.shape == (sys.noutputs, 8)
11091103

11101104
# For InputOutputSystems, also test input_output_response
1111-
if isinstance(sys, ct.InputOutputSystem) and not scipy0:
1105+
if isinstance(sys, ct.InputOutputSystem):
11121106
_, yvec = ct.input_output_response(sys, tvec, uvec)
11131107
if squeeze is not True or sys.noutputs > 1:
11141108
assert yvec.shape == (sys.noutputs, 8)

control/tests/xferfcn_test.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from control import isctime, isdtime, sample_system, defaults
1313
from control.statesp import _convert_to_statespace
1414
from control.xferfcn import _convert_to_transfer_function
15-
from control.tests.conftest import slycotonly, nopython2, matrixfilter
15+
from control.tests.conftest import slycotonly, matrixfilter
1616

1717

1818
class TestXferFcn:
@@ -448,7 +448,6 @@ def test_call_siso(self, dt, omega, resp):
448448
np.testing.assert_allclose(sys.evalfr(omega), resp, atol=1e-3)
449449

450450

451-
@nopython2
452451
def test_call_dtime(self):
453452
sys = TransferFunction([1., 3., 5], [1., 6., 2., -1], 0.1)
454453
np.testing.assert_array_almost_equal(sys(1j), -0.5 - 0.5j)
@@ -741,8 +740,7 @@ def test_indexing(self):
741740
"matarrayin",
742741
[pytest.param(np.array,
743742
id="arrayin",
744-
marks=[nopython2,
745-
pytest.mark.skip(".__matmul__ not implemented")]),
743+
marks=[pytest.mark.skip(".__matmul__ not implemented")]),
746744
pytest.param(np.matrix,
747745
id="matrixin",
748746
marks=matrixfilter)],

doc/intro.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ Installation
3636
============
3737

3838
The `python-control` package can be installed using pip, conda or the
39-
standard distutils/setuptools mechanisms. The package requires `numpy`_ and
39+
standard setuptools mechanisms. The package requires `numpy`_ and
4040
`scipy`_, and the plotting routines require `matplotlib
4141
<https://matplotlib.org>`_. In addition, some routines require the `slycot
4242
<https://github.com/python-control/Slycot>`_ library in order to implement

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
packages=find_packages(exclude=['benchmarks']),
4343
classifiers=[f for f in CLASSIFIERS.split('\n') if f],
4444
install_requires=['numpy',
45-
'scipy',
45+
'scipy>=1.3',
4646
'matplotlib'],
4747
extras_require={
4848
'test': ['pytest', 'pytest-timeout'],

0 commit comments

Comments
 (0)