Skip to content

Commit

Permalink
Fix values wrongly displayed for keyword args in exceptions (Delgan#144)
Browse files Browse the repository at this point in the history
  • Loading branch information
Delgan committed Oct 26, 2019
1 parent 78b93b6 commit 8bc1384
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
- Fix incompatibility with ``multiprocessing`` on Windows by entirely refactoring the internal structure of the ``logger`` so it can be inherited by child processes along with added handlers (`#108 <https://github.com/Delgan/loguru/issues/108>`_).
- Fix an error using a ``filter`` function "by name" while receiving a log with ``record["name"]`` equals to ``None``.
- Fix ``AttributeError`` while using a file sink on some distributions (like Alpine Linux) missing the ``os.getxattr`` and ``os.setxattr`` functions (`#158 <https://github.com/Delgan/loguru/pull/158>`_, thanks `@joshgordon <https://github.com/joshgordon>`_).
- Fix values wrongly displayed for keyword arguments during exception formatting with ``diagnose=True`` (`#144 <https://github.com/Delgan/loguru/issues/144>`_).
- Add support for ``copy.deepcopy()`` of the ``logger`` allowing multiple independent loggers with separate set of handlers (`#72 <https://github.com/Delgan/loguru/issues/72>`_).
- Prevent hypothetical ``ImportError`` if a Python installation is missing the built-in ``distutils`` module (`#118 <https://github.com/Delgan/loguru/issues/118>`_).
- Add the possibility to convert ``datetime`` to UTC before formatting (in logs and filenames) by adding ``"!UTC"`` at the end of the time format specifier (`#128 <https://github.com/Delgan/loguru/issues/128>`_).
Expand Down
19 changes: 18 additions & 1 deletion loguru/_better_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,12 +253,20 @@ def get_info(frame, lineno):

def _get_relevant_values(self, source, frame):
value = None
pending = None
is_attribute = False
is_valid_value = False
is_assignment = True

for token in self._syntax_highlighter.tokenize(source):
type_, string, (_, col), *_ = token

if pending is not None:
# Keyword arguments are ignored
if type_ != tokenize.OP or string != "=" or is_assignment:
yield pending
pending = None

if type_ == tokenize.NAME and not keyword.iskeyword(string):
if not is_attribute:
for variables in (frame.f_locals, frame.f_globals):
Expand All @@ -268,7 +276,7 @@ def _get_relevant_values(self, source, frame):
continue
else:
is_valid_value = True
yield (col, self._format_value(value))
pending = (col, self._format_value(value))
break
elif is_valid_value:
try:
Expand All @@ -279,9 +287,18 @@ def _get_relevant_values(self, source, frame):
yield (col, self._format_value(value))
elif type_ == tokenize.OP and string == ".":
is_attribute = True
is_assignment = False
elif type_ == tokenize.OP and string == ";":
is_assignment = True
is_attribute = False
is_valid_value = False
else:
is_attribute = False
is_valid_value = False
is_assignment = False

if pending is not None:
yield pending

def _format_relevant_values(self, relevant_values, colorize):
for i in reversed(range(len(relevant_values))):
Expand Down
26 changes: 26 additions & 0 deletions tests/exceptions/output/diagnose/keyword_argument.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

Traceback (most recent call last):

File "tests/exceptions/source/diagnose/keyword_argument.py", line 15, in <module>
f(x=y)
│ └ 0
└ <function f at 0xDEADBEEF>

File "tests/exceptions/source/diagnose/keyword_argument.py", line 9, in f
return 1 / x
 └ 0

ZeroDivisionError: division by zero

Traceback (most recent call last):

File "tests/exceptions/source/diagnose/keyword_argument.py", line 20, in <module>
f(x=x)
│ └ 0
└ <function f at 0xDEADBEEF>

File "tests/exceptions/source/diagnose/keyword_argument.py", line 9, in f
return 1 / x
 └ 0

ZeroDivisionError: division by zero
45 changes: 45 additions & 0 deletions tests/exceptions/output/diagnose/parenthesis.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@

Traceback (most recent call last):

File "tests/exceptions/source/diagnose/parenthesis.py", line 45, in <module>
e()
└ <function e at 0xDEADBEEF>

File "tests/exceptions/source/diagnose/parenthesis.py", line 41, in e
) + d(()) + a
 │ └ 1
 └ <function d at 0xDEADBEEF>

File "tests/exceptions/source/diagnose/parenthesis.py", line 34, in d
; z = (x * y); y = (j or xyz.val * c() \
 │ │ │ │ │ │ │ └ <function c at 0xDEADBEEF>
 │ │ │ │ │ │ └ 123
 │ │ │ │ │ └ <__main__.XYZ object at 0xDEADBEEF>
 │ │ │ │ └ ()
 │ │ │ └ 5
 │ │ └ 5
 │ └ 2
 └ 10

File "tests/exceptions/source/diagnose/parenthesis.py", line 26, in c
x.val += 456 and b()
│ │ └ <function b at 0xDEADBEEF>
│ └ 123
└ <__main__.XYZ object at 0xDEADBEEF>

File "tests/exceptions/source/diagnose/parenthesis.py", line 20, in b
foo[("baz")] = bar() + (a(5, baz))
│ │ │ └ 0
│ │ └ <function a at 0xDEADBEEF>
│ └ <class '__main__.XYZ'>
└ {}

File "tests/exceptions/source/diagnose/parenthesis.py", line 15, in a
(a, b, x.val, ) = 12, 15 / c, 17
 │ │ │ │ └ 0
 │ │ │ └ 9
 │ │ └ <__main__.XYZ object at 0xDEADBEEF>
 │ └ 5
 └ <function a at 0xDEADBEEF>

ZeroDivisionError: division by zero
20 changes: 20 additions & 0 deletions tests/exceptions/source/diagnose/keyword_argument.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import sys
from loguru import logger

logger.remove()
logger.add(sys.stderr, format="", colorize=True, backtrace=False, diagnose=True)


def f(x):
return 1 / x


y = 0

with logger.catch():
f(x=y)

x = 0

with logger.catch():
f(x=x)
45 changes: 45 additions & 0 deletions tests/exceptions/source/diagnose/parenthesis.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import sys
from loguru import logger

logger.remove()
logger.add(sys.stderr, format="", colorize=True, backtrace=False, diagnose=True)


class XYZ:
pass


def a(b, c):
x = XYZ()
x.val = 9
(a, b, x.val, ) = 12, 15 / c, 17


def b():
foo, bar, baz = {}, XYZ, 0
foo[("baz")] = bar() + (a(5, baz))


def c():
x = XYZ()
x.val = 123
x.val += 456 and b()


def d(j):
x, y, z = 2, 5, 3
xyz = XYZ()
xyz.val = 123
i = 12 \
; z = (x * y); y = (j or xyz.val * c() \
+ 3)


def e():
a = 1
(5 \
) + d(()) + a


with logger.catch():
e()
2 changes: 2 additions & 0 deletions tests/test_catch_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,10 @@ def test_backtrace(filename):
"encoding",
"global_variable",
"indentation_error",
"keyword_argument",
"multilines_repr",
"no_error_message",
"parenthesis",
"source_multilines",
"source_strings",
"syntax_error",
Expand Down

0 comments on commit 8bc1384

Please sign in to comment.