diff options
| author | Michael Merickel <michael@merickel.org> | 2018-11-14 21:26:39 -0600 |
|---|---|---|
| committer | Michael Merickel <michael@merickel.org> | 2018-11-14 21:27:08 -0600 |
| commit | 78dcc6dff88829831ead187804ac9233eafab52e (patch) | |
| tree | 9a75d95c7cd31c68e8df55b495d0ed7d0d9d2449 | |
| parent | a705f56c3ebf34f25ab567d85b7d5b421983aa4a (diff) | |
| download | pyramid-78dcc6dff88829831ead187804ac9233eafab52e.tar.gz pyramid-78dcc6dff88829831ead187804ac9233eafab52e.tar.bz2 pyramid-78dcc6dff88829831ead187804ac9233eafab52e.zip | |
remove several places supporting bytes for py2
| -rw-r--r-- | src/pyramid/response.py | 4 | ||||
| -rw-r--r-- | src/pyramid/urldispatch.py | 11 | ||||
| -rw-r--r-- | src/pyramid/util.py | 27 | ||||
| -rw-r--r-- | tests/test_httpexceptions.py | 6 | ||||
| -rw-r--r-- | tests/test_renderers.py | 2 | ||||
| -rw-r--r-- | tests/test_urldispatch.py | 17 | ||||
| -rw-r--r-- | tests/test_util.py | 52 |
7 files changed, 90 insertions, 29 deletions
diff --git a/src/pyramid/response.py b/src/pyramid/response.py index 38f9fa1ce..8a2ba8929 100644 --- a/src/pyramid/response.py +++ b/src/pyramid/response.py @@ -100,14 +100,12 @@ class FileIter(object): def __iter__(self): return self - def next(self): + def __next__(self): val = self.file.read(self.block_size) if not val: raise StopIteration return val - __next__ = next # py3 - def close(self): self.file.close() diff --git a/src/pyramid/urldispatch.py b/src/pyramid/urldispatch.py index 6348ae7e2..97626c5dd 100644 --- a/src/pyramid/urldispatch.py +++ b/src/pyramid/urldispatch.py @@ -188,14 +188,6 @@ def _compile_route(route): match = re.compile(pattern).match def matcher(path): - # This function really wants to consume Unicode patterns natively, - # but if someone passes us a bytestring, we allow it by converting it - # to Unicode using the ASCII decoding. We decode it using ASCII - # because we don't want to accept bytestrings with high-order - # characters in them here as we have no idea what the encoding - # represents. - if path.__class__ is not str: - path = text_(path, 'ascii') m = match(path) if m is None: return None @@ -216,7 +208,7 @@ def _compile_route(route): newdict = {} for k, v in dict.items(): if v.__class__ is bytes: - # url_quote below needs a native string, not bytes on Py3 + # url_quote below needs a native string v = v.decode('utf-8') if k == remainder: @@ -230,7 +222,6 @@ def _compile_route(route): else: if v.__class__ is not str: v = str(v) - # v may be bytes (py2) or native string (py3) v = q(v) # at this point, the value will be a native string diff --git a/src/pyramid/util.py b/src/pyramid/util.py index 6cd8225aa..0688e67d3 100644 --- a/src/pyramid/util.py +++ b/src/pyramid/util.py @@ -603,10 +603,7 @@ def takes_one_arg(callee, attr=None, argname=None): if inspect.isroutine(callee): fn = callee elif inspect.isclass(callee): - try: - fn = callee.__init__ - except AttributeError: - return False + fn = callee.__init__ ismethod = hasattr(fn, '__call__') else: try: @@ -614,15 +611,11 @@ def takes_one_arg(callee, attr=None, argname=None): except AttributeError: return False - try: - argspec = inspect.getfullargspec(fn) - except TypeError: - return False - + argspec = inspect.getfullargspec(fn) args = argspec[0] if hasattr(fn, '__func__') or ismethod: - # it's an instance method (or unbound method on py2) + # it's an instance method if not args: return False args = args[1:] @@ -676,8 +669,12 @@ def is_unbound_method(fn): def reraise(tp, value, tb=None): - if value is None: - value = tp - if value.__traceback__ is not tb: - raise value.with_traceback(tb) - raise value + try: + if value is None: + value = tp() + if value.__traceback__ is not tb: + raise value.with_traceback(tb) + raise value + finally: + value = None + tb = None diff --git a/tests/test_httpexceptions.py b/tests/test_httpexceptions.py index 195496e2e..48c4a22f3 100644 --- a/tests/test_httpexceptions.py +++ b/tests/test_httpexceptions.py @@ -67,6 +67,12 @@ class Test__no_escape(unittest.TestCase): def test_not_basestring(self): self.assertEqual(self._callFUT(42), '42') + def test_bytes(self): + self.assertEqual( + self._callFUT(b'/La Pe\xc3\xb1a/{x}'), + b'/La Pe\xc3\xb1a/{x}'.decode('utf-8'), + ) + def test_unicode(self): class DummyUnicodeObject(object): def __unicode__(self): diff --git a/tests/test_renderers.py b/tests/test_renderers.py index 0eacfa996..0e9f99d15 100644 --- a/tests/test_renderers.py +++ b/tests/test_renderers.py @@ -774,7 +774,7 @@ class DummyResponse: body = b'' # compat for renderer that will set unicode on py3 - def _set_text(self, val): # pragma: no cover + def _set_text(self, val): self.body = val.encode('utf8') text = property(fset=_set_text) diff --git a/tests/test_urldispatch.py b/tests/test_urldispatch.py index 9296a50e1..a74731730 100644 --- a/tests/test_urldispatch.py +++ b/tests/test_urldispatch.py @@ -140,6 +140,23 @@ class RoutesMapperTests(unittest.TestCase): request.registry = get_current_registry() self.assertRaises(URLDecodeError, mapper, request) + def test___call__pathinfo_KeyError(self): + from pyramid.threadlocal import get_current_registry + + class DummyRequest: + @property + def path_info(self): + # if the PATH_INFO is missing from the environ + raise KeyError + + mapper = self._makeOne() + mapper.connect('root', '') + request = DummyRequest() + request.registry = get_current_registry() + result = mapper(request) + self.assertEqual(result['route'], mapper.routes['root']) + self.assertEqual(result['match'], {}) + def test___call__route_matches(self): mapper = self._makeOne() mapper.connect('foo', 'archives/:action/:article') diff --git a/tests/test_util.py b/tests/test_util.py index 676290676..d6d1d1502 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -1,3 +1,4 @@ +import sys import unittest from pyramid.compat import text_, bytes_ @@ -1246,3 +1247,54 @@ class TestUnboundMethods(unittest.TestCase): return 'OK' self.assertFalse(self._callFUT(func)) + + +class TestReraise(unittest.TestCase): + def _callFUT(self, *args): + from pyramid.util import reraise + + return reraise(*args) + + def test_it(self): + # tests cribbed from six.py + def get_next(tb): + return tb.tb_next.tb_next.tb_next + + e = Exception('blah') + try: + raise e + except Exception: + tp, val, tb = sys.exc_info() + + try: + self._callFUT(tp, val, tb) + except Exception: + tp2, val2, tb2 = sys.exc_info() + self.assertIs(tp2, Exception) + self.assertIs(val2, e) + self.assertIs(get_next(tb2), tb) + + try: + self._callFUT(tp, val) + except Exception: + tp2, val2, tb2 = sys.exc_info() + self.assertIs(tp2, Exception) + self.assertIs(val2, e) + self.assertIsNot(get_next(tb2), tb) + + try: + self._callFUT(tp, val, tb2) + except Exception: + tp2, val2, tb3 = sys.exc_info() + self.assertIs(tp2, Exception) + self.assertIs(val2, e) + self.assertIs(get_next(tb3), tb2) + + try: + self._callFUT(tp, None, tb) + except Exception: + tp2, val2, tb2 = sys.exc_info() + self.assertIs(tp2, Exception) + self.assertIsNot(val2, val) + self.assertIsInstance(val2, Exception) + self.assertIs(get_next(tb2), tb) |
