google / google/openhtf

`callbacks.OutputToFile` always silently fails

Open
#1,242 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.