From 7d30475f16814c503a3f3188de7bc85dd029d887 Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Fri, 22 Nov 2019 08:31:24 -0500 Subject: [PATCH] bt2: use format_bt_error and format_bt_error_cause to generate _Error and _ErrorCause string representations This makes it so that formatting bt2._Error as a string looks the same way as what is printed by the CLI. It also allows formatting of error causes individually. The __str__ methods generate string representations that do not include terminal color control characters. If we want, we could later add a "to_string" method that can optionally generate a string with terminal color control characters. Change-Id: I9e2c6db536a1bea46b07c5fe8bb13f702d8accce Signed-off-by: Simon Marchi Reviewed-on: https://review.lttng.org/c/babeltrace/+/2435 Tested-by: jenkins --- src/bindings/python/bt2/Makefile.am | 4 +- src/bindings/python/bt2/bt2/error.py | 11 ++-- src/bindings/python/bt2/bt2/native_bt_error.i | 9 +++ .../python/bt2/bt2/native_bt_error.i.h | 59 +++++++++++++++++++ src/bindings/python/bt2/setup.py.in | 1 + tests/bindings/python/bt2/test_error.py | 2 +- 6 files changed, 77 insertions(+), 9 deletions(-) create mode 100644 src/bindings/python/bt2/bt2/native_bt_error.i.h diff --git a/src/bindings/python/bt2/Makefile.am b/src/bindings/python/bt2/Makefile.am index cc0ded09..ccd56bbb 100644 --- a/src/bindings/python/bt2/Makefile.am +++ b/src/bindings/python/bt2/Makefile.am @@ -17,6 +17,7 @@ SWIG_INTERFACE_FILES = \ bt2/native_bt_component_class.i.h \ bt2/native_bt_connection.i \ bt2/native_bt_error.i \ + bt2/native_bt_error.i.h \ bt2/native_bt_event.i \ bt2/native_bt_event_class.i \ bt2/native_bt_field.i \ @@ -94,7 +95,8 @@ STATIC_LIBRARIES_DEPS = \ $(top_builddir)/src/autodisc/libbabeltrace2-autodisc.la \ $(top_builddir)/src/logging/libbabeltrace2-logging.la \ $(top_builddir)/src/common/libbabeltrace2-common.la \ - $(top_builddir)/src/py-common/libbabeltrace2-py-common.la + $(top_builddir)/src/py-common/libbabeltrace2-py-common.la \ + $(top_builddir)/src/string-format/libbabeltrace2-string-format.la GENERATED_BINDINGS_DEPS = \ bt2/native_bt.c \ diff --git a/src/bindings/python/bt2/bt2/error.py b/src/bindings/python/bt2/bt2/error.py index a50827a8..07d24714 100644 --- a/src/bindings/python/bt2/bt2/error.py +++ b/src/bindings/python/bt2/bt2/error.py @@ -26,11 +26,10 @@ class _ErrorCause: self._module_name = native_bt.error_cause_get_module_name(ptr) self._file_name = native_bt.error_cause_get_file_name(ptr) self._line_number = native_bt.error_cause_get_line_number(ptr) + self._str = native_bt.bt2_format_bt_error_cause(ptr) def __str__(self): - s = '[{}] ({}:{})\n'.format(self.module_name, self.file_name, self.line_number) - s += self.message - return s + return self._str @property def message(self): @@ -169,6 +168,7 @@ class _Error(Exception, abc.Sequence): assert self._ptr is not None self._msg = msg + self._str = msg + '\n' + native_bt.bt2_format_bt_error(self._ptr) # Read everything we might need from the error pointer, so we don't # depend on it. It's possible for the user to keep an Error object @@ -212,7 +212,4 @@ class _Error(Exception, abc.Sequence): return len(self._causes) def __str__(self): - s = self._msg + '\n' - for c in reversed(self): - s += str(c) + '\n' - return s + return self._str diff --git a/src/bindings/python/bt2/bt2/native_bt_error.i b/src/bindings/python/bt2/bt2/native_bt_error.i index e70ebe69..1ccf6c4a 100644 --- a/src/bindings/python/bt2/bt2/native_bt_error.i +++ b/src/bindings/python/bt2/bt2/native_bt_error.i @@ -29,3 +29,12 @@ %include %include +%{ +#include "native_bt_error.i.h" +%} + +static +PyObject *bt_bt2_format_bt_error_cause(const bt_error_cause *error_cause); + +static +PyObject *bt_bt2_format_bt_error(const bt_error *error); diff --git a/src/bindings/python/bt2/bt2/native_bt_error.i.h b/src/bindings/python/bt2/bt2/native_bt_error.i.h new file mode 100644 index 00000000..578ce5ee --- /dev/null +++ b/src/bindings/python/bt2/bt2/native_bt_error.i.h @@ -0,0 +1,59 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Efficios, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +static +PyObject *bt_bt2_format_bt_error_cause(const bt_error_cause *error_cause) +{ + gchar *error_cause_str; + PyObject *py_error_cause_str = NULL; + + error_cause_str = format_bt_error_cause(error_cause, 80, + bt_python_bindings_bt2_log_level, BT_COMMON_COLOR_WHEN_NEVER); + BT_ASSERT(error_cause_str); + + py_error_cause_str = PyString_FromString(error_cause_str); + + g_free(error_cause_str); + + return py_error_cause_str; +} + +static +PyObject *bt_bt2_format_bt_error(const bt_error *error) +{ + gchar *error_str; + PyObject *py_error_str = NULL; + + error_str = format_bt_error(error, 80, + bt_python_bindings_bt2_log_level, BT_COMMON_COLOR_WHEN_NEVER); + BT_ASSERT(error_str); + + py_error_str = PyString_FromString(error_str); + + g_free(error_str); + + return py_error_str; +} diff --git a/src/bindings/python/bt2/setup.py.in b/src/bindings/python/bt2/setup.py.in index 0a94d1f3..fcce57f1 100644 --- a/src/bindings/python/bt2/setup.py.in +++ b/src/bindings/python/bt2/setup.py.in @@ -45,6 +45,7 @@ def main(): '@top_builddir@/src/logging/.libs/libbabeltrace2-logging.a', '@top_builddir@/src/common/.libs/libbabeltrace2-common.a', '@top_builddir@/src/py-common/.libs/libbabeltrace2-py-common.a', + '@top_builddir@/src/string-format/.libs/libbabeltrace2-string-format.a', ], ) diff --git a/tests/bindings/python/bt2/test_error.py b/tests/bindings/python/bt2/test_error.py index 6ec5fd89..f11cb2c2 100644 --- a/tests/bindings/python/bt2/test_error.py +++ b/tests/bindings/python/bt2/test_error.py @@ -211,7 +211,7 @@ class ErrorTestCase(unittest.TestCase): # expected bits. exc = self._run_failing_graph(SourceWithFailingIter, SinkWithExceptionChaining) s = str(exc) - self.assertIn('[src (out): src.SourceWithFailingIter]', s) + self.assertIn("[src (out): 'source.SourceWithFailingIter']", s) self.assertIn('ValueError: oops', s) -- 2.34.1