Giter Club home page Giter Club logo

better-exceptions's Introduction

better-exceptions Travis

Pretty and more helpful exceptions in Python, automatically.

Example screenshot of exceptions

Usage

Install better_exceptions via pip:

pip install better_exceptions

And set the BETTER_EXCEPTIONS environment variable to any value:

export BETTER_EXCEPTIONS=1  # Linux / OSX
setx BETTER_EXCEPTIONS 1    # Windows

That's it!

Python REPL (Interactive Shell)

In order to use better_exceptions in the Python REPL, first install the package (as instructed above) and run:

$ python -m better_exceptions
Type "help", "copyright", "credits" or "license" for more information.
(BetterExceptionsConsole)
>>>

in order to drop into a better_exceptions-enabled Python interactive shell.

Advanced Usage

If you want to allow the entirety of values to be outputted instead of being truncated to a certain amount of characters:

import better_exceptions
better_exceptions.MAX_LENGTH = None

While using better_exceptions in production, do not forget to unset the BETTER_EXCEPTIONS variable to avoid leaking sensitive data in your logs.

Use with unittest

If you want to use better_exceptions to format unittest's exception output, you can use the monkey patch below:

import sys
import unittest
import better_exceptions

def patch(self, err, test):
    lines = better_exceptions.format_exception(*err)
    if sys.version_info[0] == 2:
        return u"".join(lines).encode("utf-8")
    return "".join(lines)

unittest.result.TestResult._exc_info_to_string = patch

Note that this uses an undocumented method override, so it is not guaranteed to work on all platforms or versions of Python.

Django Usage

In settings.py, add your new class to the MIDDLEWARE setting and update your logging configuration:

# ...

MIDDLEWARE = [
    # ...
    "better_exceptions.integrations.django.BetterExceptionsMiddleware",
]

# ...

from better_exceptions.integrations.django import skip_errors_filter

# if you don't want to override LOGGING because you want to change the default,
# you can vendor Django's default logging configuration and update it for
# better-exceptions. the default for Django 3.1.4 can be found here:
# https://github.com/django/django/blob/3.1.4/django/utils/log.py#L13-L63
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'filters': {
        'skip_errors': {
            '()': 'django.utils.log.CallbackFilter',
            'callback': skip_errors_filter,
        }
    },
    'handlers': {
        'console': {
            'level': 'INFO',
            # without the 'filters' key, Django will log errors twice:
            # one time from better-exceptions and one time from Django.
            # with the 'skip_errors' filter, we remove the repeat log
            # from Django, which is unformatted.
            'filters': ['skip_errors'],
            'class': 'logging.StreamHandler',
        }
    },
    'loggers': {
        'django': {
            'handlers': [
                'console',
            ],
        }
    }
}

example output:

image

Troubleshooting

If you do not see beautiful exceptions, first make sure that the environment variable does exist. You can try echo $BETTER_EXCEPTIONS (Linux / OSX) or echo %BETTER_EXCEPTIONS% (Windows). On Linux and OSX, the export command does not add the variable permanently, you will probably need to edit the ~/.profile file to make it persistent. On Windows, you need to open a new terminal after the setx command.

Check that there is no conflict with another library, and that the sys.excepthook function has been correctly replaced with the better_exceptions's one. Sometimes other components can set up their own exception handlers, such as the python3-apport Ubuntu package that you may need to uninstall.

Make sure that you have not inadvertently deleted the better_exceptions_hook.pth file that should be in the same place as the better_exceptions folder where all of your Python packages are installed. Otherwise, try re-installing better_exceptions.

You can also try to manually activate the hook by adding import better_exceptions; better_exceptions.hook() at the beginning of your script.

Finally, if you still can not get this module to work, open a new issue by describing your problem precisely and detailing your configuration (Python and better_exceptions versions, OS, code snippet, interpreter, etc.) so that we can reproduce the bug you are experiencing.

License

Copyright © 2017, Josh Junon. Licensed under the MIT license.

better-exceptions's People

Contributors

blueyed avatar coldnight avatar dansan avatar delgan avatar elliotgao2 avatar gliptak avatar ickedude avatar inizio avatar kianmeng avatar ocavue avatar paradoxxxzero avatar pylipp avatar qix- avatar shineydev avatar sumanthratna avatar tao12345666333 avatar unformatt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

better-exceptions's Issues

Unicode error when stderr is redirected in Python 2.7

Ran into this error:

$ ./tt.py 2>&1 | cat
Error in sys.excepthook:
Traceback (most recent call last):
  File "/home/openstack/better_exceptions.py", line 194, in excepthook
    print(full_trace, file=sys.stderr)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2502' in position 99: ordinal not in range(128)

