Skip to content

Commit

Permalink
Stop extending exception trace upward if "backtrace=False" (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
Delgan committed Jan 20, 2019
1 parent 40646d1 commit 7154b5d
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 21 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
Unreleased
==========

- Modify behavior of sink option ``backtrace=False`` so it doesn't extend traceback upward automatically (`#30 <https://github.com/Delgan/loguru/issues/30>`_)
- Fix import error on some platforms using Python 3.5 with limited ``localtime()`` support (`#33 <https://github.com/Delgan/loguru/issues/33>`_)
- Fix incorrect time formatting of locale month using ``MMM`` and ``MMMM`` tokens (`#34 <https://github.com/Delgan/loguru/pull/34>`_, thanks `@nasyxx <https://github.com/nasyxx>`_)
- Fix race condition permitting to write on a stopped handler
Expand Down
6 changes: 3 additions & 3 deletions loguru/_logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,9 @@ def add(
Whether or not the logged message and its records should be first converted to a JSON
string before being sent to the sink.
backtrace : |bool|, optional
Whether or not the formatted exception should use stack trace to display local
variables values. This probably should be set to ``False`` in production to avoid
leaking sensitive data.
Whether or not the formatted exception should use stack trace to display local variables
values and be extended upward beyond the caught frame. This probably should be set to
``False`` in production to avoid leaking sensitive data.
enqueue : |bool|, optional
Whether or not the messages to be logged should first pass through a multiprocess-safe
queue before reaching the sink. This is useful while logging to a file through multiple
Expand Down
37 changes: 22 additions & 15 deletions loguru/_recattrs.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,19 @@ def __init__(self, exception, decorated):
self.value = value
self.traceback = traceback

if traceback:
self._extended_traceback = self._extend_traceback(traceback, decorated)
else:
self._extended_traceback = None
self._decorated = decorated
self._extended_traceback = None
self._cache = {}

def __reduce__(self):
exception = (self.type, self.value, None) # tracebacks are not pickable
args = (exception, None)
args = (exception, self._decorated)
return (ExceptionRecattr, args)

def _extend_traceback(self, tb, decorated):
if tb is None:
return None

frame = tb.tb_frame

if decorated:
Expand Down Expand Up @@ -142,17 +144,22 @@ def replace(match):
return re.sub(regex, replace, error, re.MULTILINE)

def format_exception(self, backtrace, colored, encoding):
type_, value, ex_traceback = self.type, self.value, self._extended_traceback
key = (backtrace, colored, encoding)

if key in self._cache:
return self._cache[key]

type_, value, traceback_ = self.type, self.value, self.traceback

if not backtrace:
error = traceback.format_exception(type_, value, ex_traceback)
elif colored:
formatter = ExceptionFormatter(colored=True, encoding=encoding)
error = formatter.format_exception(type_, value, ex_traceback)
else:
formatter = ExceptionFormatter(colored=False, encoding=encoding)
error = formatter.format_exception(type_, value, ex_traceback)
error = traceback.format_exception(type_, value, traceback_)
error = "".join(error)
return self._cache.setdefault(key, error)

error = "".join(error)
if self._extended_traceback is None:
self._extended_traceback = self._extend_traceback(traceback_, self._decorated)

return self._format_catch_point(error)
formatter = ExceptionFormatter(colored=colored, encoding=encoding)
error = formatter.format_exception(type_, value, self._extended_traceback)
error = self._format_catch_point("".join(error))
return self._cache.setdefault(key, error)
13 changes: 10 additions & 3 deletions tests/test_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,12 @@ def compare_outputs(with_loguru, without_loguru, caught_scope_index, caught_trac
def compare(compare_outputs, request):
catch_mode = request.param

add = 'logger.add(sys.stdout, backtrace=False, colorize=False, format="{message}")\n'
add = (
'import traceback; import loguru;'
'format_exception = lambda self, *args: traceback.format_exception(*args);'
'loguru._recattrs.ExceptionFormatter.format_exception = format_exception;'
'logger.add(sys.stdout, backtrace=True, colorize=False, format="{message}")\n'
)

def compare(template, caught_scope_index, caught_trace_index=0, *, disabled=[]):
template = textwrap.dedent(template)
Expand Down Expand Up @@ -350,7 +355,7 @@ def f(y):
@pytest.mark.parametrize("rec", [1, 2, 3])
@pytest.mark.parametrize("catch_mode", ["explicit", "decorator", "context_manager"])
def test_raising_recursion(writer, rec, catch_mode):
logger.add(writer, format="{message}", backtrace=False)
logger.add(writer, format="{message}", backtrace=True, colorize=False)

if catch_mode == "explicit":

Expand Down Expand Up @@ -383,6 +388,8 @@ def f(n):
lines = writer.read().splitlines()
assert sum(line.startswith("Traceback") for line in lines) == rec + 1
assert sum(line.startswith("> File") for line in lines) == rec + 1


caughts = [
(line, next_line) for line, next_line in zip(lines, lines[1:]) if line.startswith("> File")
]
Expand All @@ -401,7 +408,7 @@ def f(n):


def test_carret_not_masked(writer):
logger.add(writer, backtrace=False, colorize=False)
logger.add(writer, backtrace=True, colorize=False)

@logger.catch
def f(n):
Expand Down

0 comments on commit 7154b5d

Please sign in to comment.