Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Lint tests #1127

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 24 commits into from
Feb 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
d5156e5
Lint: remove unused variables, or prefix with `_`
roryyorke Feb 9, 2025
2a18331
Remove unused imports
roryyorke Feb 9, 2025
1bc0119
Remove imports needed for `eval`
roryyorke Feb 16, 2025
df756eb
Fix incorrect variable names in f-strings
roryyorke Feb 15, 2025
48d6195
Apply ruff checks to control/tests/
roryyorke Feb 16, 2025
20f4b76
Remove unused variable fail_if_missing in test_parameter_docs
roryyorke Feb 16, 2025
3729d89
Remove unused obj and objname in test_iosys_attribute_lists
roryyorke Feb 16, 2025
36d5e8a
Remove unused variable docstring in test_iosys_container_classes
roryyorke Feb 16, 2025
7fe9d4e
Import numpy for symbol np.array
roryyorke Feb 16, 2025
ba33c21
Remove ineffective testFeedback2 in frd_test.py
roryyorke Feb 16, 2025
2156adf
Add assertion in testUnwrap in matlab_test
roryyorke Feb 16, 2025
69afb82
Remove unused steady-state output variable
roryyorke Feb 16, 2025
4e0b9c1
Mark unused test function with noqa
roryyorke Feb 16, 2025
3654163
Merge remote-tracking branch 'upstream/main' into lint-tests
roryyorke Feb 16, 2025
2d5738a
Fix bugs and lint errors in test_timeresp_aliases
roryyorke Feb 16, 2025
fb0519c
Correct use of slycotonly in statesp_test.py
roryyorke Feb 16, 2025
c6d26f1
Remove unused ss_{siso,mimo} variables
roryyorke Feb 16, 2025
22db2bf
Don't use keyword args for eval
roryyorke Feb 16, 2025
5ff3c0c
Handle deprecation warnings from conda setup in Github actions
roryyorke Feb 16, 2025
51eb00a
Remove redundant kwarg test entries
roryyorke Feb 16, 2025
e29ba64
Add assertion to check result of markov call
roryyorke Feb 16, 2025
ff4d7b6
Remove unused variables in test_optimal_doc
roryyorke Feb 16, 2025
870fa19
Merge remote-tracking branch 'upstream/main' into lint-tests
roryyorke Feb 16, 2025
c907a4f
Revert "Handle deprecation warnings from conda setup in Github actions"
roryyorke Feb 16, 2025
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
10 changes: 5 additions & 5 deletions control/tests/bdalg_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,19 +347,19 @@ def test_bdalg_udpate_names_errors():
sys2 = ctrl.rss(2, 1, 1)

with pytest.raises(ValueError, match="number of inputs does not match"):
sys = ctrl.series(sys1, sys2, inputs=2)
ctrl.series(sys1, sys2, inputs=2)

with pytest.raises(ValueError, match="number of outputs does not match"):
sys = ctrl.series(sys1, sys2, outputs=2)
ctrl.series(sys1, sys2, outputs=2)

with pytest.raises(ValueError, match="number of states does not match"):
sys = ctrl.series(sys1, sys2, states=2)
ctrl.series(sys1, sys2, states=2)

with pytest.raises(ValueError, match="number of states does not match"):
sys = ctrl.series(ctrl.tf(sys1), ctrl.tf(sys2), states=2)
ctrl.series(ctrl.tf(sys1), ctrl.tf(sys2), states=2)

with pytest.raises(TypeError, match="unrecognized keywords"):
sys = ctrl.series(sys1, sys2, dt=1)
ctrl.series(sys1, sys2, dt=1)


class TestEnsureTf:
Expand Down
26 changes: 12 additions & 14 deletions control/tests/bspline_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,9 @@

import numpy as np
import pytest
import scipy as sp

import control as ct
import control.flatsys as fs
import control.optimal as opt

def test_bspline_basis():
Tf = 10
Expand Down Expand Up @@ -182,40 +180,40 @@ def test_kinematic_car_multivar():
def test_bspline_errors():
# Breakpoints must be a 1D array, in increasing order
with pytest.raises(NotImplementedError, match="not yet supported"):
basis = fs.BSplineFamily([[0, 1, 3], [0, 2, 3]], [3, 3])
fs.BSplineFamily([[0, 1, 3], [0, 2, 3]], [3, 3])

with pytest.raises(ValueError,
match="breakpoints must be convertable to a 1D array"):
basis = fs.BSplineFamily([[[0, 1], [0, 1]], [[0, 1], [0, 1]]], [3, 3])
fs.BSplineFamily([[[0, 1], [0, 1]], [[0, 1], [0, 1]]], [3, 3])

with pytest.raises(ValueError, match="must have at least 2 values"):
basis = fs.BSplineFamily([10], 2)
fs.BSplineFamily([10], 2)

