diff options
| author | Michael Merickel <michael@merickel.org> | 2018-10-31 01:36:26 -0500 |
|---|---|---|
| committer | Michael Merickel <michael@merickel.org> | 2018-11-12 21:39:23 -0600 |
| commit | 6b0e4625da2c53a1e3fdb4857fc7c6ba6ce562cf (patch) | |
| tree | 5d115273784eb021e5550539e39f552672921329 | |
| parent | 7429fcb5a96aa10bbe86da08bd0b30c9292efdde (diff) | |
| download | pyramid-6b0e4625da2c53a1e3fdb4857fc7c6ba6ce562cf.tar.gz pyramid-6b0e4625da2c53a1e3fdb4857fc7c6ba6ce562cf.tar.bz2 pyramid-6b0e4625da2c53a1e3fdb4857fc7c6ba6ce562cf.zip | |
initial work to remove py2 from the codebase
| -rw-r--r-- | .travis.yml | 6 | ||||
| -rw-r--r-- | appveyor.yml | 2 | ||||
| -rw-r--r-- | setup.py | 9 | ||||
| -rw-r--r-- | src/pyramid/compat.py | 302 | ||||
| -rw-r--r-- | src/pyramid/i18n.py | 15 | ||||
| -rw-r--r-- | src/pyramid/interfaces.py | 15 | ||||
| -rw-r--r-- | src/pyramid/request.py | 4 | ||||
| -rw-r--r-- | src/pyramid/scripts/pserve.py | 23 | ||||
| -rw-r--r-- | src/pyramid/session.py | 8 | ||||
| -rw-r--r-- | src/pyramid/testing.py | 4 | ||||
| -rw-r--r-- | src/pyramid/traversal.py | 61 | ||||
| -rw-r--r-- | src/pyramid/urldispatch.py | 12 | ||||
| -rw-r--r-- | src/pyramid/util.py | 13 | ||||
| -rw-r--r-- | tests/test_config/test_adapters.py | 6 | ||||
| -rw-r--r-- | tests/test_config/test_factories.py | 7 | ||||
| -rw-r--r-- | tests/test_config/test_init.py | 3 | ||||
| -rw-r--r-- | tests/test_path.py | 6 | ||||
| -rw-r--r-- | tests/test_request.py | 7 | ||||
| -rw-r--r-- | tests/test_session.py | 8 | ||||
| -rw-r--r-- | tests/test_traversal.py | 7 | ||||
| -rw-r--r-- | tests/test_urldispatch.py | 7 | ||||
| -rw-r--r-- | tests/test_util.py | 27 | ||||
| -rw-r--r-- | tox.ini | 24 |
23 files changed, 133 insertions, 443 deletions
diff --git a/.travis.yml b/.travis.yml index 6efbee21b..c4860d2de 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,20 +4,16 @@ sudo: false matrix: include: - - python: 2.7 - env: TOXENV=py27 - python: 3.4 env: TOXENV=py34 - python: 3.5 env: TOXENV=py35 - python: 3.6 env: TOXENV=py36 - - python: pypy - env: TOXENV=pypy - python: pypy3 env: TOXENV=pypy3 - python: 3.6 - env: TOXENV=py2-cover,py3-cover,coverage + env: TOXENV=py36-cover,coverage - python: 3.5 env: TOXENV=docs - python: 3.6 diff --git a/appveyor.yml b/appveyor.yml index 8c9d158e1..a9bcd40f1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -8,8 +8,6 @@ environment: TOXENV: "py35" - PYTHON: "C:\\Python34" TOXENV: "py34" - - PYTHON: "C:\\Python27" - TOXENV: "py27" cache: - '%LOCALAPPDATA%\pip\Cache' @@ -69,7 +69,6 @@ setup( "Development Status :: 6 - Mature", "Intended Audience :: Developers", "Programming Language :: Python", - "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", @@ -96,13 +95,9 @@ setup( package_dir={'': 'src'}, include_package_data=True, zip_safe=False, - python_requires='>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*', + python_requires='>=3.4', install_requires=install_requires, - extras_require={ - ':python_version<"3.2"': ['repoze.lru >= 0.4'], - 'testing': testing_extras, - 'docs': docs_extras, - }, + extras_require={'testing': testing_extras, 'docs': docs_extras}, tests_require=tests_require, test_suite="tests", entry_points="""\ diff --git a/src/pyramid/compat.py b/src/pyramid/compat.py index 31832c874..77e9bea98 100644 --- a/src/pyramid/compat.py +++ b/src/pyramid/compat.py @@ -13,34 +13,15 @@ except BaseException: # pragma: no cover __pypy__ = None PYPY = False -try: - import cPickle as pickle -except ImportError: # pragma: no cover - import pickle - -try: - from functools import lru_cache -except ImportError: - from repoze.lru import lru_cache - -# PY3 is left as bw-compat but PY2 should be used for most checks. -PY2 = sys.version_info[0] == 2 -PY3 = sys.version_info[0] == 3 - -if PY2: - string_types = (basestring,) - integer_types = (int, long) - class_types = (type, types.ClassType) - text_type = unicode - binary_type = str - long = long -else: - string_types = (str,) - integer_types = (int,) - class_types = (type,) - text_type = str - binary_type = bytes - long = int +from functools import lru_cache +import pickle + +string_types = (str,) +integer_types = (int,) +class_types = (type,) +text_type = str +binary_type = bytes +long = int def text_(s, encoding='latin-1', errors='strict'): @@ -59,236 +40,105 @@ def bytes_(s, encoding='latin-1', errors='strict'): return s -if PY2: - - def ascii_native_(s): - if isinstance(s, text_type): - s = s.encode('ascii') - return str(s) - - -else: - - def ascii_native_(s): - if isinstance(s, text_type): - s = s.encode('ascii') - return str(s, 'ascii', 'strict') - - -ascii_native_.__doc__ = """ -Python 3: If ``s`` is an instance of ``text_type``, return -``s.encode('ascii')``, otherwise return ``str(s, 'ascii', 'strict')`` - -Python 2: If ``s`` is an instance of ``text_type``, return -``s.encode('ascii')``, otherwise return ``str(s)`` -""" - - -if PY2: - - def native_(s, encoding='latin-1', errors='strict'): - """ If ``s`` is an instance of ``text_type``, return - ``s.encode(encoding, errors)``, otherwise return ``str(s)``""" - if isinstance(s, text_type): - return s.encode(encoding, errors) - return str(s) - - -else: - - def native_(s, encoding='latin-1', errors='strict'): - """ If ``s`` is an instance of ``text_type``, return - ``s``, otherwise return ``str(s, encoding, errors)``""" - if isinstance(s, text_type): - return s - return str(s, encoding, errors) - - -native_.__doc__ = """ -Python 3: If ``s`` is an instance of ``text_type``, return ``s``, otherwise -return ``str(s, encoding, errors)`` - -Python 2: If ``s`` is an instance of ``text_type``, return -``s.encode(encoding, errors)``, otherwise return ``str(s)`` -""" - -if PY2: - import urlparse - from urllib import quote as url_quote - from urllib import quote_plus as url_quote_plus - from urllib import unquote as url_unquote - from urllib import urlencode as url_encode - from urllib2 import urlopen as url_open - - def url_unquote_text( - v, encoding='utf-8', errors='replace' - ): # pragma: no cover - v = url_unquote(v) - return v.decode(encoding, errors) - - def url_unquote_native( - v, encoding='utf-8', errors='replace' - ): # pragma: no cover - return native_(url_unquote_text(v, encoding, errors)) - - -else: - from urllib import parse - - urlparse = parse - from urllib.parse import quote as url_quote - from urllib.parse import quote_plus as url_quote_plus - from urllib.parse import unquote as url_unquote - from urllib.parse import urlencode as url_encode - from urllib.request import urlopen as url_open - - url_unquote_text = url_unquote - url_unquote_native = url_unquote - - -if PY2: # pragma: no cover - - 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): - raise tp, value, tb -""" - ) +def ascii_native_(s): + """ + If ``s`` is an instance of ``text_type``, return + ``s.encode('ascii')``, otherwise return ``str(s, 'ascii', 'strict')`` + """ + if isinstance(s, text_type): + s = s.encode('ascii') + return str(s, 'ascii', 'strict') -else: # pragma: no cover - import builtins - exec_ = getattr(builtins, "exec") +def native_(s, encoding='latin-1', errors='strict'): + """ If ``s`` is an instance of ``text_type``, return + ``s``, otherwise return ``str(s, encoding, errors)`` + """ + if isinstance(s, text_type): + return s + return str(s, encoding, errors) - 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 - del builtins +from urllib import parse +urlparse = parse +from urllib.parse import quote as url_quote +from urllib.parse import quote_plus as url_quote_plus +from urllib.parse import unquote as url_unquote +from urllib.parse import urlencode as url_encode +from urllib.request import urlopen as url_open -if PY2: # pragma: no cover +url_unquote_text = url_unquote +url_unquote_native = url_unquote - def iteritems_(d): - return d.iteritems() - def itervalues_(d): - return d.itervalues() +import builtins - def iterkeys_(d): - return d.iterkeys() +exec_ = getattr(builtins, "exec") -else: # pragma: no cover +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 - def iteritems_(d): - return d.items() - def itervalues_(d): - return d.values() +del builtins - def iterkeys_(d): - return d.keys() +def iteritems_(d): + return d.items() -if PY2: - map_ = map -else: - def map_(*arg): - return list(map(*arg)) +def itervalues_(d): + return d.values() -if PY2: +def iterkeys_(d): + return d.keys() - def is_nonstr_iter(v): - return hasattr(v, '__iter__') +def map_(*arg): + return list(map(*arg)) -else: - def is_nonstr_iter(v): - if isinstance(v, str): - return False - return hasattr(v, '__iter__') +def is_nonstr_iter(v): + if isinstance(v, str): + return False + return hasattr(v, '__iter__') -if PY2: - im_func = 'im_func' - im_self = 'im_self' -else: - im_func = '__func__' - im_self = '__self__' +im_func = '__func__' +im_self = '__self__' -try: - import configparser -except ImportError: - import ConfigParser as configparser +import configparser -try: - from http.cookies import SimpleCookie -except ImportError: - from Cookie import SimpleCookie +from http.cookies import SimpleCookie -if PY2: - from cgi import escape -else: - from html import escape +from html import escape -if PY2: - input_ = raw_input -else: - input_ = input +input_ = input -if PY2: - from io import BytesIO as NativeIO -else: - from io import StringIO as NativeIO +from io import StringIO as NativeIO # "json" is not an API; it's here to support older pyramid_debugtoolbar # versions which attempt to import it import json -if PY2: - - def decode_path_info(path): - return path.decode('utf-8') +# see PEP 3333 for why we encode WSGI PATH_INFO to latin-1 before +# decoding it to utf-8 +def decode_path_info(path): + return path.encode('latin-1').decode('utf-8') -else: - # see PEP 3333 for why we encode WSGI PATH_INFO to latin-1 before - # decoding it to utf-8 - def decode_path_info(path): - return path.encode('latin-1').decode('utf-8') +# see PEP 3333 for why we decode the path to latin-1 +from urllib.parse import unquote_to_bytes -if PY2: - from urlparse import unquote as unquote_to_bytes - - def unquote_bytes_to_wsgi(bytestring): - return unquote_to_bytes(bytestring) - - -else: - # see PEP 3333 for why we decode the path to latin-1 - from urllib.parse import unquote_to_bytes - - def unquote_bytes_to_wsgi(bytestring): - return unquote_to_bytes(bytestring).decode('latin-1') +def unquote_bytes_to_wsgi(bytestring): + return unquote_to_bytes(bytestring).decode('latin-1') def is_bound_method(ob): @@ -296,15 +146,9 @@ def is_bound_method(ob): # support annotations and keyword-only arguments in PY3 -if PY2: - from inspect import getargspec -else: - from inspect import getfullargspec as getargspec +from inspect import getfullargspec as getargspec -if PY2: - from itertools import izip_longest as zip_longest -else: - from itertools import zip_longest +from itertools import zip_longest def is_unbound_method(fn): @@ -318,9 +162,7 @@ def is_unbound_method(fn): spec = getargspec(fn) has_self = len(spec.args) > 0 and spec.args[0] == 'self' - if PY2 and inspect.ismethod(fn): - return True - elif inspect.isfunction(fn) and has_self: + if inspect.isfunction(fn) and has_self: return True return False diff --git a/src/pyramid/i18n.py b/src/pyramid/i18n.py index e99a29aab..45f528852 100644 --- a/src/pyramid/i18n.py +++ b/src/pyramid/i18n.py @@ -8,7 +8,6 @@ from translationstring import ( TranslationStringFactory, # API ) -from pyramid.compat import PY2 from pyramid.decorator import reify from pyramid.interfaces import ( @@ -353,10 +352,7 @@ class Translations(gettext.GNUTranslations, object): """Like ``ugettext()``, but look the message up in the specified domain. """ - if PY2: - return self._domains.get(domain, self).ugettext(message) - else: - return self._domains.get(domain, self).gettext(message) + return self._domains.get(domain, self).gettext(message) def dngettext(self, domain, singular, plural, num): """Like ``ngettext()``, but look the message up in the specified @@ -374,14 +370,7 @@ class Translations(gettext.GNUTranslations, object): """Like ``ungettext()`` but look the message up in the specified domain. """ - if PY2: - return self._domains.get(domain, self).ungettext( - singular, plural, num - ) - else: - return self._domains.get(domain, self).ngettext( - singular, plural, num - ) + return self._domains.get(domain, self).ngettext(singular, plural, num) class LocalizerRequestMixin(object): diff --git a/src/pyramid/interfaces.py b/src/pyramid/interfaces.py index 31bcd7e88..f1e238c6b 100644 --- a/src/pyramid/interfaces.py +++ b/src/pyramid/interfaces.py @@ -1,7 +1,5 @@ from zope.interface import Attribute, Interface -from pyramid.compat import PY2 - # public API interfaces @@ -366,19 +364,6 @@ class IDict(Interface): def values(): """ Return a list of values from the dictionary """ - if PY2: - - def iterkeys(): - """ Return an iterator of keys from the dictionary """ - - def iteritems(): - """ Return an iterator of (k,v) pairs from the dictionary """ - - def itervalues(): - """ Return an iterator of values from the dictionary """ - - has_key = __contains__ - def pop(k, default=None): """ Pop the key k from the dictionary and return its value. If k doesn't exist, and default is provided, return the default. If k diff --git a/src/pyramid/request.py b/src/pyramid/request.py index 907b4477f..5ee87ff58 100644 --- a/src/pyramid/request.py +++ b/src/pyramid/request.py @@ -13,7 +13,7 @@ from pyramid.interfaces import ( ISessionFactory, ) -from pyramid.compat import text_, bytes_, native_, iteritems_ +from pyramid.compat import text_, bytes_, native_ from pyramid.decorator import reify from pyramid.i18n import LocalizerRequestMixin @@ -328,7 +328,7 @@ def apply_request_extensions(request, extensions=None): if extensions is None: extensions = request.registry.queryUtility(IRequestExtensions) if extensions is not None: - for name, fn in iteritems_(extensions.methods): + for name, fn in extensions.methods.items(): method = fn.__get__(request, request.__class__) setattr(request, name, method) diff --git a/src/pyramid/scripts/pserve.py b/src/pyramid/scripts/pserve.py index 581479d65..7d68521a4 100644 --- a/src/pyramid/scripts/pserve.py +++ b/src/pyramid/scripts/pserve.py @@ -19,8 +19,6 @@ import webbrowser import hupper -from pyramid.compat import PY2 - from pyramid.scripts.common import get_config_loader from pyramid.scripts.common import parse_vars from pyramid.path import AssetResolver @@ -380,18 +378,15 @@ def cherrypy_server_runner( server = WSGIServer(bind_addr, app, server_name=server_name, **kwargs) if ssl_pem is not None: - if PY2: - server.ssl_certificate = server.ssl_private_key = ssl_pem - else: - # creates wsgiserver.ssl_builtin as side-effect - try: - from cheroot.server import get_ssl_adapter_class - from cheroot.ssl.builtin import BuiltinSSLAdapter - except ImportError: - from cherrypy.wsgiserver import get_ssl_adapter_class - from cherrypy.wsgiserver.ssl_builtin import BuiltinSSLAdapter - get_ssl_adapter_class() - server.ssl_adapter = BuiltinSSLAdapter(ssl_pem, ssl_pem) + # creates wsgiserver.ssl_builtin as side-effect + try: + from cheroot.server import get_ssl_adapter_class + from cheroot.ssl.builtin import BuiltinSSLAdapter + except ImportError: + from cherrypy.wsgiserver import get_ssl_adapter_class + from cherrypy.wsgiserver.ssl_builtin import BuiltinSSLAdapter + get_ssl_adapter_class() + server.ssl_adapter = BuiltinSSLAdapter(ssl_pem, ssl_pem) if protocol_version: server.protocol = protocol_version diff --git a/src/pyramid/session.py b/src/pyramid/session.py index 68e0c506c..e9486ec6d 100644 --- a/src/pyramid/session.py +++ b/src/pyramid/session.py @@ -7,7 +7,7 @@ from zope.interface import implementer from webob.cookies import JSONSerializer, SignedSerializer -from pyramid.compat import pickle, PY2, text_, bytes_, native_ +from pyramid.compat import pickle, text_, bytes_, native_ from pyramid.csrf import check_csrf_origin, check_csrf_token from pyramid.interfaces import ISession @@ -255,12 +255,6 @@ def BaseCookieSessionFactory( __len__ = manage_accessed(dict.__len__) __iter__ = manage_accessed(dict.__iter__) - if PY2: - iteritems = manage_accessed(dict.iteritems) - itervalues = manage_accessed(dict.itervalues) - iterkeys = manage_accessed(dict.iterkeys) - has_key = manage_accessed(dict.has_key) - # modifying dictionary methods clear = manage_changed(dict.clear) update = manage_changed(dict.update) diff --git a/src/pyramid/testing.py b/src/pyramid/testing.py index f700b5a4e..5fe8f8a62 100644 --- a/src/pyramid/testing.py +++ b/src/pyramid/testing.py @@ -8,7 +8,7 @@ from zope.interface import implementer, alsoProvides from pyramid.interfaces import IRequest, ISession -from pyramid.compat import PY3, PYPY, class_types, text_ +from pyramid.compat import PYPY, class_types, text_ from pyramid.config import Configurator from pyramid.decorator import reify @@ -640,8 +640,6 @@ def skip_on(*platforms): # pragma: no cover skip = True if platform == 'pypy' and PYPY: skip = True - if platform == 'py3' and PY3: - skip = True def decorator(func): if isinstance(func, class_types): diff --git a/src/pyramid/traversal.py b/src/pyramid/traversal.py index 338b49083..f46937d73 100644 --- a/src/pyramid/traversal.py +++ b/src/pyramid/traversal.py @@ -9,7 +9,6 @@ from pyramid.interfaces import ( ) from pyramid.compat import ( - PY2, native_, text_, ascii_native_, @@ -580,49 +579,23 @@ the ``safe`` argument to this function. This corresponds to the """ -if PY2: - # special-case on Python 2 for speed? unchecked - def quote_path_segment(segment, safe=PATH_SEGMENT_SAFE): - """ %s """ % quote_path_segment_doc - # The bit of this code that deals with ``_segment_cache`` is an - # optimization: we cache all the computation of URL path segments - # in this module-scope dictionary with the original string (or - # unicode value) as the key, so we can look it up later without - # needing to reencode or re-url-quote it - try: - return _segment_cache[(segment, safe)] - except KeyError: - if ( - segment.__class__ is text_type - ): # isinstance slighly slower (~15%) - result = url_quote(segment.encode('utf-8'), safe) - else: - result = url_quote(str(segment), safe) - # we don't need a lock to mutate _segment_cache, as the below - # will generate exactly one Python bytecode (STORE_SUBSCR) - _segment_cache[(segment, safe)] = result - return result - - -else: - - def quote_path_segment(segment, safe=PATH_SEGMENT_SAFE): - """ %s """ % quote_path_segment_doc - # The bit of this code that deals with ``_segment_cache`` is an - # optimization: we cache all the computation of URL path segments - # in this module-scope dictionary with the original string (or - # unicode value) as the key, so we can look it up later without - # needing to reencode or re-url-quote it - try: - return _segment_cache[(segment, safe)] - except KeyError: - if segment.__class__ not in (text_type, binary_type): - segment = str(segment) - result = url_quote(native_(segment, 'utf-8'), safe) - # we don't need a lock to mutate _segment_cache, as the below - # will generate exactly one Python bytecode (STORE_SUBSCR) - _segment_cache[(segment, safe)] = result - return result +def quote_path_segment(segment, safe=PATH_SEGMENT_SAFE): + """ %s """ % quote_path_segment_doc + # The bit of this code that deals with ``_segment_cache`` is an + # optimization: we cache all the computation of URL path segments + # in this module-scope dictionary with the original string (or + # unicode value) as the key, so we can look it up later without + # needing to reencode or re-url-quote it + try: + return _segment_cache[(segment, safe)] + except KeyError: + if segment.__class__ not in (text_type, binary_type): + segment = str(segment) + result = url_quote(native_(segment, 'utf-8'), safe) + # we don't need a lock to mutate _segment_cache, as the below + # will generate exactly one Python bytecode (STORE_SUBSCR) + _segment_cache[(segment, safe)] = result + return result slash = text_('/') diff --git a/src/pyramid/urldispatch.py b/src/pyramid/urldispatch.py index de8a69d2a..1d3f8d91b 100644 --- a/src/pyramid/urldispatch.py +++ b/src/pyramid/urldispatch.py @@ -4,7 +4,6 @@ from zope.interface import implementer from pyramid.interfaces import IRoutesMapper, IRoute from pyramid.compat import ( - PY2, native_, text_, text_type, @@ -227,14 +226,9 @@ def _compile_route(route): def generator(dict): newdict = {} for k, v in dict.items(): - if PY2: - if v.__class__ is text_type: - # url_quote below needs bytes, not unicode on Py2 - v = v.encode('utf-8') - else: - if v.__class__ is binary_type: - # url_quote below needs a native string, not bytes on Py3 - v = v.decode('utf-8') + if v.__class__ is binary_type: + # url_quote below needs a native string, not bytes on Py3 + v = v.decode('utf-8') if k == remainder: # a stararg argument diff --git a/src/pyramid/util.py b/src/pyramid/util.py index bebf9e7d3..39b67471e 100644 --- a/src/pyramid/util.py +++ b/src/pyramid/util.py @@ -1,11 +1,6 @@ from contextlib import contextmanager import functools - -try: - # py2.7.7+ and py3.3+ have native comparison support - from hmac import compare_digest -except ImportError: # pragma: no cover - compare_digest = None +from hmac import compare_digest import inspect import weakref @@ -19,7 +14,6 @@ from pyramid.compat import ( string_types, bytes_, text_, - PY2, native_, ) @@ -337,10 +331,7 @@ def object_description(object): if isinstance(object, (bool, float, type(None))): return text_(str(object)) if isinstance(object, set): - if PY2: - return shortrepr(object, ')') - else: - return shortrepr(object, '}') + return shortrepr(object, '}') if isinstance(object, tuple): return shortrepr(object, ')') if isinstance(object, list): diff --git a/tests/test_config/test_adapters.py b/tests/test_config/test_adapters.py index d871e8825..60a4f3090 100644 --- a/tests/test_config/test_adapters.py +++ b/tests/test_config/test_adapters.py @@ -1,6 +1,5 @@ import unittest -from pyramid.compat import PY2 from . import IDummy @@ -270,10 +269,7 @@ class AdaptersConfiguratorMixinTests(unittest.TestCase): from pyramid.interfaces import IResponse config = self._makeOne(autocommit=True) - if PY2: - str_name = '__builtin__.str' - else: - str_name = 'builtins.str' + str_name = 'builtins.str' config.add_response_adapter('pyramid.response.Response', str_name) result = config.registry.queryAdapter('foo', IResponse) self.assertTrue(result.body, b'foo') diff --git a/tests/test_config/test_factories.py b/tests/test_config/test_factories.py index c03d3f68b..cca528275 100644 --- a/tests/test_config/test_factories.py +++ b/tests/test_config/test_factories.py @@ -161,7 +161,6 @@ class TestFactoriesMixin(unittest.TestCase): self.assertRaises(AttributeError, config.add_request_method) def test_add_request_method_with_text_type_name(self): - from pyramid.compat import text_, PY2 from pyramid.exceptions import ConfigurationError config = self._makeOne(autocommit=True) @@ -170,11 +169,7 @@ class TestFactoriesMixin(unittest.TestCase): pass def get_bad_name(): - if PY2: - name = text_(b'La Pe\xc3\xb1a', 'utf-8') - else: - name = b'La Pe\xc3\xb1a' - + name = b'La Pe\xc3\xb1a' config.add_request_method(boomshaka, name=name) self.assertRaises(ConfigurationError, get_bad_name) diff --git a/tests/test_config/test_init.py b/tests/test_config/test_init.py index 811672fb3..1cd63f113 100644 --- a/tests/test_config/test_init.py +++ b/tests/test_config/test_init.py @@ -2,7 +2,6 @@ import os import unittest from pyramid.compat import im_func -from pyramid.testing import skip_on from . import dummy_tween_factory from . import dummy_include @@ -1157,7 +1156,6 @@ test_config.dummy_include2""" "@view_config(name='two', renderer='string')" in which ) - @skip_on('py3') def test_hook_zca(self): from zope.component import getSiteManager @@ -1173,7 +1171,6 @@ test_config.dummy_include2""" finally: getSiteManager.reset() - @skip_on('py3') def test_unhook_zca(self): from zope.component import getSiteManager diff --git a/tests/test_path.py b/tests/test_path.py index 626bb1139..da7cd64e1 100644 --- a/tests/test_path.py +++ b/tests/test_path.py @@ -1,6 +1,5 @@ import unittest import os -from pyramid.compat import PY2 here = os.path.abspath(os.path.dirname(__file__)) @@ -429,10 +428,7 @@ class TestDottedNameResolver(unittest.TestCase): def test_zope_dottedname_style_resolve_builtin(self): typ = self._makeOne() - if PY2: - result = typ._zope_dottedname_style('__builtin__.str', None) - else: - result = typ._zope_dottedname_style('builtins.str', None) + result = typ._zope_dottedname_style('builtins.str', None) self.assertEqual(result, str) def test_zope_dottedname_style_resolve_absolute(self): diff --git a/tests/test_request.py b/tests/test_request.py index dcac501aa..60cc2b31a 100644 --- a/tests/test_request.py +++ b/tests/test_request.py @@ -1,7 +1,7 @@ import unittest from pyramid import testing -from pyramid.compat import PY2, text_, bytes_, native_ +from pyramid.compat import text_, bytes_, native_ from pyramid.security import AuthenticationAPIMixin, AuthorizationAPIMixin @@ -352,10 +352,7 @@ class TestRequest(unittest.TestCase): inp = text_( b'/\xe6\xb5\x81\xe8\xa1\x8c\xe8\xb6\x8b\xe5\x8a\xbf', 'utf-8' ) - if PY2: - body = json.dumps({'a': inp}).decode('utf-8').encode('utf-16') - else: - body = bytes(json.dumps({'a': inp}), 'utf-16') + body = bytes(json.dumps({'a': inp}), 'utf-16') request.body = body request.content_type = 'application/json; charset=utf-16' self.assertEqual(request.json_body, {'a': inp}) diff --git a/tests/test_session.py b/tests/test_session.py index 5e2a1ff55..f7e7bab05 100644 --- a/tests/test_session.py +++ b/tests/test_session.py @@ -607,13 +607,7 @@ class DummySerializer(object): return base64.b64encode(json.dumps(value).encode('utf-8')) def loads(self, value): - try: - return json.loads(base64.b64decode(value).decode('utf-8')) - - # base64.b64decode raises a TypeError on py2 instead of a ValueError - # and a ValueError is required for the session to handle it properly - except TypeError: - raise ValueError + return json.loads(base64.b64decode(value).decode('utf-8')) class DummySessionFactory(dict): diff --git a/tests/test_traversal.py b/tests/test_traversal.py index 61e480cbc..b517fa646 100644 --- a/tests/test_traversal.py +++ b/tests/test_traversal.py @@ -3,7 +3,7 @@ import unittest from pyramid.testing import cleanUp -from pyramid.compat import text_, native_, text_type, url_quote, PY2 +from pyramid.compat import text_, native_, text_type, url_quote class TraversalPathTests(unittest.TestCase): @@ -346,10 +346,7 @@ class ResourceTreeTraverserTests(unittest.TestCase): foo = DummyContext(bar, path) root = DummyContext(foo, 'root') policy = self._makeOne(root) - if PY2: - vhm_root = b'/Qu\xc3\xa9bec' - else: - vhm_root = b'/Qu\xc3\xa9bec'.decode('latin-1') + vhm_root = b'/Qu\xc3\xa9bec'.decode('latin-1') environ = self._getEnviron(HTTP_X_VHM_ROOT=vhm_root) request = DummyRequest(environ, path_info=text_('/bar')) result = policy(request) diff --git a/tests/test_urldispatch.py b/tests/test_urldispatch.py index 772250e89..b50e86b99 100644 --- a/tests/test_urldispatch.py +++ b/tests/test_urldispatch.py @@ -1,6 +1,6 @@ import unittest from pyramid import testing -from pyramid.compat import text_, PY2 +from pyramid.compat import text_ class TestRoute(unittest.TestCase): @@ -132,10 +132,7 @@ class RoutesMapperTests(unittest.TestCase): from pyramid.exceptions import URLDecodeError mapper = self._makeOne() - if PY2: - path_info = b'\xff\xfe\xe6\x00' - else: - path_info = b'\xff\xfe\xe6\x00'.decode('latin-1') + path_info = b'\xff\xfe\xe6\x00'.decode('latin-1') request = self._getRequest(PATH_INFO=path_info) self.assertRaises(URLDecodeError, mapper, request) diff --git a/tests/test_util.py b/tests/test_util.py index a36655f6f..8af5fe557 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -1,5 +1,5 @@ import unittest -from pyramid.compat import PY2, text_, bytes_ +from pyramid.compat import text_, bytes_ class Test_InstancePropertyHelper(unittest.TestCase): @@ -170,14 +170,10 @@ class Test_InstancePropertyHelper(unittest.TestCase): self.assertEqual(2, foo.y) def test_make_property_unicode(self): - from pyramid.compat import text_ from pyramid.exceptions import ConfigurationError cls = self._getTargetClass() - if PY2: - name = text_(b'La Pe\xc3\xb1a', 'utf-8') - else: - name = b'La Pe\xc3\xb1a' + name = b'La Pe\xc3\xb1a' def make_bad_name(): cls.make_property(lambda x: 1, name=name, reify=True) @@ -498,10 +494,7 @@ class Test_object_description(unittest.TestCase): self.assertEqual(self._callFUT(('a', 'b')), "('a', 'b')") def test_set(self): - if PY2: - self.assertEqual(self._callFUT(set(['a'])), "set(['a'])") - else: - self.assertEqual(self._callFUT(set(['a'])), "{'a'}") + self.assertEqual(self._callFUT(set(['a'])), "{'a'}") def test_list(self): self.assertEqual(self._callFUT(['a']), "['a']") @@ -841,26 +834,16 @@ class TestSentinel(unittest.TestCase): class TestCallableName(unittest.TestCase): def test_valid_ascii(self): from pyramid.util import get_callable_name - from pyramid.compat import text_ - - if PY2: - name = text_(b'hello world', 'utf-8') - else: - name = b'hello world' + name = b'hello world' self.assertEqual(get_callable_name(name), 'hello world') def test_invalid_ascii(self): from pyramid.util import get_callable_name - from pyramid.compat import text_ from pyramid.exceptions import ConfigurationError def get_bad_name(): - if PY2: - name = text_(b'La Pe\xc3\xb1a', 'utf-8') - else: - name = b'La Pe\xc3\xb1a' - + name = b'La Pe\xc3\xb1a' get_callable_name(name) self.assertRaises(ConfigurationError, get_bad_name) @@ -1,23 +1,19 @@ [tox] envlist = lint, - py27,py34,py35,py36,py37,py38,pypy,pypy3, - docs,{py2,py3}-cover,coverage, + py34,py35,py36,py37,py38,pypy3, + docs,py36-cover,coverage, [testenv] # Most of these are defaults but if you specify any you can't fall back # to defaults for others. basepython = - py27: python2.7 py34: python3.4 py35: python3.5 py36: python3.6 py37: python3.7 py38: python3.8 - pypy: pypy pypy3: pypy3 - py2: python2.7 - py3: python3.6 commands = nosetests --with-xunit --xunit-file=nosetests-{envname}.xml {posargs:} @@ -59,21 +55,13 @@ extras = # we separate coverage into its own testenv because a) "last run wins" wrt # cobertura jenkins reporting and b) pypy and jython can't handle any # combination of versions of coverage and nosexcover that i can find. -[testenv:py2-cover] -commands = - coverage run {envbindir}/nosetests - coverage xml -o coverage-py2.xml -setenv = - COVERAGE_FILE=.coverage.py2 -extras = - testing - -[testenv:py3-cover] +[testenv:py36-cover] +basepython = python3.6 commands = coverage run {envbindir}/nosetests - coverage xml -o coverage-py3.xml + coverage xml -o coverage-{envname}.xml setenv = - COVERAGE_FILE=.coverage.py3 + COVERAGE_FILE=.coverage.{envname} extras = testing |
