ros_comm icon indicating copy to clipboard operation
ros_comm copied to clipboard

[rostest] python w/ coverage and pybind11 module crashes

Open gleichdick opened this issue 3 years ago • 0 comments

For helping at ros-planning/moveit#2910, I wanted to enable coverage analysis for moveit_commander. I discovered one trivial bug (#2198) and this issue. moveit_commander uses boost::python wrappers for the C++ API. When using rostest.rosrun(..., sysargs=["--cov"]), the test fails with the following trace:

Traceback (most recent call last):
  File "/usr/lib/python3.8/tokenize.py", line 330, in find_cookie
    line_string = line.decode('utf-8')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa0 in position 40: invalid start byte

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/workspaces/ros/src/rostest_py_coverage_bug/test/test_example.py", line 14, in <module>
    rostest.rosrun(PKG, 'test_foo', TestPythonExample, sysargs=["--cov"])
  File "/opt/ros/noetic/lib/python3/dist-packages/rostest/__init__.py", line 153, in rosrun
    _stop_coverage([package])
  File "/opt/ros/noetic/lib/python3/dist-packages/rostest/__init__.py", line 232, in _stop_coverage
    _cov.stop()
  File "/usr/local/lib/python3.8/dist-packages/coverage/control.py", line 927, in report
    return reporter.report(morfs, outfile=file)
  File "/usr/local/lib/python3.8/dist-packages/coverage/summary.py", line 43, in report
    for fr, analysis in get_analysis_to_report(self.coverage, morfs):
  File "/usr/local/lib/python3.8/dist-packages/coverage/report.py", line 72, in get_analysis_to_report
    analysis = coverage._analyze(fr)
  File "/usr/local/lib/python3.8/dist-packages/coverage/control.py", line 822, in _analyze
    return Analysis(data, self.config.precision, it, self._file_mapper)
  File "/usr/local/lib/python3.8/dist-packages/coverage/results.py", line 20, in __init__
    self.statements = self.file_reporter.lines()
  File "/usr/local/lib/python3.8/dist-packages/coverage/python.py", line 191, in lines
    return self.parser.statements
  File "/usr/local/lib/python3.8/dist-packages/coverage/python.py", line 182, in parser
    self._parser = PythonParser(
  File "/usr/local/lib/python3.8/dist-packages/coverage/parser.py", line 42, in __init__
    self.text = get_python_source(self.filename)
  File "/usr/local/lib/python3.8/dist-packages/coverage/python.py", line 66, in get_python_source
    source = source.decode(source_encoding(source), "replace")
  File "/usr/local/lib/python3.8/dist-packages/coverage/phystokens.py", line 195, in source_encoding
    return tokenize.detect_encoding(readline)[0]
  File "/usr/lib/python3.8/tokenize.py", line 371, in detect_encoding
    encoding = find_cookie(first)
  File "/usr/lib/python3.8/tokenize.py", line 335, in find_cookie
    raise SyntaxError(msg)
SyntaxError: invalid or missing encoding declaration

I discovered that coverage tries to load the ELF file of the C/C++ wrapper.

Please find a MWE here. (Please note that it needs pybind11 to be installed with pip, because the C extension is build from setup.py)

gleichdick avatar Oct 31 '21 16:10 gleichdick