with pytest.raises(ValueError, match="must be strictly increasing"):
basis = fs.BSplineFamily([1, 3, 2], 2)
fs.BSplineFamily([1, 3, 2], 2)

# Smoothness can't be more than dimension of splines
basis = fs.BSplineFamily([0, 1], 4, 3) # OK
fs.BSplineFamily([0, 1], 4, 3) # OK
with pytest.raises(ValueError, match="degree must be greater"):
basis = fs.BSplineFamily([0, 1], 4, 4) # not OK
fs.BSplineFamily([0, 1], 4, 4) # not OK

# nvars must be an integer
with pytest.raises(TypeError, match="vars must be an integer"):
basis = fs.BSplineFamily([0, 1], 4, 3, vars=['x1', 'x2'])
fs.BSplineFamily([0, 1], 4, 3, vars=['x1', 'x2'])

# degree, smoothness must match nvars
with pytest.raises(ValueError, match="length of 'degree' does not match"):
basis = fs.BSplineFamily([0, 1], [4, 4, 4], 3, vars=2)
fs.BSplineFamily([0, 1], [4, 4, 4], 3, vars=2)

# degree, smoothness must be list of ints
basis = fs.BSplineFamily([0, 1], [4, 4], 3, vars=2) # OK
fs.BSplineFamily([0, 1], [4, 4], 3, vars=2) # OK
with pytest.raises(ValueError, match="could not parse 'degree'"):
basis = fs.BSplineFamily([0, 1], [4, '4'], 3, vars=2)
fs.BSplineFamily([0, 1], [4, '4'], 3, vars=2)

# degree must be strictly positive
with pytest.raises(ValueError, match="'degree'; must be at least 1"):
basis = fs.BSplineFamily([0, 1], 0, 1)
fs.BSplineFamily([0, 1], 0, 1)

# smoothness must be non-negative
with pytest.raises(ValueError, match="'smoothness'; must be at least 0"):
basis = fs.BSplineFamily([0, 1], 2, -1)
fs.BSplineFamily([0, 1], 2, -1)
5 changes: 1 addition & 4 deletions control/tests/config_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,11 +339,8 @@ def test_system_indexing(self):
{'dt': 0.1}
])
def test_repr_format(self, kwargs):
from ..statesp import StateSpace
from numpy import array

sys = ct.ss([[1]], [[1]], [[1]], [[0]], **kwargs)
new = eval(repr(sys))
new = eval(repr(sys), None, {'StateSpace':ct.StateSpace, 'array':np.array})
for attr in ['A', 'B', 'C', 'D']:
assert getattr(new, attr) == getattr(sys, attr)
for prop in ['input_labels', 'output_labels', 'state_labels']:
Expand Down
3 changes: 0 additions & 3 deletions control/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
"""conftest.py - pytest local plugins, fixtures, marks and functions."""

import os
from contextlib import contextmanager

import matplotlib as mpl
import numpy as np
import pytest
Expand Down
36 changes: 3 additions & 33 deletions control/tests/ctrlplot_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ def setup_plot_arguments(resp_fcn, plot_fcn, compute_time_response=True):
case ct.gangof4_response, _:
args1 = (sys1, sys1c)
args2 = (sys2, sys1c)
default_labels = ["P=sys[1]", "P=sys[2]"]

case ct.frequency_response, ct.nichols_plot:
args1 = (sys1, None) # to allow *fmt in linestyle test
Expand Down Expand Up @@ -239,10 +238,10 @@ def test_plot_ax_processing(resp_fcn, plot_fcn):
# Call the plotting function, passing the axes
if resp_fcn is not None:
resp = resp_fcn(*args, **kwargs, **resp_kwargs)
cplt4 = resp.plot(**kwargs, **meth_kwargs, ax=ax)
resp.plot(**kwargs, **meth_kwargs, ax=ax)
else:
# No response function available; just plot the data
cplt4 = plot_fcn(*args, **kwargs, **plot_kwargs, ax=ax)
plot_fcn(*args, **kwargs, **plot_kwargs, ax=ax)

# Check to make sure original settings did not change
assert fig._suptitle.get_text() == title
Expand Down Expand Up @@ -331,19 +330,9 @@ def test_plot_label_processing(resp_fcn, plot_fcn):
@pytest.mark.parametrize("resp_fcn, plot_fcn", resp_plot_fcns)
@pytest.mark.usefixtures('mplcleanup')
def test_plot_linestyle_processing(resp_fcn, plot_fcn):
# Create some systems to use
sys1 = ct.rss(2, 1, 1, strictly_proper=True, name="sys[1]")
sys1c = ct.rss(4, 1, 1, strictly_proper=True, name="sys[1]_C")
sys2 = ct.rss(4, 1, 1, strictly_proper=True, name="sys[2]")

