In Python 2, to raise a new exception but reuse a traceback requires a special form of ``raise`` (``raise etype, evalue, tb``). In Python 3, this is now done via a ``with_traceback`` method on exception objects. However this requires a bit of trickery as the former is invalid syntax in Python 3, hence pycompat bridge created via an exec for Python 2.
44 lines
1.1 KiB
Python
44 lines
1.1 KiB
Python
# -*- coding: utf-8 -*-
|
|
# to remove if we decide to add a dependency on six or future
|
|
# very strongly inspired by https://github.com/pallets/werkzeug/blob/master/werkzeug/_compat.py
|
|
import sys
|
|
|
|
PY2 = sys.version_info[0] == 2
|
|
|
|
if PY2:
|
|
# pylint: disable=long-builtin,dict-iter-method
|
|
integer_types = (int, long)
|
|
|
|
keys = lambda d: iter(d.iterkeys())
|
|
values = lambda d: iter(d.itervalues())
|
|
items = lambda d: iter(d.iteritems())
|
|
|
|
# noinspection PyUnresolvedReferences
|
|
from itertools import imap, izip, ifilter
|
|
|
|
def implements_iterator(cls):
|
|
cls.next = cls.__next__
|
|
del cls.__next__
|
|
return cls
|
|
|
|
exec ('def reraise(tp, value, tb=None):\n raise tp, value, tb')
|
|
else:
|
|
# pylint: disable=bad-functions
|
|
integer_types = (int,)
|
|
|
|
keys = lambda d: iter(d.keys())
|
|
values = lambda d: iter(d.values())
|
|
items = lambda d: iter(d.items())
|
|
|
|
imap = map
|
|
izip = zip
|
|
ifilter = filter
|
|
|
|
def implements_iterator(cls):
|
|
return cls
|
|
|
|
def reraise(tp, value, tb=None):
|
|
if value.__traceback__ != tb:
|
|
raise value.with_traceback(tb)
|
|
raise value
|