8000 Merge pull request #619 from bnavigator/defaults-deprecation · python-control/python-control@9f27293 · GitHub
[go: up one dir, main page]

Skip to content
8000
.kglDHV{width:20px;height:20px;}/*!sc*/ .fTXDSd{width:60px;}/*!sc*/ .bpjOzT{width:62px;}/*!sc*/ .eXXeJz{width:60px;height:22px;}/*!sc*/ data-styled.g1[id="Box-sc-62in7e-0"]{content:"kglDHV,fTXDSd,bpjOzT,eXXeJz,"}/*!sc*/ .iIGVMW{font-weight:600;color:var(--fgColor-default,var(--color-fg-default,#1F2328));}/*!sc*/ .iIGVMW:hover{color:var(--fgColor-default,var(--color-fg-default,#1F2328));}/*!sc*/ data-styled.g27[id="Link__StyledLink-sc-1syctfj-0"]{content:"iIGVMW,"}/*!sc*/ .hlLCru{position:relative;overflow:hidden;-webkit-mask-image:radial-gradient(white,black);mask-image:radial-gradient(white,black);background-color:var(--bgColor-neutral-muted,var(--color-neutral-subtle,rgba(234,238,242,0.5)));border-radius:3px;display:block;height:1.2em;width:60px;}/*!sc*/ .hlLCru::after{-webkit-animation:crVFvv 1.5s infinite linear;animation:crVFvv 1.5s infinite linear;background:linear-gradient(90deg,transparent,var(--bgColor-neutral-muted,var(--color-neutral-subtle,rgba(234,238,242,0.5))),transparent);content:'';position:absolute;-webkit-transform:translateX(-100%);-ms-transform:translateX(-100%);transform:translateX(-100%);bottom:0;left:0;right:0;top:0;}/*!sc*/ .hvOysI{position:relative;overflow:hidden;-webkit-mask-image:radial-gradient(white,black);mask-image:radial-gradient(white,black);background-color:var(--bgColor-neutral-muted,var(--color-neutral-subtle,rgba(234,238,242,0.5)));border-radius:3px;display:block;height:1.2em;width:62px;}/*!sc*/ .hvOysI::after{-webkit-animation:crVFvv 1.5s infinite linear;animation:crVFvv 1.5s infinite linear;background:linear-gradient(90deg,transparent,var(--bgColor-neutral-muted,var(--color-neutral-subtle,rgba(234,238,242,0.5))),transparent);content:'';position:absolute;-webkit-transform:translateX(-100%);-ms-transform:translateX(-100%);transform:translateX(-100%);bottom:0;left:0;right:0;top:0;}/*!sc*/ .biZyBe{position:relative;overflow:hidden;-webkit-mask-image:radial-gradient(white,black);mask-image:radial-gradient(white,black);background-color:var(--bgColor-neutral-muted,var(--color-neutral-subtle,rgba(234,238,242,0.5)));border-radius:3px;display:block;height:1.2em;width:60px;height:22px;}/*!sc*/ .biZyBe::after{-webkit-animation:crVFvv 1.5s infinite linear;animation:crVFvv 1.5s infinite linear;background:linear-gradient(90deg,transparent,var(--bgColor-neutral-muted,var(--color-neutral-subtle,rgba(234,238,242,0.5))),transparent);content:'';position:absolute;-webkit-transform:translateX(-100%);-ms-transform:translateX(-100%);transform:translateX(-100%);bottom:0;left:0;right:0;top:0;}/*!sc*/ data-styled.g46[id="LoadingSkeleton-sc-f120ff6b-0"]{content:"hlLCru,hvOysI,biZyBe,"}/*!sc*/ @-webkit-keyframes crVFvv{0%{-webkit-transform:translateX(-100%);-ms-transform:translateX(-100%);transform:translateX(-100%);}50%{-webkit-transform:translateX(100%);-ms-transform:translateX(100%);transform:translateX(100%);}100%{-webkit-transform:translateX(100%);-ms-transform:translateX(100%);transform:translateX(100%);}}/*!sc*/ @keyframes crVFvv{0%{-webkit-transform:translateX(-100%);-ms-transform:translateX(-100%);transform:translateX(-100%);}50%{-webkit-transform:translateX(100%);-ms-transform:translateX(100%);transform:translateX(100%);}100%{-webkit-transform:translateX(100%);-ms-transform:translateX(100%);transform:translateX(100%);}}/*!sc*/ data-styled.g62[id="sc-keyframes-crVFvv"]{content:"crVFvv,"}/*!sc*/

Commit 9f27293

Browse files
authored
Merge pull request #619 from bnavigator/defaults-deprecation
add DefaultDict for deprecation handling
2 parents db174b7 + e0dab93 commit 9f27293

File tree

3 files changed

+90
-1
lines changed

3 files changed

+90
-1
lines changed

control/config.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
# files. For now, you can just choose between MATLAB and FBS default
88
# values + tweak a few other things.
99

10+
11+
import collections
1012
import warnings
1113

1214
__all__ = ['defaults', 'set_defaults', 'reset_defaults',
@@ -20,7 +22,43 @@
2022
'control.squeeze_time_response': None,
2123
'forced_response.return_x': False,
2224
}
23-
defaults = dict(_control_defaults)
25+
26+
27+
class DefaultDict(collections.UserDict):
28+
"""Map names for settings from older version to their renamed ones.
29+
30+
If a user wants to write to an old setting, issue a warning and write to
31+
the renamed setting instead. Accessing the old setting returns the value
32+
from the new name.
33+
"""
34+
35+
def __init__(self, *args, **kwargs):
36+
super().__init__(*args, **kwargs)
37+
38+
def __setitem__(self, key, value):
39+
super().__setitem__(self._check_deprecation(key), value)
40+
41+
def __missing__(self, key):
42+
# An old key should never have been set. If it is being accessed
43+
# through __getitem__, return the value from the new name.
44+
repl = self._check_deprecation(key)
45+
if self.__contains__(repl):
46+
return self[repl]
47+
else:
48+
raise KeyError(key)
49+
50+
def _check_deprecation(self, key):
51+
if self.__contains__(f"deprecated.{key}"):
52+
repl = self[f"deprecated.{key}"]
53+
warnings.warn(f"config.defaults['{key}'] has been renamed to "
54+
f"config.defaults['{repl}'].",
55+
FutureWarning, stacklevel=3)
56+
return repl
57+
else:
58+
return key
59+
60+
61+
defaults = DefaultDict(_control_defaults)
2462

2563

2664
def set_defaults(module, **keywords):

control/freqplot.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,16 @@
6868
'freqplot.Hz': False, # Plot frequency in Hertz
6969
'freqplot.grid': True, # Turn on grid for gain and phase
7070
'freqplot.wrap_phase': False, # Wrap the phase plot at a given value
71+
72+
# deprecations
73+
'deprecated.bode.dB': 'freqplot.dB',
74+
'deprecated.bode.deg': 'freqplot.deg',
75+
'deprecated.bode.Hz': 'freqplot.Hz',
76+
'deprecated.bode.grid': 'freqplot.grid',
77+
'deprecated.bode.wrap_phase': 'freqplot.wrap_phase',
7178
}
7279

80+
7381
#
7482
# Main plotting functions
7583
#

control/tests/config_test.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,49 @@ def test_get_param(self):
4949

5050
assert ct.config._get_param('config', 'test4', {'test4': 1}, None) == 1
5151

52+
def test_default_deprecation(self):
53+
ct.config.defaults['deprecated.config.oldkey'] = 'config.newkey'
54+
ct.config.defaults['deprecated.config.oldmiss'] = 'config.newmiss'
55+
56+
msgpattern = r'config\.oldkey.* has been renamed to .*config\.newkey'
57+
58+
ct.config.defaults['config.newkey'] = 1
59+
with pytest.warns(FutureWarning, match=msgpattern):
60+
assert ct.config.defaults['config.oldkey'] == 1
61+
with pytest.warns(FutureWarning, match=msgpattern):
62+
ct.config.defaults['config.oldkey'] = 2
63+
with pytest.warns(FutureWarning, match=msgpattern):
64+
assert ct.config.defaults['config.oldkey'] == 2
65+
assert ct.config.defaults['config.newkey'] == 2
66+
67+
ct.config.set_defaults('config', newkey=3)
68+
with pytest.warns(FutureWarning, match=msgpattern):
69+
assert ct.config._get_param('config', 'oldkey') == 3
70+
with pytest.warns(FutureWarning, match=msgpattern):
71+
ct.config.set_defaults('config', oldkey=4)
72+
with pytest.warns(FutureWarning, match=msgpattern):
73+
assert ct.config.defaults['config.oldkey'] == 4
74+
assert ct.config.defaults['config.newkey'] == 4
75+
76+
ct.config.defaults.update({'config.newkey': 5})
77+
with pytest.warns(FutureWarning, match=msgpattern):
78+
ct.config.defaults.update({'config.oldkey': 6})
79+
with pytest.warns(FutureWarning, match=msgpattern):
80+
assert ct.config.defaults.get('config.oldkey') == 6
81+
82+
with pytest.raises(KeyError):
83+
with pytest.warns(FutureWarning, match=msgpattern):
84+
ct.config.defaults['config.oldmiss']
85+
with pytest.raises(KeyError):
86+
ct.config.defaults['config.neverdefined']
87+
88+
# assert that reset defaults keeps the custom type
89+
ct.config.reset_defaults()
90+
with pytest.warns(FutureWarning,
91+
match='bode.* has been renamed to.*freqplot'):
92+
assert ct.config.defaults['bode.Hz'] \
93+
== ct.config.defaults['freqplot.Hz']
94+
5295
@mplcleanup
5396
def test_fbs_bode(self):
5497
ct.use_fbs_defaults()

0 commit comments

Comments
 (0)
0