Skip to content

Commit 289897e

Browse files
Improve string representation of RecordWrapper
The returned string is the full DeviceName:RecordName. Previously the string representation would be lost when builder.LoadDatabase() is called, as the __builder instance is removed and so __str__ returns None. The __device is not removed at any point, and so can always be safely used to fetch the full name.
1 parent 860f59c commit 289897e

File tree

3 files changed

+63
-2
lines changed

3 files changed

+63
-2
lines changed

CHANGELOG.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ Versioning <https://semver.org/spec/v2.0.0.html>`_.
1010
Unreleased_
1111
-----------
1212

13+
Changed:
14+
15+
- `Improve string representation of RecordWrapper instances <../../pull/130>`
16+
1317
4.3.0_ - 2023-04-04
1418
-------------------
1519

softioc/pythonSoftIoc.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,7 @@ def __call__(self, *specifiers):
8080
return self.__builder(*specifiers)
8181

8282
def __str__(self):
83-
return str(self.__builder)
84-
83+
return self.__device._name
8584

8685

8786
class PythonDevice(object):

tests/test_records.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,64 @@ def test_clear_records_too_late():
289289
pytest.fail("Process did not terminate")
290290

291291

292+
def str_ioc_test_func(device_name, conn):
293+
builder.SetDeviceName(device_name)
294+
295+
record_name = "MyAI"
296+
297+
full_name = device_name + ":" + record_name
298+
299+
ai = builder.aIn(record_name)
300+
301+
302+
log("CHILD: Created ai record: ", ai.__str__())
303+
304+
assert (
305+
ai.__str__() == full_name
306+
), f"Record name {ai.__str__()} before LoadDatabase did not match " \
307+
f"expected string {full_name}"
308+
309+
builder.LoadDatabase()
310+
311+
assert (
312+
ai.__str__() == full_name
313+
), f"Record name {ai.__str__()} after LoadDatabase did not match " \
314+
f"expected string {full_name}"
315+
316+
dispatcher = asyncio_dispatcher.AsyncioDispatcher()
317+
softioc.iocInit(dispatcher)
318+
319+
assert (
320+
ai.__str__() == full_name
321+
), f"Record name {ai.__str__()} after iocInit did not match expected " \
322+
f"string {full_name}"
323+
324+
conn.send("R") # "Ready"
325+
log("CHILD: Sent R over Connection to Parent")
326+
327+
328+
329+
def test_record_wrapper_str():
330+
"""Test that the __str__ method on the RecordWrapper behaves as expected,
331+
both before and after loading the record database"""
332+
333+
ctx = get_multiprocessing_context()
334+
parent_conn, child_conn = ctx.Pipe()
335+
336+
device_name = create_random_prefix()
337+
338+
ioc_process = ctx.Process(
339+
target=str_ioc_test_func,
340+
args=(device_name, child_conn),
341+
)
342+
343+
ioc_process.start()
344+
345+
346+
# Wait for message that IOC has started
347+
# If we never receive R it probably means an assert failed
348+
select_and_recv(parent_conn, "R")
349+
292350

293351
def validate_fixture_names(params):
294352
"""Provide nice names for the out_records fixture in TestValidate class"""

0 commit comments

Comments
 (0)