Skip to content

Commit 8620442

Browse files
author
Emanuele Palazzetti
authored
[pylons] ensure the middleware code is Python 3 compatible (#475)
* [compat] add Py2 and Py3 `reraise` compatible function * [pylons] use Py2 and Py3 compatible reraise
1 parent 99d3c7b commit 8620442

File tree

4 files changed

+53
-3
lines changed

4 files changed

+53
-3
lines changed

ddtrace/compat.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,25 @@ def to_unicode(s):
7979
msgpack_type = bytes
8080
numeric_types = (int, float)
8181

82+
if PY2:
83+
# avoids Python 3 `SyntaxError`
84+
# this block will be replaced with the `six` library
85+
from .utils.reraise import _reraise as reraise
86+
else:
87+
def reraise(tp, value, tb=None):
88+
"""Python 3 re-raise function. This function is internal and
89+
will be replaced entirely with the `six` library.
90+
"""
91+
try:
92+
if value is None:
93+
value = tp()
94+
if value.__traceback__ is not tb:
95+
raise value.with_traceback(tb)
96+
raise value
97+
finally:
98+
value = None
99+
tb = None
100+
82101

83102
__all__ = [
84103
'httplib',
@@ -89,4 +108,5 @@ def to_unicode(s):
89108
'StringIO',
90109
'urlencode',
91110
'parse',
111+
'reraise',
92112
]

ddtrace/contrib/pylons/middleware.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from .renderer import trace_rendering
88
from .constants import CONFIG_MIDDLEWARE
99

10+
from ...compat import reraise
1011
from ...ext import http, AppTypes
1112
from ...propagation.http import HTTPPropagator
1213

@@ -78,7 +79,7 @@ def _start_response(status, *args, **kwargs):
7879
span.error = 1
7980

8081
# re-raise the original exception with its original traceback
81-
raise typ, val, tb
82+
reraise(typ, val, tb=tb)
8283
except SystemExit:
8384
span.set_tag(http.STATUS_CODE, 500)
8485
span.error = 1

ddtrace/utils/reraise.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
def _reraise(tp, value, tb=None):
2+
"""Python 2 re-raise function. This function is internal and
3+
will be replaced entirely with the `six` library.
4+
"""
5+
raise tp, value, tb

tests/test_compat.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
# -*- coding: utf-8 -*-
22
# Define source file encoding to support raw unicode characters in Python 2
3+
import sys
34

45
# Third party
5-
from nose.tools import eq_
6+
from nose.tools import eq_, assert_raises
67

78
# Project
8-
from ddtrace.compat import to_unicode, PY2
9+
from ddtrace.compat import to_unicode, PY2, reraise
910

1011

1112
# Use different test suites for each Python version, this allows us to test the expected
@@ -92,3 +93,26 @@ def test_to_unicode_non_string(self):
9293
eq_(to_unicode(True), 'True')
9394
eq_(to_unicode(None), 'None')
9495
eq_(to_unicode(dict(key='value')), '{\'key\': \'value\'}')
96+
97+
98+
class TestPy2Py3Compat(object):
99+
"""Common tests to ensure functions are both Python 2 and
100+
Python 3 compatible.
101+
"""
102+
def test_reraise(self):
103+
# ensure the `raise` function is Python 2/3 compatible
104+
with assert_raises(Exception) as ex:
105+
try:
106+
raise Exception('Ouch!')
107+
except Exception as e:
108+
# original exception we want to re-raise
109+
(typ, val, tb) = sys.exc_info()
110+
try:
111+
# this exception doesn't allow a re-raise, and we need
112+
# to use the previous one collected via `exc_info()`
113+
raise Exception('Obfuscate!')
114+
except Exception:
115+
pass
116+
# this call must be Python 2 and 3 compatible
117+
raise reraise(typ, val, tb)
118+
eq_(ex.exception.args[0], 'Ouch!')

0 commit comments

Comments
 (0)