Original exception was:
Traceback (most recent call last):
  File "./tt.py", line 83, in <module>
    sys.exit(main())
  File "./tt.py", line 40, in main
    raise ValueError("testing")
ValueError: testing

Drop support for Python 2.7?

Hello @Qix-.

So, to explain you the problem I'm facing: I have implemented a few fixes for some edge cases, but I'm not sure how to handle it properly for Python 2.7.

These fixes implies working with strings formatting and encoding, which is a pain to deal with in Python 2.

Considering that official Python 2 support is ending in less than one year, what are your thoughts on tagging better_exceptions v0.2.2 as the "final" stable release for Python 2, and making v0.3.0 Python 3 only?

If you wish to maintain compatibility for Python 2.7, I think I could manage to make it work for all versions. But I'm afraid that it will clutter the codebase while introducing prone to errors string manipulations. This is why I prefer to ask you first: does it worth it?

Manually generated exceptions in Python 3 on Linux don't have full frames

Using Python 3 on Linux (Ubuntu) it the try...except block to generate a traceback manually is being triggered, which fails to get the proper stack information when testing the raw interactive mode handling.

test/output/python3-xterm-256color-ascii-nocolor.out
    python3 test/test.py
    python3 test/test_color.py
    ./test/test_interactive.sh
    ./test/test_interactive_raw.sh
    ./test/test_string.sh
63,64d62
<   File "<console>", line 1, in <module>
<   File "<console>", line 2, in foo

I'm not sure what's different about how Python3 handles it since it works just fine in Python2 as well as just fine on Python3 on OSX.

Will investigate.

PDB Integration

I'm currently using https://pypi.org/project/pdbpp/ as my debugger and was wondering if there's a way to hook better_exceptions into the .pdbrc.py file when a pdb statement or error occurs.

Any ideas on this..?

This is my current pdbrc configuration:

"""
This is an example configuration file for pdb++.
"""

import pdb


class Config(pdb.DefaultConfig):

    use_pygments = True
    disable_pytest_capturing = True
    stdin_paste = "epaste"
    filename_color = pdb.Color.lightgray
    use_terminal256formatter = False

    def __init__(self):
        try:
            from pygments.formatters import terminal
        except ImportError:
            pass
        else:
            self.colorscheme = terminal.TERMINAL_COLORS.copy()
            self.colorscheme.update(
                {
                    terminal.Keyword: ("darkred", "red"),
                    terminal.Number: ("darkyellow", "yellow"),
                    terminal.String: ("brown", "green"),
                    terminal.Name.Function: ("darkgreen", "blue"),
                    terminal.Name.Namespace: ("teal", "turquoise"),
                }
            )

    def setup(self, pdb):
        Pdb = pdb.__class__
        Pdb.do_l = Pdb.do_longlist
        Pdb.do_st = Pdb.do_sticky

fix Python 2 import

The Python 2 import code for load_module() in __main__.py is broken:

