summaryrefslogtreecommitdiff
path: root/raven/utils
diff options
context:
space:
mode:
authorMatt Robenolt <matt@ydekproductions.com>2016-12-14 13:55:15 -0800
committerGitHub <noreply@github.com>2016-12-14 13:55:15 -0800
commitc69abaa1506a426802e979c7f8c6a4ab0ef9c4d7 (patch)
tree5432701ff3b79809c81a1d4bd500f248e2e5067b /raven/utils
parentc2c5d876a3f0fdf7c44b0d022adde36ab61a48b2 (diff)
downloadraven-c69abaa1506a426802e979c7f8c6a4ab0ef9c4d7.tar.gz
Remove six entirely and unify _compat into utils.compat (#812)
Diffstat (limited to 'raven/utils')
-rw-r--r--raven/utils/__init__.py2
-rw-r--r--raven/utils/compat.py204
-rw-r--r--raven/utils/conf.py2
-rw-r--r--raven/utils/encoding.py2
-rw-r--r--raven/utils/imports.py2
-rw-r--r--raven/utils/serializer/base.py6
-rw-r--r--raven/utils/serializer/manager.py2
-rw-r--r--raven/utils/stacks.py2
-rw-r--r--raven/utils/wsgi.py3
9 files changed, 188 insertions, 37 deletions
diff --git a/raven/utils/__init__.py b/raven/utils/__init__.py
index db23162..173b856 100644
--- a/raven/utils/__init__.py
+++ b/raven/utils/__init__.py
@@ -7,7 +7,7 @@ raven.utils
"""
from __future__ import absolute_import
-from raven._compat import iteritems, string_types
+from raven.utils.compat import iteritems, string_types
import logging
import threading
from functools import update_wrapper
diff --git a/raven/utils/compat.py b/raven/utils/compat.py
index 4a3c8bc..9c4f8e3 100644
--- a/raven/utils/compat.py
+++ b/raven/utils/compat.py
@@ -2,50 +2,202 @@
raven.utils.compat
~~~~~~~~~~~~~~~~~~
-:copyright: (c) 2010-2012 by the Sentry Team, see AUTHORS for more details.
+:copyright: (c) 2010-2016 by the Sentry Team, see AUTHORS for more details.
:license: BSD, see LICENSE for more details.
+
+Utilities for writing code that runs on Python 2 and 3
"""
+# flake8: noqa
+
+# Copyright (c) 2010-2013 Benjamin Peterson
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy of
+# this software and associated documentation files (the "Software"), to deal in
+# the Software without restriction, including without limitation the rights to
+# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+# the Software, and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
from __future__ import absolute_import
+import operator
+import sys
+import types
-try:
- from urllib.error import HTTPError
-except ImportError:
- from urllib2 import HTTPError # NOQA
+PY2 = sys.version_info[0] == 2
+PY3 = sys.version_info[0] == 3
-try:
- import httplib # NOQA
-except ImportError:
- from http import client as httplib # NOQA
+
+if PY3:
+ string_types = str,
+ integer_types = int,
+ class_types = type,
+ text_type = str
+ binary_type = bytes
+else:
+ string_types = basestring,
+ integer_types = (int, long)
+ class_types = (type, types.ClassType)
+ text_type = unicode
+ binary_type = str
try:
- import urllib.request as urllib2
-except ImportError:
- import urllib2
+ advance_iterator = next
+except NameError:
+ def advance_iterator(it):
+ return it.next()
+next = advance_iterator
-Request = urllib2.Request
-urlopen = urllib2.urlopen
try:
- from urllib import quote as urllib_quote
-except ImportError:
- from urllib.parse import quote as urllib_quote # NOQA
+ callable = callable
+except NameError:
+ def callable(obj):
+ return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
+
+if PY3:
+ Iterator = object
+else:
+ class Iterator(object):
+
+ def next(self):
+ return type(self).__next__(self)
+
+
+if PY3:
+ def iterkeys(d, **kw):
+ return iter(d.keys(**kw))
+
+ def itervalues(d, **kw):
+ return iter(d.values(**kw))
+
+ def iteritems(d, **kw):
+ return iter(d.items(**kw))
+
+ def iterlists(d, **kw):
+ return iter(d.lists(**kw))
+else:
+ def iterkeys(d, **kw):
+ return d.iterkeys(**kw)
+
+ def itervalues(d, **kw):
+ return d.itervalues(**kw)
+
+ def iteritems(d, **kw):
+ return d.iteritems(**kw)
+
+ def iterlists(d, **kw):
+ return d.iterlists(**kw)
+
+
+if PY3:
+ def b(s):
+ return s.encode("latin-1")
+
+ def u(s):
+ return s
+ import io
+ StringIO = io.StringIO
+ BytesIO = io.BytesIO
+else:
+ def b(s):
+ return s
+ # Workaround for standalone backslash
+
+ def u(s):
+ return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape")
+ import StringIO
+ StringIO = BytesIO = StringIO.StringIO
+
+
+if PY3:
+ exec_ = getattr(__import__('builtins'), 'exec')
+
+ def reraise(tp, value, tb=None):
+ 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
+
+else:
+ def exec_(_code_, _globs_=None, _locs_=None):
+ """Execute code in a namespace."""
+ if _globs_ is None:
+ frame = sys._getframe(1)
+ _globs_ = frame.f_globals
+ if _locs_ is None:
+ _locs_ = frame.f_locals
+ del frame
+ elif _locs_ is None:
+ _locs_ = _globs_
+ exec("""exec _code_ in _globs_, _locs_""")
+
+ exec_("""def reraise(tp, value, tb=None):
+ try:
+ raise tp, value, tb
+ finally:
+ tb = None
+""")
-try:
- from queue import Queue
-except ImportError:
- from Queue import Queue # NOQA
+if sys.version_info[:2] == (3, 2):
+ exec_("""def raise_from(value, from_value):
+ try:
+ if from_value is None:
+ raise value
+ raise value from from_value
+ finally:
+ value = None
+""")
+elif sys.version_info[:2] > (3, 2):
+ exec_("""def raise_from(value, from_value):
+ try:
+ raise value from from_value
+ finally:
+ value = None
+""")
+else:
+ def raise_from(value, from_value):
+ raise value
-try:
- import urlparse as _urlparse
-except ImportError:
- from urllib import parse as _urlparse # NOQA
+if PY3:
+ from urllib.error import HTTPError
+ from http import client as httplib
+ import urllib.request as urllib2
+ from queue import Queue
+ from urllib.parse import quote as urllib_quote
+ from urllib import parse as urlparse
+else:
+ from urllib2 import HTTPError
+ import httplib
+ import urllib2
+ from Queue import Queue
+ from urllib import quote as urllib_quote
+ import urlparse
+
-urlparse = _urlparse
+def get_code(func):
+ rv = getattr(func, '__code__', getattr(func, 'func_code', None))
+ if rv is None:
+ raise TypeError('Could not get code from %r' % type(func).__name__)
+ return rv
def check_threads():
diff --git a/raven/utils/conf.py b/raven/utils/conf.py
index 4cf8c0d..7a9bc42 100644
--- a/raven/utils/conf.py
+++ b/raven/utils/conf.py
@@ -3,7 +3,7 @@ from __future__ import absolute_import
import copy
import os
-from raven._compat import string_types
+from raven.utils.compat import string_types
from raven.utils.imports import import_string
diff --git a/raven/utils/encoding.py b/raven/utils/encoding.py
index cf8bca5..44fe567 100644
--- a/raven/utils/encoding.py
+++ b/raven/utils/encoding.py
@@ -9,7 +9,7 @@ from __future__ import absolute_import, unicode_literals
import warnings
-from raven._compat import integer_types, text_type, binary_type, \
+from raven.utils.compat import integer_types, text_type, binary_type, \
string_types, PY2
diff --git a/raven/utils/imports.py b/raven/utils/imports.py
index 8086fc3..fc0dce9 100644
--- a/raven/utils/imports.py
+++ b/raven/utils/imports.py
@@ -1,6 +1,6 @@
from __future__ import absolute_import
-from raven._compat import PY2
+from raven.utils.compat import PY2
def import_string(key):
diff --git a/raven/utils/serializer/base.py b/raven/utils/serializer/base.py
index 1a5f32e..06753b2 100644
--- a/raven/utils/serializer/base.py
+++ b/raven/utils/serializer/base.py
@@ -11,8 +11,8 @@ from __future__ import absolute_import
import itertools
import types
-from raven._compat import text_type, binary_type, string_types, iteritems, \
- class_types, PY2
+from raven.utils.compat import text_type, binary_type, string_types, iteritems, \
+ class_types, PY2, PY3
from raven.utils.encoding import to_unicode
from .manager import manager as serialization_manager
@@ -113,7 +113,7 @@ class StringSerializer(Serializer):
def serialize(self, value, **kwargs):
string_max_length = kwargs.get('string_max_length', None)
- if not PY2:
+ if PY3:
return repr(value[:string_max_length])
try:
diff --git a/raven/utils/serializer/manager.py b/raven/utils/serializer/manager.py
index 7343111..bf22cc8 100644
--- a/raven/utils/serializer/manager.py
+++ b/raven/utils/serializer/manager.py
@@ -9,7 +9,7 @@ from __future__ import absolute_import
import logging
from contextlib import closing
-from raven._compat import text_type
+from raven.utils.compat import text_type
__all__ = ('register', 'transform')
diff --git a/raven/utils/stacks.py b/raven/utils/stacks.py
index ee95d7a..cacd2ee 100644
--- a/raven/utils/stacks.py
+++ b/raven/utils/stacks.py
@@ -13,7 +13,7 @@ import re
import sys
from raven.utils.serializer import transform
-from raven._compat import iteritems
+from raven.utils.compat import iteritems
_coding_re = re.compile(r'coding[:=]\s*([-\w.]+)')
diff --git a/raven/utils/wsgi.py b/raven/utils/wsgi.py
index 24a8e81..f68bd5e 100644
--- a/raven/utils/wsgi.py
+++ b/raven/utils/wsgi.py
@@ -6,8 +6,7 @@ This module implements WSGI related helpers adapted from ``werkzeug.wsgi``
"""
from __future__ import absolute_import
-from raven._compat import iteritems
-from raven.utils.compat import urllib_quote
+from raven.utils.compat import iteritems, urllib_quote
# `get_headers` comes from `werkzeug.datastructures.EnvironHeaders`