# Set up arguments
args1, args2, _, kwargs, meth_kwargs, plot_kwargs, resp_kwargs = \
setup_plot_arguments(resp_fcn, plot_fcn)
default_labels = ["sys[1]", "sys[2]"]
expected_labels = ["sys1_", "sys2_"]
match resp_fcn, plot_fcn:
case ct.gangof4_response, _:
default_labels = ["P=sys[1]", "P=sys[2]"]

# Set line color
cplt1 = plot_fcn(*args1, **kwargs, **plot_kwargs, color='r')
Expand Down Expand Up @@ -491,16 +480,10 @@ def test_mimo_plot_legend_processing(resp_fcn, plot_fcn):
@pytest.mark.parametrize("resp_fcn, plot_fcn", resp_plot_fcns)
@pytest.mark.usefixtures('mplcleanup')
def test_plot_title_processing(resp_fcn, plot_fcn):
# Create some systems to use
sys1 = ct.rss(2, 1, 1, strictly_proper=True, name="sys[1]")
sys1c = ct.rss(4, 1, 1, strictly_proper=True, name="sys[1]_C")
sys2 = ct.rss(2, 1, 1, strictly_proper=True, name="sys[2]")

# Set up arguments
args1, args2, argsc, kwargs, meth_kwargs, plot_kwargs, resp_kwargs = \
setup_plot_arguments(resp_fcn, plot_fcn)
default_title = "sys[1], sys[2]"
expected_title = "sys1_, sys2_"
match resp_fcn, plot_fcn:
case ct.gangof4_response, _:
default_title = "P=sys[1], C=sys[1]_C, P=sys[2], C=sys[1]_C"
Expand Down Expand Up @@ -536,7 +519,7 @@ def test_plot_title_processing(resp_fcn, plot_fcn):
case ct.input_output_response, _:
title_prefix = "Input/output response for "
case _:
raise RuntimeError(f"didn't recognize {resp_fnc}, {plot_fnc}")
raise RuntimeError(f"didn't recognize {resp_fcn}, {plot_fcn}")

# Generate the first plot, with default title
cplt1 = plot_fcn(*args1, **kwargs, **plot_kwargs)
Expand Down Expand Up @@ -587,11 +570,9 @@ def test_plot_title_processing(resp_fcn, plot_fcn):
@pytest.mark.usefixtures('mplcleanup')
def test_tickmark_label_processing(plot_fcn):
# Generate the response that we will use for plotting
top_row, bot_row = 0, -1
match plot_fcn:
case ct.bode_plot:
resp = ct.frequency_response(ct.rss(4, 2, 2))
top_row = 1
case ct.time_response_plot:
resp = ct.step_response(ct.rss(4, 2, 2))
case ct.gangof4_plot:
Expand Down Expand Up @@ -625,20 +606,9 @@ def test_tickmark_label_processing(plot_fcn):
@pytest.mark.parametrize("resp_fcn, plot_fcn", resp_plot_fcns)
@pytest.mark.usefixtures('mplcleanup', 'editsdefaults')
def test_rcParams(resp_fcn, plot_fcn):
# Create some systems to use
sys1 = ct.rss(2, 1, 1, strictly_proper=True, name="sys[1]")
sys1c = ct.rss(4, 1, 1, strictly_proper=True, name="sys[1]_C")
sys2 = ct.rss(2, 1, 1, strictly_proper=True, name="sys[2]")

# Set up arguments
args1, args2, argsc, kwargs, meth_kwargs, plot_kwargs, resp_kwargs = \
setup_plot_arguments(resp_fcn, plot_fcn)
default_title = "sys[1], sys[2]"
expected_title = "sys1_, sys2_"
match resp_fcn, plot_fcn:
case ct.gangof4_response, _:
default_title = "P=sys[1], C=sys[1]_C, P=sys[2], C=sys[1]_C"

# Create new set of rcParams
my_rcParams = {}
for key in ct.ctrlplot.rcParams:
Expand Down
6 changes: 3 additions & 3 deletions control/tests/descfcn_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,12 +205,12 @@ def test_describing_function_exceptions():
assert saturation(3) == 2

# Turn off the bias check
bias = ct.describing_function(saturation, 0, zero_check=False)
ct.describing_function(saturation, 0, zero_check=False)

# Function should evaluate to zero at zero amplitude
f = lambda x: x + 0.5
with pytest.raises(ValueError, match="must evaluate to zero"):
bias = ct.describing_function(f, 0, zero_check=True)
ct.describing_function(f, 0, zero_check=True)

# Evaluate at a negative amplitude
with pytest.raises(ValueError, match="cannot evaluate"):
Expand All @@ -236,4 +236,4 @@ def test_describing_function_exceptions():
# Describing function plot for non-describing function object
resp = ct.frequency_response(H_simple)
with pytest.raises(TypeError, match="data must be DescribingFunction"):
cplt = ct.describing_function_plot(resp)
ct.describing_function_plot(resp)
Loading
Loading