diff --git a/.travis.yml b/.travis.yml index 6c43e4e2772..ee634279e35 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,8 +27,6 @@ matrix: env: TOXENV=py27-alldeps-withcov-posix,codecov-publish - python: 2.7 env: TOXENV=py27-nodeps-withcov-posix,codecov-publish - - python: 3.3 - env: TOXENV=py33-alldeps-withcov-posix,codecov-publish - python: 3.4 env: TOXENV=py34-alldeps-withcov-posix,codecov-publish - python: 3.5 diff --git a/NEWS.rst b/NEWS.rst index c6a01bdf83b..b2568bce73c 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -6,6 +6,9 @@ http://twistedmatrix.com/trac/ticket/ Twisted 17.9.0 (2017-09-23) =========================== +This is the last Twisted release where Python 3.3 is supported, on any +platform. + Features -------- diff --git a/src/twisted/__init__.py b/src/twisted/__init__.py index 720fec979da..ebff4c2301d 100644 --- a/src/twisted/__init__.py +++ b/src/twisted/__init__.py @@ -7,18 +7,6 @@ Twisted: The Framework Of Your Internet. """ -def _checkRequirements(): - # Don't allow the user to run a version of Python we don't support. - import sys - - version = getattr(sys, "version_info", (0,)) - if version < (2, 7): - raise ImportError("Twisted requires Python 2.7 or later.") - elif version >= (3, 0) and version < (3, 3): - raise ImportError("Twisted on Python 3 requires Python 3.3 or later.") - -_checkRequirements() - # setup version from twisted._version import __version__ as version __version__ = version.short() diff --git a/src/twisted/internet/abstract.py b/src/twisted/internet/abstract.py index 9e374f69133..4b560dc4e6b 100644 --- a/src/twisted/internet/abstract.py +++ b/src/twisted/internet/abstract.py @@ -17,18 +17,11 @@ from twisted.python import reflect, failure from twisted.internet import interfaces, main -import sys - if _PY3: - if (sys.version_info.major, sys.version_info.minor) == (3, 3): - # Python 3.3 cannot join bytes and memoryviews - def _concatenate(bObj, offset, bArray): - return bObj[offset:] + b"".join(bArray) - else: - # Python 3.4+ can join bytes and memoryviews; using a - # memoryview prevents the slice from copying - def _concatenate(bObj, offset, bArray): - return b''.join([memoryview(bObj)[offset:]] + bArray) + # Python 3.4+ can join bytes and memoryviews; using a + # memoryview prevents the slice from copying + def _concatenate(bObj, offset, bArray): + return b''.join([memoryview(bObj)[offset:]] + bArray) else: from __builtin__ import buffer diff --git a/src/twisted/newsfragments/9352.removal b/src/twisted/newsfragments/9352.removal new file mode 100644 index 00000000000..8a266065981 --- /dev/null +++ b/src/twisted/newsfragments/9352.removal @@ -0,0 +1 @@ +Python 3.3 is no longer supported. diff --git a/src/twisted/python/_setup.py b/src/twisted/python/_setup.py index 1fdc64b9ff7..6f62d445a9e 100644 --- a/src/twisted/python/_setup.py +++ b/src/twisted/python/_setup.py @@ -65,7 +65,6 @@ classifiers=[ "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", @@ -198,11 +197,26 @@ def __init__(self, *args, **kwargs): +def _checkPythonVersion(): + """ + Fail if we detect a version of Python we don't support. + """ + version = getattr(sys, "version_info", (0,)) + if version < (2, 7): + raise ImportError("Twisted requires Python 2.7 or later.") + elif version >= (3, 0) and version < (3, 4): + raise ImportError("Twisted on Python 3 requires Python 3.4 or later.") + + + def getSetupArgs(extensions=_EXTENSIONS): """ + @return: The keyword arguments to be used the the setup method. @rtype: L{dict} """ + _checkPythonVersion() + arguments = STATIC_PACKAGE_METADATA.copy() # This is a workaround for distutils behavior; ext_modules isn't @@ -341,8 +355,8 @@ def _check_header(self, header_name): Check if the given header can be included by trying to compile a file that contains only an #include line. """ - self.compiler.announce("checking for %s ..." % header_name, 0) - return self._compile_helper("#include <%s>\n" % header_name) + self.compiler.announce("checking for {} ...".format(header_name), 0) + return self._compile_helper("#include <{}>\n".format(header_name)) diff --git a/src/twisted/test/test_twisted.py b/src/twisted/test/test_twisted.py index e2c7cbc859e..b68e7b22368 100644 --- a/src/twisted/test/test_twisted.py +++ b/src/twisted/test/test_twisted.py @@ -13,7 +13,7 @@ from types import ModuleType -from twisted import _checkRequirements +from twisted.python._setup import _checkPythonVersion from twisted.python.compat import _PY3 from twisted.python import reflect from twisted.trial.unittest import TestCase @@ -160,8 +160,8 @@ class RequirementsTests(TestCase): """ unsupportedPythonVersion = (2, 6) supportedPythonVersion = (2, 7) - Py3unsupportedPythonVersion = (3, 2) - Py3supportedPythonVersion = (3, 3) + Py3unsupportedPythonVersion = (3, 3) + Py3supportedPythonVersion = (3, 4) def setUp(self): @@ -181,12 +181,12 @@ def tearDown(self): def test_oldPython(self): """ - L{_checkRequirements} raises L{ImportError} when run on a version of + L{_checkPythonVersion} raises L{ImportError} when run on a version of Python that is too old. """ sys.version_info = self.unsupportedPythonVersion with self.assertRaises(ImportError) as raised: - _checkRequirements() + _checkPythonVersion() self.assertEqual("Twisted requires Python %d.%d or later." % self.supportedPythonVersion, str(raised.exception)) @@ -194,21 +194,21 @@ def test_oldPython(self): def test_newPython(self): """ - L{_checkRequirements} returns L{None} when run on a version of Python + L{_checkPythonVersion} returns L{None} when run on a version of Python that is sufficiently new. """ sys.version_info = self.supportedPythonVersion - self.assertIsNone(_checkRequirements()) + self.assertIsNone(_checkPythonVersion()) def test_oldPythonPy3(self): """ - L{_checkRequirements} raises L{ImportError} when run on a version of + L{_checkPythonVersion} raises L{ImportError} when run on a version of Python that is too old. """ sys.version_info = self.Py3unsupportedPythonVersion with self.assertRaises(ImportError) as raised: - _checkRequirements() + _checkPythonVersion() self.assertEqual("Twisted on Python 3 requires Python %d.%d or later." % self.Py3supportedPythonVersion, str(raised.exception)) @@ -216,11 +216,11 @@ def test_oldPythonPy3(self): def test_newPythonPy3(self): """ - L{_checkRequirements} returns L{None} when run on a version of Python + L{_checkPythonVersion} returns L{None} when run on a version of Python that is sufficiently new. """ sys.version_info = self.Py3supportedPythonVersion - self.assertIsNone(_checkRequirements()) + self.assertIsNone(_checkPythonVersion())