summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Merickel <michael@merickel.org>2018-10-31 01:36:26 -0500
committerMichael Merickel <michael@merickel.org>2018-11-12 21:39:23 -0600
commit6b0e4625da2c53a1e3fdb4857fc7c6ba6ce562cf (patch)
tree5d115273784eb021e5550539e39f552672921329
parent7429fcb5a96aa10bbe86da08bd0b30c9292efdde (diff)
downloadpyramid-6b0e4625da2c53a1e3fdb4857fc7c6ba6ce562cf.tar.gz
pyramid-6b0e4625da2c53a1e3fdb4857fc7c6ba6ce562cf.tar.bz2
pyramid-6b0e4625da2c53a1e3fdb4857fc7c6ba6ce562cf.zip
initial work to remove py2 from the codebase
-rw-r--r--.travis.yml6
-rw-r--r--appveyor.yml2
-rw-r--r--setup.py9
-rw-r--r--src/pyramid/compat.py302
-rw-r--r--src/pyramid/i18n.py15
-rw-r--r--src/pyramid/interfaces.py15
-rw-r--r--src/pyramid/request.py4
-rw-r--r--src/pyramid/scripts/pserve.py23
-rw-r--r--src/pyramid/session.py8
-rw-r--r--src/pyramid/testing.py4
-rw-r--r--src/pyramid/traversal.py61
-rw-r--r--src/pyramid/urldispatch.py12
-rw-r--r--src/pyramid/util.py13
-rw-r--r--tests/test_config/test_adapters.py6
-rw-r--r--tests/test_config/test_factories.py7
-rw-r--r--tests/test_config/test_init.py3
-rw-r--r--tests/test_path.py6
-rw-r--r--tests/test_request.py7
-rw-r--r--tests/test_session.py8
-rw-r--r--tests/test_traversal.py7
-rw-r--r--tests/test_urldispatch.py7
-rw-r--r--tests/test_util.py27
-rw-r--r--tox.ini24
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'
diff --git a/setup.py b/setup.py
index 0143764b8..b63f4c182 100644
--- a/setup.py
+++ b/setup.py
@@ -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)
diff --git a/tox.ini b/tox.ini
index 5bf19d2a7..0dae17e0f 100644
--- a/tox.ini
+++ b/tox.ini
@@ -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