From fd3b2dc7251e13f7448419f328d29c245183f063 Mon Sep 17 00:00:00 2001 From: Allison Chilton Date: Sat, 10 Apr 2021 11:58:44 -0600 Subject: [PATCH] Add standard error to exception message The rationale is that when castxml has an error it raises a RuntimeError to the user with the message. However, the message only contains the stdout from castxml - this makes the RuntimeError contain no information about what actually went wrong. This change allows the user to add error handling to their applications based on what went wrong with castxml (such as changing their include directories, etc) --- pygccxml/parser/source_reader.py | 8 ++++++-- unittests/source_reader_tester.py | 12 ++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/pygccxml/parser/source_reader.py b/pygccxml/parser/source_reader.py index d864554b..6a2e0b11 100644 --- a/pygccxml/parser/source_reader.py +++ b/pygccxml/parser/source_reader.py @@ -235,7 +235,8 @@ def create_xml_file(self, source_file, destination=None): process = subprocess.Popen( args=command_line, shell=True, - stdout=subprocess.PIPE) + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) try: results = [] @@ -246,9 +247,12 @@ def create_xml_file(self, source_file, destination=None): for line in process.stdout.readlines(): if line.strip(): results.append(line.rstrip()) + for line in process.stderr.readlines(): + if line.strip(): + results.append(line.rstrip()) exit_status = process.returncode - msg = os.linesep.join([str(s) for s in results]) + msg = os.linesep.join([str(s.decode()) for s in results]) if self.__config.ignore_gccxml_output: if not os.path.isfile(xml_file): raise RuntimeError( diff --git a/unittests/source_reader_tester.py b/unittests/source_reader_tester.py index ce286451..4841eafb 100644 --- a/unittests/source_reader_tester.py +++ b/unittests/source_reader_tester.py @@ -4,6 +4,7 @@ # See http://www.boost.org/LICENSE_1_0.txt import unittest +import os from . import parser_test_case @@ -31,6 +32,17 @@ def test_compound_argument_type(self): self.assertTrue(do_smth, "unable to find do_smth") do_smth.function_type() + def test_stderr_present_and_readable(self): + with open(os.path.join('unittests', 'data', self.header), 'r') as f: + source_str = f.read() + + err_str = "add some stuff that should not compile" + source_str += err_str + with self.assertRaises(RuntimeError) as e_context: + decls = parser.parse_string(source_str, self.config) + + self.assertIn(err_str, e_context.exception.args[0]) + def create_suite(): suite = unittest.TestSuite()