(be) dtroeder@sommar:/tmp$ pip install better_exceptions
DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7.
Collecting better_exceptions
Installing collected packages: better-exceptions
Successfully installed better-exceptions-0.2.2
(be) dtroeder@sommar:/tmp$ export BETTER_EXCEPTIONS=1
(be) dtroeder@sommar:/tmp$ python -m better_exceptions
Traceback (most recent call last):
  File "/usr/lib/python2.7/runpy.py", line 174, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
         │       └ {'argparse': <module 'argparse' from '/usr/lib/python2.7/argparse.pyc'>, 'parser': ArgumentParser(prog='python -m better_excepti...
         └ <code object <module> at 0x7f03cfa0b6b0, file "/tmp/be/lib/python2.7/site-packages/better_exceptions/__main__.py", line 1>
  File "/tmp/be/lib/python2.7/site-packages/better_exceptions/__main__.py", line 31, in <module>
    load_module('pystartup', startup_file)
    │                        └ '/home/dtroeder/.pythonrc.py'<function load_module at 0x7f03cf56a0c8>
  File "/tmp/be/lib/python2.7/site-packages/better_exceptions/__main__.py", line 19, in load_module
    imp.load_module('a_b', f, path, ('.py', 'U', imp.PY_SOURCE))
    │                                            └ <module 'imp' (built-in)><module 'imp' (built-in)>
NameError: global name 'f' is not defined

Color support for non-xterm terminals

The nocolor check is a bit too strict:

NOCOLOR = not os.isatty(2) or os.name == 'nt' or os.getenv('TERM', '')[:5] != 'xterm'

There are a lot of terminals that don't set their TERM env to xterm but support colors (e.g. TERM=urxvt-unicode-256color), including the TTYs on many systems. I'd suggest omitting the TERM check or limiting it to a few common excludes.


PS: If anyone else uses a terminal where color support is blocked (like urxvt) you can work around it by explicitly overwriting the NOCOLOR variable:

import better_exceptions
better_exceptions.NOCOLOR = False

Travis builds do not tests ascii encoding

See for example: Job #30.5

We can see a warning in the logs:

./test_all.sh: line 52: warning: setlocale: LC_ALL: cannot change locale (en_US.ascii)

So I guess it is still testing with default UTF-8.

I do not know how to fix that unfortunately.

How can I use in pycharm?

Hello , I have already successfully install better-exceptions. When I create a new *.py file ,how can I use this module ,like:
import better-exceptions
and then?

not work with tornado

env:

"sys": "win10",
"python: "python3.6.5",
"tornado": "5.0.2",
"better-excpetions": "0.2.1"

demo

# coding: utf-8
import sys
import better_exceptions
better_exceptions.hook()
from tornado import  gen
from tornado.ioloop import IOLoop


@gen.coroutine
def main():
    b = 1 + 1
    assert b == 3

def ping(loop:IOLoop, timeout=2):
    loop.add_callback(lambda : ping(loop, timeout))

if __name__ == '__main__':
    loop = IOLoop.current()
    loop.add_callback(main)
    ping(loop, timeout=1)
    loop.start()

outuput

ERROR:tornado.application:Exception in callback functools.partial(<function wrap.<locals>.null_wrapper at 0x0000018EA688B378>, <Future finished exception=AssertionError()>)
Traceback (most recent call last):
  File "C:\Python36\lib\site-packages\tornado\ioloop.py", line 759, in _run_callback
    ret = callback()
  File "C:\Python36\lib\site-packages\tornado\stack_context.py", line 276, in null_wrapper
    return fn(*args, **kwargs)
  File "C:\Python36\lib\site-packages\tornado\ioloop.py", line 780, in _discard_future_result
    future.result()
  File "C:\Python36\lib\site-packages\tornado\gen.py", line 296, in wrapper
    result = func(*args, **kwargs)
  File "C:\Python36\lib\types.py", line 248, in wrapped
    coro = func(*args, **kwargs)
  File "F:/Seafile/Nutstore/pycode/cqh_exceptions/try_tornado.py", line 12, in main
    assert b == 3
AssertionError

Hyperlinks

It would be great if the better exceptions could output file:/// hyperlinks using the new ansi standard.

I'm not quite sure which bit of the output should be the link.

Unfortunately AFAICT line numbers aren't supported, but just being able to click from somewhere in the exception and open the file would be a big plus.

https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda

List of small errors to fix and possible improvements to implement

I prefer to gather everything here rather than opening a ticket for each of them, as some bugs are really minimal. Some points are just ideas I have had.

  • Nested issues are not displayed (see)
  • Surround repr(value) with try / except just in case something goes wrong (see traceback source code)
  • Print Traceback (most recent call last): right before formatting the issue, so user have a clue about what is going wrong if formatting hangs (see #37)
  • \n inside a string should be escaped, no newline should be displayed (see)
  • SyntaxError are wrongly truncated (see and see #35)
  • Multilines expressions like a = 1 + [2, \n 3] are not enhanced
  • Encoding issues:
    • "天" / 1 is wrongly displayed as "天" / 11 because of utf-8 string slicing (see)
    • Do not force char decoding, stay close to the default behavior displaying "\u5929" instead of "天" if LANG = en_US.ascii (see)
    • Keep the quotation marks and u string prefixes used in the source code, do not replace them with ' marks (see)
    • Encoding long strings may raise an error (see #34)
  • Possible readability improvement:
    • Syntax highlighting could (optionally) include operators (*, +, -, /, ...), functions, methods
    • int and string values could be highlighted with two different colors
    • Traceback frames could be optionally spaced between each others (see)
    • Is it possible for shadowed built-in (len = lambda x: 5) to not be higlighted as a built-in?
    • Location (File "test.py", line 13 in func) could be colored (see #38)
    • Other messages (like Exception: XXX, Traceback (most recent call last):, ...) could be optionally colored too
    • Traceback relevant to the user could be bold / not relevant could be dimmed (see #38)
    • Advanced user could have more control over formatting to suit its need with colors which works best on its terminal, or by customizing style (see #39). For example: import better_exceptions; better_exceptions.THEME['location_message'] = 'File "{filepath} +{lineno}", in {source}'. Maybe use ansimarkup to easily colorize / strip (if SUPPORTS_COLORS is False) messages.
    • c = self.a + self.b: is it possible to give information about a and b? It seems very complicated. What about dct['key'], lst[3], obj.val, a.b.c, x.get('key', default), etc.

Display coding problem

Code:

-- coding:utf-8 --

import better_exceptions
import sys
print(sys.stdout.encoding)
better_exceptions.hook()

foo = 52

def shallow(a, b):
deep(a + b)

def deep(val):
global foo
assert val > 10 and foo == 60

bar = foo - 50
shallow(bar, 15)
shallow(bar, 2)

display:
"C:\Program Files\Python36\python.exe" C:/Users/Alex/PycharmProjects/Test/Test02.py
UTF-8
Traceback (most recent call last):
File "C:/Users/Alex/PycharmProjects/Test/Test02.py", line 20, in
shallow(bar, 15)
�� �� 2
�� <function shallow at 0x000001860AAEF730>
File "C:/Users/Alex/PycharmProjects/Test/Test02.py", line 11, in shallow
deep(a + b)
�� �� �� 15
�� �� 2
�� <function deep at 0x000001860B079620>
File "C:/Users/Alex/PycharmProjects/Test/Test02.py", line 16, in deep
assert val > 10 and foo == 60
�� �� 52
�� 17
AssertionError: assert val > 10 and foo == 60

Process finished with exit code 1

system: windows 10
python: 3.6

Indentation errors stop better-exceptions from returning correct errors.

I'm using gentoo Linux x86_64 on a PC desktop.

Using Python 2.7.10

Using better-exceptions version 0.1.8

I installed as non root user: pip install -U better_exceptions

Put this in a file:

import better_exceptions
if (True):
    a = 5
       print("foobar")      #intentional faulty indentation here.
    b = 7

It works as I expect, the better_exception defaults to normal python interpreter telling me line 4 has bad indentation. Great.

But when I put the import in my /home/el/.local/lib64/python2.7/site-packages/usercustomize.py then better_exceptions charges ahead, and fails, returning:

Traceback (most recent call last):
File "a.py", line 4

So better_exceptions isn't wrong, however, it failed to defer to regular python error messaging letting me know about bad indentation.

Perhaps the problem is the way I'm importing using the usercustomize.py script. Obviously your code is working, just not when the import is specified in a pre-processing file.

psutil, expect and setlocale

I am packaging this for openSUSE, and noticed that it was using ps. I noticed because that isnt in the standard rpmbuild image, so I got file not found errors in the execs. I wonder if it would be possible to use the Python package psutil instead, as that would make the tests a bit more independent of the host environment.

Also it is using expect. pexpect is another alternative.

Then this package can declare all of its test dependencies, and packagers will have an effortless time ;-)

Then the remaining problem I am facing is the test suite uses setlocale, which isnt working in an rpmbuild environment, causing the tests to fail like this:

   30s] > sh: warning: setlocale: LC_ALL: cannot change locale (en_US.ascii)
[   30s] 81a88

Working area at https://build.opensuse.org/package/show/home:jayvdb:py-new/python-better-exceptions

Add support for doc strings in functions

It might be helpful to have an option to enable showing doc string in traceback if the function has it defined in __doc__ attribute near the traceback explanation section to make it even more awesome

Logged exceptions shouldn't contain colour

Issuehunt badges

Currently if the output is to a terminal, then an exception that gets logged will also include the colour escape codes. This is not really ideal since they will just show up as raw escape codes in most editors, making the log harder to read. So it would be great if the logged exceptions could skip the colour-coding even if the current terminal supports colours. The output to the terminal itself should still be coloured of course. Thanks!


IssueHunt Summary

Backers (Total: $50.00)

Submitted pull Requests


Become a backer now!

Or submit a pull request to get the deposits!

Tips


IssueHunt has been backed by the following sponsors. Become a sponsor

format_exception compatibility

One may expect better_exceptions.format_exception and traceback.format_exception to be compatible. The difference is though that the first one returns list while the former one returns string. I would suggest to consider aligning behavior of these methods.

An ipython startup file to enable better_exceptions in ipython

If you put this in $HOME/.ipython/profile_default/startup/00-better_exceptions.py this will enable better_exceptions to be used as the default exception formatter in ipython. Maybe this should go in a contrib folder or something like that.

from __future__ import print_function
import better_exceptions, sys

ip = get_ipython()
old_show = ip.showtraceback

def exception_thunk(exc_tuple=None, filename=None,
                    tb_offset=None, exception_only=False):
    print("Thunk: %r %r %r %r" % (exc_tuple, filename, tb_offset, exception_only),
          file=sys.stderr)
    notuple = False
    if exc_tuple is None:
        notuple = True
        exc_tuple = sys.exc_info()
    use_better = True
    use_better = use_better and (filename is None)
    use_better = use_better and (tb_offset is None)
    use_better = use_better and (not exception_only)
    use_better = use_better and (not isinstance(exc_tuple[0], SyntaxError))
    if use_better:
        return better_exceptions.excepthook(*exc_tuple)
    else:
        return old_show(None if notuple else exc_tuple,
                        filename, tb_offset, exception_only)

ip.showtraceback = exception_thunk

Better Exceptions hangs Dask Distributed execution on exception

Here is the reproduction:

import better_exceptions

import dask
import dask.distributed


def x():
    assert 0

if __name__ == '__main__':
    client = dask.distributed.Client()
    dask.delayed(x)().compute(get=client.get)

If I run this code with import better_exceptions commented out, I can see the AssertionError traceback and the program exits:

$ python test.py
distributed.utils - ERROR -
Traceback (most recent call last):
  File "/opt/conda/lib/python3.5/site-packages/distributed/utils.py", line 212, in f
    result[0] = yield make_coro()
  File "/opt/conda/lib/python3.5/site-packages/tornado/gen.py", line 1055, in run
    value = future.result()
  File "/opt/conda/lib/python3.5/site-packages/tornado/concurrent.py", line 238, in result
    raise_exc_info(self._exc_info)
  File "<string>", line 4, in raise_exc_info
  File "/opt/conda/lib/python3.5/site-packages/tornado/gen.py", line 1063, in run
    yielded = self.gen.throw(*exc_info)
  File "/opt/conda/lib/python3.5/site-packages/distributed/client.py", line 1551, in _get
    result = yield self._gather(packed)
  File "/opt/conda/lib/python3.5/site-packages/tornado/gen.py", line 1055, in run
    value = future.result()
  File "/opt/conda/lib/python3.5/site-packages/tornado/concurrent.py", line 238, in result
    raise_exc_info(self._exc_info)
  File "<string>", line 4, in raise_exc_info
  File "/opt/conda/lib/python3.5/site-packages/tornado/gen.py", line 1063, in run
    yielded = self.gen.throw(*exc_info)
  File "/opt/conda/lib/python3.5/site-packages/distributed/client.py", line 996, in _gather
    traceback)
  File "/opt/conda/lib/python3.5/site-packages/six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "qq3.py", line 8, in x
    assert 0
AssertionError
Traceback (most recent call last):
  File "qq3.py", line 12, in <module>
    dask.delayed(x)().compute(get=client.get)
  File "/opt/conda/lib/python3.5/site-packages/dask/base.py", line 96, in compute
    (result,) = compute(self, traverse=False, **kwargs)
  File "/opt/conda/lib/python3.5/site-packages/dask/base.py", line 203, in compute
    results = get(dsk, keys, **kwargs)
  File "/opt/conda/lib/python3.5/site-packages/distributed/client.py", line 1590, in get
    resources=resources)
  File "/opt/conda/lib/python3.5/site-packages/distributed/utils.py", line 223, in sync
    six.reraise(*error[0])
  File "/opt/conda/lib/python3.5/site-packages/six.py", line 686, in reraise
    raise value
  File "/opt/conda/lib/python3.5/site-packages/distributed/utils.py", line 212, in f
    result[0] = yield make_coro()
  File "/opt/conda/lib/python3.5/site-packages/tornado/gen.py", line 1055, in run
    value = future.result()
  File "/opt/conda/lib/python3.5/site-packages/tornado/concurrent.py", line 238, in result
    raise_exc_info(self._exc_info)
  File "<string>", line 4, in raise_exc_info
  File "/opt/conda/lib/python3.5/site-packages/tornado/gen.py", line 1063, in run
    yielded = self.gen.throw(*exc_info)
  File "/opt/conda/lib/python3.5/site-packages/distributed/client.py", line 1551, in _get
    result = yield self._gather(packed)
  File "/opt/conda/lib/python3.5/site-packages/tornado/gen.py", line 1055, in run
    value = future.result()
  File "/opt/conda/lib/python3.5/site-packages/tornado/concurrent.py", line 238, in result
    raise_exc_info(self._exc_info)
  File "<string>", line 4, in raise_exc_info
  File "/opt/conda/lib/python3.5/site-packages/tornado/gen.py", line 1063, in run
    yielded = self.gen.throw(*exc_info)
  File "/opt/conda/lib/python3.5/site-packages/distributed/client.py", line 996, in _gather
    traceback)
  File "/opt/conda/lib/python3.5/site-packages/six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "qq3.py", line 8, in x
    assert 0
AssertionError
distributed.nanny - INFO - Worker closed
distributed.nanny - INFO - Worker closed
distributed.nanny - INFO - Worker closed
distributed.nanny - INFO - Worker closed
distributed.nanny - INFO - Worker closed
distributed.nanny - INFO - Worker closed
distributed.nanny - INFO - Worker closed
distributed.nanny - INFO - Worker closed
distributed.client - WARNING - Client report stream closed to scheduler

However, once I have import better_exception, the output is blank and the program just hangs forever.

Attribute inspection

Issuehunt badges

Hi. This is not an issue. Rather an improvement proposal. I thought that it may be useful if better_exceptions could show values of attributes accessed by period operator.

For instance, instead of:

Traceback (most recent call last):
  File "foo.py", line 9, in <module>
    print(123 / X.y)
                └ <class '__main__.X'>
ZeroDivisionError: division by zero

we would get:

Traceback (most recent call last):
  File "foo.py", line 9, in <module>
    print(123 / X.y)
                | └ 0
                └ <class '__main__.X'>
ZeroDivisionError: division by zero

IssueHunt Summary

dtrckd dtrckd has been rewarded.

Backers (Total: $40.00)

Submitted pull Requests


Tips


IssueHunt has been backed by the following sponsors. Become a sponsor

Don't work on termux

Python version: 3.7.2
better_exceptions: 0.2.2

>>> import g
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'g'
>>> import better_exceptions; better_exceptions.hook()
WARNING: better_exceptions will only inspect code from the command line
         when using: `python -m better_exceptions'. Otherwise, only code
         loaded from files will be inspected!
>>> import g
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'g'
>>>

Command line not being read on Windows

On POSIX systems we can (ab)use ps to find the command line arguments that were used when calling the process.

However on windows, we're going to have to use ctypes and call CommandLineToArgvW.

There is a placeholder conditional for windows in there right now, but it currently doesn't do anything. This makes #17 only work on POSIX systems for now, and ideally it'd be great to be able to expand this functionality to Windows.

However, I don't currently have a windows box to test this on :)

Enable better exceptions in my app ?

Hi,
Is there an API I can call to enable better exceptions in my app.
It's for Shoebot, where we basically exec python code to make graphics, we already have an home grown exception formatter thingy, but better exceptions looks better to me.

Cheers
S

Add documentation for Django support to README

Hi,

thank you for great lib.

However I had no luck to get it working under Django. I tried to put the import into wsgi.py or into specific file, where exception is thrown. No luck.

Any ideas?

strange behaviour while calling function during assertion

b0wl@kitchen:~$ cat be_test.py 
import better_exceptions
a=12
b='nooo'
assert a==13 and len(b) < 5

b0wl@kitchen:~$ python be_test.py 
Traceback (most recent call last):
  File "be_test..py", line 6, in <module>
    assert a==13 and len(b) < 5len(b) < 5
           │             ┕ 'nooo'
           ┕ 12
AssertionError: assert a==13 and len(b) < 5len(b) < 5

Duplicated len(b) < 5 after assertion line both in traceback and error msg.

Edit:

b0wl@kitchen:~$ python --version
Python 2.7.12

import error

While working with virtualenv, I get this error:

Python 2.7.12 (aff251e54385, Nov 09 2016, 18:02:49)
[PyPy 5.6.0 with GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>> import better_exceptions
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/********************/site-packages/better_exceptions/__init__.py", line 49, in <module>
    'builtins': __builtins__.keys(),
AttributeError: 'module' object has no attribute 'keys'

Add a way to use library functions without automatic hook

Hello.

You had a very good idea with better-exceptions, I love it!

However, I would like to be able to use some functions of the library (like format_exception()) without triggering the side effects related to the import.

I thought of a way to solve this problem by publishing two packages instead of a single one (so the user can do something like import better_exceptions_functions). I'm preparing a pull request so you can tell me what you think.

Catch/handle error from __repr__

repr() might trigger database queries in Django, and then e.g. pytest-django
might throw an exception that disallows this.

Therefore when using better-exceptions from a debugger it might crash it there.

I think the call to repr should be protected against this.

.venv/lib/python3.7/site-packages/pdb.py:1325: in _format_extra_exception
    fmt_exc = list(better_formatter.format_exception(etype, evalue, tb))
../../Vcs/better-exceptions/better_exceptions/formatter.py:322: in format_exception
    for line in self._format_exception(value, tb):
../../Vcs/better-exceptions/better_exceptions/formatter.py:311: in _format_exception
    formatted, colored_source = self.format_traceback(exc_traceback)
../../Vcs/better-exceptions/better_exceptions/formatter.py:274: in format_traceback
    formatted, colored = self.format_traceback_frame(tb)
../../Vcs/better-exceptions/better_exceptions/formatter.py:234: in format_traceback_frame
    filename, lineno, function, source, color_source, relevant_values = self.get_traceback_information(tb)
../../Vcs/better-exceptions/better_exceptions/formatter.py:227: in get_traceback_information
    relevant_values = self.get_relevant_values(source, frame, tree)
../../Vcs/better-exceptions/better_exceptions/formatter.py:135: in get_relevant_values
    values.append((text, col, self.format_value(val)))
../../Vcs/better-exceptions/better_exceptions/formatter.py:117: in format_value
    v = repr(v)
../../Vcs/django/django/db/models/query.py:250: in __repr__
    data = list(self[:REPR_OUTPUT_SIZE + 1])
../../Vcs/django/django/db/models/query.py:274: in __iter__
    self._fetch_all()
../../Vcs/django/django/db/models/query.py:1242: in _fetch_all
    self._result_cache = list(self._iterable_class(self))
../../Vcs/django/django/db/models/query.py:55: in __iter__
    results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
../../Vcs/django/django/db/models/sql/compiler.py:1098: in execute_sql
    cursor = self.connection.cursor()
../../Vcs/django/django/db/backends/base/base.py:260: in cursor
    return self._cursor()
../../Vcs/django/django/db/backends/base/base.py:235: in _cursor
    self.ensure_connection()
E   Failed: Database access not allowed, use the "django_db" mark, or the "db" or "transactional_db" fixtures to enable it.

How to use better-exceptions with unittest?

Issuehunt badges

I want to use better-exceptions to show error when using unittest. Here is my example:

test.py:

import better_exceptions
import unittest

better_exceptions.hook()


class MyTestCase(unittest.TestCase):
    def add(self, a, b):
        better_exceptions.hook()

        return a + b

    def test_add(self,):
        better_exceptions.hook()

        r1 = self.add(1, 2)
        r2 = self.add(2, "1")
        self.assertTrue(r1, r2)


if __name__ == "__main__":
    unittest.main()

shell:

$ export BETTER_EXCEPTIONS=1
$ echo $BETTER_EXCEPTIONS
1
$ python3 test.py
E
======================================================================
ERROR: test_add (__main__.MyTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test.py", line 17, in test_add
    r2 = self.add(2, "1")
  File "test.py", line 11, in add
    return a + b
TypeError: unsupported operand type(s) for +: 'int' and 'str'

----------------------------------------------------------------------
Ran 1 test in 0.004s

FAILED (errors=1)

Is there any way to use better-exceptions to print exception stack?


IssueHunt Summary

ocavue ocavue has been rewarded.

Backers (Total: $40.00)

Submitted pull Requests


Tips


IssueHunt has been backed by the following sponsors. Become a sponsor

Merge with TBVaccine?

Hello, I'm the author of tbvaccine, which is very similar in functionality. I just discovered this library, and quite like how variables are presented (tbvaccine prints all the locals in the frame).

Would you consider merging the two, or implementing some features so tbvaccine is superseded? Mainly, the features are highlighting the parts of the traceback that are relevant to the user (see screenshots), making the filenames bold, etc.

Thanks!

better_exceptions_hook.pth is missing from the package

Here is what I do on Ubuntu with python 3.5:

$ export BETTER_EXCEPTIONS=1
$ sudo apt remove python3-apport
# ...
$ python3 -c "import sys; print(sys.excepthook)"
<built-in function excepthook>
$ sudo pip3 install better_exceptions
Collecting better_exceptions
  Downloading better_exceptions-0.1.8.tar.gz
Installing collected packages: better-exceptions
  Running setup.py install for better-exceptions ... done
Successfully installed better-exceptions-0.1.8
$ python3 -c "import sys; print(sys.excepthook)"
<built-in function excepthook>
$ sudo pip3 uninstall better_exceptions
Uninstalling better-exceptions-0.1.8:
  /usr/local/lib/python3.5/dist-packages/better_exceptions-0.1.8-py3.5.egg-info
  /usr/local/lib/python3.5/dist-packages/better_exceptions/__init__.py
  /usr/local/lib/python3.5/dist-packages/better_exceptions/__main__.py
  /usr/local/lib/python3.5/dist-packages/better_exceptions/__pycache__/__init__.cpython-35.pyc
  /usr/local/lib/python3.5/dist-packages/better_exceptions/__pycache__/__main__.cpython-35.pyc
  /usr/local/lib/python3.5/dist-packages/better_exceptions/__pycache__/color.cpython-35.pyc
  /usr/local/lib/python3.5/dist-packages/better_exceptions/__pycache__/log.cpython-35.pyc
  /usr/local/lib/python3.5/dist-packages/better_exceptions/__pycache__/repl.cpython-35.pyc
  /usr/local/lib/python3.5/dist-packages/better_exceptions/color.py
  /usr/local/lib/python3.5/dist-packages/better_exceptions/log.py
  /usr/local/lib/python3.5/dist-packages/better_exceptions/repl.py
Proceed (y/n)? n

So the hook does not work. The file which README mentions, better_exceptions_hook.pth, does not exist. I have manually copied it from GitHub to /usr/local/lib/python3.5/dist-packages/better_exceptions_hook.pth and got this bizarre error:

$ python3 -c "import sys; print(sys.excepthook)"
An error occured while automatically hooking better_exceptions.
If you uninstalled better_exceptions, you should probably delete any 'better_exceptions_hook.pth' file on your system or unset your 'BETTER_EXCEPTIONS' environment variable.
Error processing line 1 of /usr/local/lib/python3.5/dist-packages/better_exceptions_hook.pth:

  Traceback (most recent call last):
    File "/usr/lib/python3.5/site.py", line 173, in addpackage
      exec(line)
    File "<string>", line 1, in <module>
    File "<string>", line 2, in <module>
  AttributeError: module 'better_exceptions' has no attribute 'hook'

Remainder of file ignored
<function excepthook at 0x7f6c4fe9b378>

Can this be used in testing?

I imported better_exceptions into my test, and ran it (both with nosetests and "plain" python). When the code being tested produces an exception, the standard trace is printed. I guess that testing frameworks are capturing the exceptions somehow. Would it be possible to tweak something so that better_exceptions is used to report the exceptions?

ANSI does not show correctly

Hello,

My env is Win7P x64 w/ SP1, Py 3.5.2 32b and colorama 0.3.7.

Possibly some misconfiguration of my cmd/system but all output from better_exceptions comes out like this

C:\Users\JMatos\MEOCloud\Python\dexp\dexp>python dexp.py
Traceback (most recent call last):
  File "dexp.py", line 45, in <module>
    ←[33;1mimport←[m base_dexp as bdexp
  File "C:\Users\JMatos\MEOCloud\Python\dexp\dexp\base_dexp.py", line 14, in <mo
dule>
    ←[33;1mimport←[m configuration as cfg
ImportError: No module named 'configuration'

and this

(dexp) C:\Users\JMatos\MEOCloud\Python\dexp\dexp>python dexp.py
Traceback (most recent call last):
  File "dexp.py", line 63, in <module>
    start()
    ←[36m-> <function start at 0x05786618>←[m
  File "C:\Users\JMatos\MEOCloud\Python\dexp\dexp\gui_dexp.py", line 536, in sta
rt
    ←[35;1mprint←[m(a + b)
    ←[36m      |   -> 'a'←[m
    ←[36m      -> 2←[m
TypeError: unsupported operand type(s) for +: 'int' and 'str'

However, on the same cmd console if I run a small colorama based game I created everything shows correctly (all the colors, brightness, etc.).

Any ideas?

Best regards,

JM

Not working when running via -c parameter

It doesn't work if you run commands by directly passing it to python interpreter via -c cli flag.

Can be reproduced using:
python -c "import better_exceptions; val=3; assert val > 10"

Add production switch

A few people now have pointed out it'd be neat to have a production switch.

While I personally would remove the import statement manually and only use this in debugging, it might be nice to have a production switch as well.

Line numbers are getting munged

Not entirely sure how to reproduce this minimally, but with better_exceptions enabled:

Traceback (most recent call last):
  File "test_color.py", line 1, in <module>
    from better_exceptions import color
  File "/src/qix-.better-exceptions/better_exceptions/color.py", line 64, in <module>
    SUPPORTS_COLOR = True
    └ None
TypeError: hex() argument can't be converted to hex

and without them enabled:

Traceback (most recent call last):
  File "test_color.py", line 1, in <module>
    from better_exceptions import color
  File "/src/qix-.better-exceptions/better_exceptions/color.py", line 51, in <module>
    print hex(magic_number)
TypeError: hex() argument can't be converted to hex

Options for colorizing the output.

I just wanted to show you what I did, and secondly get your opinion on an enhancement. See https://github.com/sentientmachine/better-exceptions/blob/master/README.md

I like it when the line numbers pop out so it draws my eye, so I did that in the link above.

Enhancement suggestion: these python errors/warnings are all well documented and well known. What if better-exceptions had a feature that would read the error message, read the code that committed it and return a more easily understood error message and a quick one or two line code snippet to show you what isn't allowed.

It would be most helpful for cryptic bugs that bubble-up implementationitis when you use numpy functions incorrectly and you get blasted in the face with incomprehensible error messages. Like for example matrix multiplications that say you can't invert a singular matrix. It gives you a 5 line refresher on why singular matrices can't be inverted.

Multiple terminfo locations

I'm on a Ubuntu 16.04 box. Automatic terminfo detection in the color.py module didn't work for me.
There are several terminfo directories in my root.

find / -type d -name terminfo -print

returns

/usr/share/terminfo
/etc/terminfo
/lib/terminfo

/etc/terminfo contains nothing but a README saying

This directory is for system-local terminfo descriptions. By default,
ncurses will search ${HOME}/.terminfo first, then /etc/terminfo (this
directory), then /lib/terminfo, and last not least /usr/share/terminfo.

Indeed, I found the relevant entry /lib/terminfo/x/xterm-256color. The directory /usr/share/terminfo is empty.

I can submit a PR fixing this by iterating over the possible terminfo directories in get_terminfo_file(), looking for an existing file.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.