From 82cd1caf1d1e97af5f3c8e66900e9e3b88853893 Mon Sep 17 00:00:00 2001 From: AlexWells Date: Tue, 14 Sep 2021 12:01:05 +0100 Subject: [PATCH 1/4] Only use the calculated length if NELM was NOT provided during record creation --- softioc/builder.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/softioc/builder.py b/softioc/builder.py index 8c6272e1..ec4497f6 100644 --- a/softioc/builder.py +++ b/softioc/builder.py @@ -166,7 +166,10 @@ def _waveform(value, fields): 'Can\'t specify FTVL and datatype together' FTVL = NumpyCharCodeToFtvl[numpy.dtype(datatype).char] - fields['NELM'] = length + # If NELM has been explicitly set use that, otherwise use computed length + if 'NELM' not in fields: + fields['NELM'] = length + fields.setdefault('FTVL', FTVL) From 9c6d7f3299744260feb2b36437218cb2c2b637d4 Mon Sep 17 00:00:00 2001 From: AlexWells Date: Wed, 15 Sep 2021 13:11:39 +0100 Subject: [PATCH 2/4] IMprove documentation for Waveform construction --- docs/reference/api.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/reference/api.rst b/docs/reference/api.rst index 7efab9e0..2fa0cdf9 100644 --- a/docs/reference/api.rst +++ b/docs/reference/api.rst @@ -298,9 +298,10 @@ All functions return a wrapped `ProcessDeviceSupportIn` or If ``value`` is specified or if an `initial_value` is specified (only one of these can be used) the value is used to initialise the waveform and to - determine its field type and length. If no initial value is specified then - the keyword argument ``length`` must be used to specify the length of the - waveform. + determine its field type and length (the inferred values may be overridden using + keywords ``datatype`` and ``NELM`` respectively). If no initial value is specified + then the keyword argument ``length`` (or ``NELM``) must be used to specify the + length of the waveform. The field type can be explicitly specified either by setting the ``datatype`` keyword to a Python type name, or by setting ``FTVL`` to the appropriate EPICS From 612840586a8045fe4ff404736d8560e7aebf67d9 Mon Sep 17 00:00:00 2001 From: AlexWells Date: Wed, 15 Sep 2021 13:12:06 +0100 Subject: [PATCH 3/4] Add check to ensure length is valid --- softioc/builder.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/softioc/builder.py b/softioc/builder.py index ec4497f6..2a3f6504 100644 --- a/softioc/builder.py +++ b/softioc/builder.py @@ -169,7 +169,9 @@ def _waveform(value, fields): # If NELM has been explicitly set use that, otherwise use computed length if 'NELM' not in fields: fields['NELM'] = length - + elif fields['NELM'] < length: + raise ValueError("NELM value shorter than value length") + fields.setdefault('FTVL', FTVL) From 146f350da40f2cb7c19c13fc226e5caf0b09e4fa Mon Sep 17 00:00:00 2001 From: AlexWells Date: Wed, 15 Sep 2021 13:13:11 +0100 Subject: [PATCH 4/4] Add test and minimal config to run tests inside VSCode There could certainly be a lot more tests written - awaiting discussion in PR to see how many more should be written. --- .vscode/settings.json | 5 +++++ tests/test_records.py | 12 +++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..7688f821 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "python.testing.pytestArgs": [], + "python.testing.unittestEnabled": false, + "python.testing.pytestEnabled": true +} \ No newline at end of file diff --git a/tests/test_records.py b/tests/test_records.py index 756a44ec..caee0199 100644 --- a/tests/test_records.py +++ b/tests/test_records.py @@ -4,7 +4,7 @@ from softioc import builder import sim_records - +import numpy def test_records(tmp_path): path = str(tmp_path / "records.db") @@ -13,8 +13,18 @@ def test_records(tmp_path): assert open(path).readlines()[5:] == open(expected).readlines() def test_enum_length_restriction(): + """Test that supplying too many labels (more than maximum of 16) raises expected + exception""" with pytest.raises(AssertionError): builder.mbbIn( "ManyLabels", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen") + + +def test__waveform_fields_nelm_used(): + """Test that the waveform construction returns the expected fields - i.e. NELM + is the same as the input value. Test for issue #37""" + fields = {"initial_value": numpy.array([1, 2, 3]), "NELM": 999} + builder._waveform(None, fields) + assert fields["NELM"] == 999