`callbacks.OutputToFile` always silently fails
- Dominant language
- Python
- Stars
- 722
- Forks
- 237
- Avg merge
- 11h 31m
- Merged PRs (30d)
- 4
Description
When `callbacks.OutputToFile` is used as a callback, the test passes with no warning, but the output file is not written to.
We can learn more by looking at the log_records object which does log the error: `TypeError: a bytes-like object is required, not 'int'`.
Example:
```python
import openhtf
from openhtf.output import callbacks
import logging
logger = logging.getLogger(__name__)
line_break = "\n"
test = openhtf.Test()
test.add_output_callbacks(
callbacks.OutputToFile("./test.pickle"),
lambda tr: logger.warning(f"{ line_break.join(list(map(lambda lr: lr.message,tr.log_records)))}")
)
test.execute()
```
Output:
```
> python main.py
Tearing down all plugs.
Finishing test execution normally with outcome PASS.
Thread finished: TestExecutorThread
DUT ID is still not set; using default.
Test completed for openhtf_test, outputting now.
Output callback raised:
Traceback (most recent call last):
File "/Users//Projects/python-tmp/.venv/lib/python3.13/site-packages/openhtf/core/test_descriptor.py", line 355, in execute
output_cb(final_state.test_record)
~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users//Projects/python-tmp/.venv/lib/python3.13/site-packages/openhtf/output/callbacks/__init__.py", line 138, in __call__
outfile.write(chunk.encode() if isinstance(chunk, str) else chunk)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users//Projects/python-tmp/.venv/lib/python3.13/site-packages/openhtf/output/callbacks/__init__.py", line 48, in write
return self.temp.write(write_data)
~~~~~~~~~~~~~~~^^^^^^^^^^^^
File "/opt/homebrew/Cellar/python@3.13/3.13.4/Frameworks/Python.framework/Versions/3.13/lib/python3.13/tempfile.py", line 499, in func_wrapper
return func(*args, **kwargs)
TypeError: a bytes-like object is required, not 'int'
Continuing anyway...
======================= test: openhtf_test outcome: PASS ======================
```
This is caused by the following code in `openhtf/output/callbacks/__init__.py`:
```
def __call__(self, test_rec: test_record.TestRecord) -> None:
with self.open_output_file(test_rec) as outfile:
serialized_record = self.serialize_test_record(test_rec)
if isinstance(serialized_record, str):
outfile.write(serialized_record.encode())
elif isinstance(serialized_record, Iterable):
for chunk in serialized_record:
outfile.write(chunk.encode() if isinstance(chunk, str) else chunk)
else:
raise TypeError('Expected string or iterable but got {}.'.format(
type(serialized_record)))
```
`serialize_record` is a `bytes` (so an `Iterables`), but this implies `chunk` is an `int`, whereas `write` expects a `bytes`
Here is one possible fix:
```diff
def __call__(self, test_rec: test_record.TestRecord) -> None:
with self.open_output_file(test_rec) as outfile:
serialized_record = self.serialize_test_record(test_rec)
if isinstance(serialized_record, str):
outfile.write(serialized_record.encode())
+ elif isinstance(serialized_record, bytes):
+ outfile.write(serialized_record)
elif isinstance(serialized_record, Iterable):
for chunk in serialized_record:
outfile.write(chunk.encode() if isinstance(chunk, str) else chunk)
else:
raise TypeError('Expected string or iterable but got {}.'.format(
type(serialized_record)))
```
Which seems to work
Contributor guide
Assessment
This issue has not been assessed yet.