diff options
author | Matt Robenolt <matt@ydekproductions.com> | 2016-12-14 13:55:15 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-12-14 13:55:15 -0800 |
commit | c69abaa1506a426802e979c7f8c6a4ab0ef9c4d7 (patch) | |
tree | 5432701ff3b79809c81a1d4bd500f248e2e5067b /raven/utils | |
parent | c2c5d876a3f0fdf7c44b0d022adde36ab61a48b2 (diff) | |
download | raven-c69abaa1506a426802e979c7f8c6a4ab0ef9c4d7.tar.gz |
Remove six entirely and unify _compat into utils.compat (#812)
Diffstat (limited to 'raven/utils')
-rw-r--r-- | raven/utils/__init__.py | 2 | ||||
-rw-r--r-- | raven/utils/compat.py | 204 | ||||
-rw-r--r-- | raven/utils/conf.py | 2 | ||||
-rw-r--r-- | raven/utils/encoding.py | 2 | ||||
-rw-r--r-- | raven/utils/imports.py | 2 | ||||
-rw-r--r-- | raven/utils/serializer/base.py | 6 | ||||
-rw-r--r-- | raven/utils/serializer/manager.py | 2 | ||||
-rw-r--r-- | raven/utils/stacks.py | 2 | ||||
-rw-r--r-- | raven/utils/wsgi.py | 3 |
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` |