From 51d2fa068a627a8c8d633b17f415932cb0af7f47 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) --- src/pygccxml/parser/source_reader.py | 8 ++++++-- unittests/source_reader_tester.py | 12 ++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/pygccxml/parser/source_reader.py b/src/pygccxml/parser/source_reader.py index d864554b..6a2e0b11 100644 --- a/src/pygccxml/parser/source_reader.py +++ b/src/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 fbb7c236..aef41c77 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()