summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml5
-rw-r--r--CHANGELOG.rst3
-rwxr-xr-xsetup.py7
-rw-r--r--src/OpenSSL/SSL.py36
-rw-r--r--src/OpenSSL/_util.py32
-rw-r--r--src/OpenSSL/crypto.py44
-rw-r--r--tests/test_ssl.py50
-rw-r--r--tests/util.py7
8 files changed, 58 insertions, 126 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 08d8ae1..e5e2e6a 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -10,12 +10,10 @@ jobs:
matrix:
PYTHON:
# Base builds
- - {VERSION: "2.7", TOXENV: "py27"}
- {VERSION: "3.6", TOXENV: "py36"}
- {VERSION: "3.7", TOXENV: "py37"}
- {VERSION: "3.8", TOXENV: "py38"}
- {VERSION: "3.9", TOXENV: "py39"}
- - {VERSION: "pypy2", TOXENV: "pypy"}
- {VERSION: "pypy3", TOXENV: "pypy3"}
# -cryptographyMain
- {VERSION: "3.6", TOXENV: "py36-cryptographyMain"}
@@ -24,15 +22,12 @@ jobs:
- {VERSION: "3.9", TOXENV: "py39-cryptographyMain"}
- {VERSION: "pypy3", TOXENV: "pypy3-cryptographyMain"}
# -cryptographyMinimum
- - {VERSION: "2.7", TOXENV: "py27-cryptographyMinimum"}
- {VERSION: "3.6", TOXENV: "py36-cryptographyMinimum"}
- {VERSION: "3.7", TOXENV: "py37-cryptographyMinimum"}
- {VERSION: "3.8", TOXENV: "py38-cryptographyMinimum"}
- {VERSION: "3.9", TOXENV: "py39-cryptographyMinimum"}
- - {VERSION: "pypy2", TOXENV: "pypy-cryptographyMinimum"}
- {VERSION: "pypy3", TOXENV: "pypy3-cryptographyMinimum"}
# Random order
- - {VERSION: "2.7", TOXENV: "py27-randomorder"}
- {VERSION: "3.9", TOXENV: "py39-randomorder"}
# Downstreams
- {VERSION: "3.7", TOXENV: "py37-twistedTrunk"}
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 9ffeeb7..853e576 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -10,6 +10,9 @@ The third digit is only for regressions.
Backward-incompatible changes:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+- Drop support for Python 2.7.
+ `#1047 <https://github.com/pyca/pyopenssl/pull/1047>`_
+
Deprecations:
^^^^^^^^^^^^^
diff --git a/setup.py b/setup.py
index 1ca7b11..b9cd5bf 100755
--- a/setup.py
+++ b/setup.py
@@ -76,8 +76,6 @@ if __name__ == "__main__":
"Operating System :: MacOS :: MacOS X",
"Operating System :: Microsoft :: Windows",
"Operating System :: POSIX",
- "Programming Language :: Python :: 2",
- "Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
@@ -89,15 +87,12 @@ if __name__ == "__main__":
"Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: System :: Networking",
],
- python_requires=(
- ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*"
- ),
+ python_requires=(">=3.6"),
packages=find_packages(where="src"),
package_dir={"": "src"},
install_requires=[
# Fix cryptographyMinimum in tox.ini when changing this!
"cryptography>=3.3",
- "six>=1.5.2",
],
extras_require={
"test": ["flaky", "pretend", "pytest>=3.0.1"],
diff --git a/src/OpenSSL/SSL.py b/src/OpenSSL/SSL.py
index e71b044..59f21ce 100644
--- a/src/OpenSSL/SSL.py
+++ b/src/OpenSSL/SSL.py
@@ -6,8 +6,6 @@ from itertools import count, chain
from weakref import WeakValueDictionary
from errno import errorcode
-from six import integer_types, int2byte, indexbytes
-
from OpenSSL._util import (
UNSPECIFIED as _UNSPECIFIED,
exception_from_error_queue as _exception_from_error_queue,
@@ -381,7 +379,7 @@ class _ALPNSelectHelper(_CallbackExceptionHelper):
instr = _ffi.buffer(in_, inlen)[:]
protolist = []
while instr:
- encoded_len = indexbytes(instr, 0)
+ encoded_len = instr[0]
proto = instr[1 : encoded_len + 1]
protolist.append(proto)
instr = instr[encoded_len + 1 :]
@@ -551,15 +549,15 @@ class _OCSPClientCallbackHelper(_CallbackExceptionHelper):
def _asFileDescriptor(obj):
fd = None
- if not isinstance(obj, integer_types):
+ if not isinstance(obj, int):
meth = getattr(obj, "fileno", None)
if meth is not None:
obj = meth()
- if isinstance(obj, integer_types):
+ if isinstance(obj, int):
fd = obj
- if not isinstance(fd, integer_types):
+ if not isinstance(fd, int):
raise TypeError("argument must be an int, or have a fileno() method.")
elif fd < 0:
raise ValueError(
@@ -653,7 +651,7 @@ class Context(object):
)
def __init__(self, method):
- if not isinstance(method, integer_types):
+ if not isinstance(method, int):
raise TypeError("method must be an integer")
try:
@@ -897,7 +895,7 @@ class Context(object):
:return: None
"""
certfile = _path_string(certfile)
- if not isinstance(filetype, integer_types):
+ if not isinstance(filetype, int):
raise TypeError("filetype must be an integer")
use_result = _lib.SSL_CTX_use_certificate_file(
@@ -958,7 +956,7 @@ class Context(object):
if filetype is _UNSPECIFIED:
filetype = FILETYPE_PEM
- elif not isinstance(filetype, integer_types):
+ elif not isinstance(filetype, int):
raise TypeError("filetype must be an integer")
use_result = _lib.SSL_CTX_use_PrivateKey_file(
@@ -1035,7 +1033,7 @@ class Context(object):
.. versionadded:: 0.14
"""
- if not isinstance(mode, integer_types):
+ if not isinstance(mode, int):
raise TypeError("mode must be an integer")
return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
@@ -1070,7 +1068,7 @@ class Context(object):
See SSL_CTX_set_verify(3SSL) for further details.
"""
- if not isinstance(mode, integer_types):
+ if not isinstance(mode, int):
raise TypeError("mode must be an integer")
if callback is None:
@@ -1093,7 +1091,7 @@ class Context(object):
:param depth: An integer specifying the verify depth
:return: None
"""
- if not isinstance(depth, integer_types):
+ if not isinstance(depth, int):
raise TypeError("depth must be an integer")
_lib.SSL_CTX_set_verify_depth(self._context, depth)
@@ -1253,7 +1251,7 @@ class Context(object):
:param timeout: The timeout in (whole) seconds
:return: The previous session timeout
"""
- if not isinstance(timeout, integer_types):
+ if not isinstance(timeout, int):
raise TypeError("timeout must be an integer")
return _lib.SSL_CTX_set_timeout(self._context, timeout)
@@ -1356,7 +1354,7 @@ class Context(object):
:param options: The options to add.
:return: The new option bitmask.
"""
- if not isinstance(options, integer_types):
+ if not isinstance(options, int):
raise TypeError("options must be an integer")
return _lib.SSL_CTX_set_options(self._context, options)
@@ -1369,7 +1367,7 @@ class Context(object):
:param mode: The mode to add.
:return: The new mode bitmask.
"""
- if not isinstance(mode, integer_types):
+ if not isinstance(mode, int):
raise TypeError("mode must be an integer")
return _lib.SSL_CTX_set_mode(self._context, mode)
@@ -1426,7 +1424,7 @@ class Context(object):
# Take the list of protocols and join them together, prefixing them
# with their lengths.
protostr = b"".join(
- chain.from_iterable((int2byte(len(p)), p) for p in protos)
+ chain.from_iterable((bytes((len(p),)), p) for p in protos)
)
# Build a C string from the list. We don't need to save this off
@@ -1839,7 +1837,7 @@ class Connection(object):
if self._from_ssl is None:
raise TypeError("Connection sock was not None")
- if not isinstance(bufsiz, integer_types):
+ if not isinstance(bufsiz, int):
raise TypeError("bufsiz must be an integer")
buf = _no_zero_allocator("char[]", bufsiz)
@@ -2070,7 +2068,7 @@ class Connection(object):
:param state: bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
:return: None
"""
- if not isinstance(state, integer_types):
+ if not isinstance(state, int):
raise TypeError("state must be an integer")
_lib.SSL_set_shutdown(self._ssl, state)
@@ -2454,7 +2452,7 @@ class Connection(object):
# Take the list of protocols and join them together, prefixing them
# with their lengths.
protostr = b"".join(
- chain.from_iterable((int2byte(len(p)), p) for p in protos)
+ chain.from_iterable((bytes((len(p),)), p) for p in protos)
)
# Build a C string from the list. We don't need to save this off
diff --git a/src/OpenSSL/_util.py b/src/OpenSSL/_util.py
index 53c0b9e..8235f5b 100644
--- a/src/OpenSSL/_util.py
+++ b/src/OpenSSL/_util.py
@@ -1,8 +1,6 @@
import sys
import warnings
-from six import PY2, text_type
-
from cryptography.hazmat.bindings.openssl.binding import Binding
@@ -83,14 +81,10 @@ def native(s):
:raise TypeError: The input is neither :py:class:`bytes` nor
:py:class:`unicode`.
"""
- if not isinstance(s, (bytes, text_type)):
+ if not isinstance(s, (bytes, str)):
raise TypeError("%r is neither bytes nor unicode" % s)
- if PY2:
- if isinstance(s, text_type):
- return s.encode("utf-8")
- else:
- if isinstance(s, bytes):
- return s.decode("utf-8")
+ if isinstance(s, bytes):
+ return s.decode("utf-8")
return s
@@ -105,31 +99,21 @@ def path_string(s):
"""
if isinstance(s, bytes):
return s
- elif isinstance(s, text_type):
+ elif isinstance(s, str):
return s.encode(sys.getfilesystemencoding())
else:
raise TypeError("Path must be represented as bytes or unicode string")
-if PY2:
-
- def byte_string(s):
- return s
-
-
-else:
-
- def byte_string(s):
- return s.encode("charmap")
+def byte_string(s):
+ return s.encode("charmap")
# A marker object to observe whether some optional arguments are passed any
# value or not.
UNSPECIFIED = object()
-_TEXT_WARNING = (
- text_type.__name__ + " for {0} is no longer accepted, use bytes"
-)
+_TEXT_WARNING = "str for {0} is no longer accepted, use bytes"
def text_to_bytes_and_warn(label, obj):
@@ -145,7 +129,7 @@ def text_to_bytes_and_warn(label, obj):
UTF-8 encoding of that text is returned. Otherwise, ``obj`` itself is
returned.
"""
- if isinstance(obj, text_type):
+ if isinstance(obj, str):
warnings.warn(
_TEXT_WARNING.format(label),
category=DeprecationWarning,
diff --git a/src/OpenSSL/crypto.py b/src/OpenSSL/crypto.py
index eda4af6..151d7d1 100644
--- a/src/OpenSSL/crypto.py
+++ b/src/OpenSSL/crypto.py
@@ -5,12 +5,6 @@ from base64 import b16encode
from functools import partial
from operator import __eq__, __ne__, __lt__, __le__, __gt__, __ge__
-from six import (
- integer_types as _integer_types,
- text_type as _text_type,
- PY2 as _PY2,
-)
-
from cryptography import utils, x509
from cryptography.hazmat.primitives.asymmetric import dsa, rsa
@@ -411,18 +405,16 @@ class _EllipticCurve(object):
_curves = None
- if not _PY2:
- # This only necessary on Python 3. Moreover, it is broken on Python 2.
- def __ne__(self, other):
- """
- Implement cooperation with the right-hand side argument of ``!=``.
+ def __ne__(self, other):
+ """
+ Implement cooperation with the right-hand side argument of ``!=``.
- Python 3 seems to have dropped this cooperation in this very narrow
- circumstance.
- """
- if isinstance(other, _EllipticCurve):
- return super(_EllipticCurve, self).__ne__(other)
- return NotImplemented
+ Python 3 seems to have dropped this cooperation in this very narrow
+ circumstance.
+ """
+ if isinstance(other, _EllipticCurve):
+ return super(_EllipticCurve, self).__ne__(other)
+ return NotImplemented
@classmethod
def _load_elliptic_curves(cls, lib):
@@ -602,7 +594,7 @@ class X509Name(object):
_lib.X509_NAME_ENTRY_free(ent)
break
- if isinstance(value, _text_type):
+ if isinstance(value, str):
value = value.encode("utf-8")
add_result = _lib.X509_NAME_add_entry_by_NID(
@@ -1304,7 +1296,7 @@ class X509(object):
:return: :py:data`None`
"""
- if not isinstance(serial, _integer_types):
+ if not isinstance(serial, int):
raise TypeError("serial must be an integer")
hex_serial = hex(serial)[2:]
@@ -1957,7 +1949,7 @@ def load_certificate(type, buffer):
:return: The X509 object
"""
- if isinstance(buffer, _text_type):
+ if isinstance(buffer, str):
buffer = buffer.encode("ascii")
bio = _new_mem_buf(buffer)
@@ -2883,7 +2875,7 @@ def load_publickey(type, buffer):
:return: The PKey object.
:rtype: :class:`PKey`
"""
- if isinstance(buffer, _text_type):
+ if isinstance(buffer, str):
buffer = buffer.encode("ascii")
bio = _new_mem_buf(buffer)
@@ -2919,7 +2911,7 @@ def load_privatekey(type, buffer, passphrase=None):
:return: The PKey object
"""
- if isinstance(buffer, _text_type):
+ if isinstance(buffer, str):
buffer = buffer.encode("ascii")
bio = _new_mem_buf(buffer)
@@ -2980,7 +2972,7 @@ def load_certificate_request(type, buffer):
:param buffer: The buffer the certificate request is stored in
:return: The X509Req object
"""
- if isinstance(buffer, _text_type):
+ if isinstance(buffer, str):
buffer = buffer.encode("ascii")
bio = _new_mem_buf(buffer)
@@ -3109,7 +3101,7 @@ def load_crl(type, buffer):
:return: The PKey object
"""
- if isinstance(buffer, _text_type):
+ if isinstance(buffer, str):
buffer = buffer.encode("ascii")
bio = _new_mem_buf(buffer)
@@ -3138,7 +3130,7 @@ def load_pkcs7_data(type, buffer):
:param buffer: The buffer with the pkcs7 data.
:return: The PKCS7 object
"""
- if isinstance(buffer, _text_type):
+ if isinstance(buffer, str):
buffer = buffer.encode("ascii")
bio = _new_mem_buf(buffer)
@@ -3183,7 +3175,7 @@ def load_pkcs12(buffer, passphrase=None):
"""
passphrase = _text_to_bytes_and_warn("passphrase", passphrase)
- if isinstance(buffer, _text_type):
+ if isinstance(buffer, str):
buffer = buffer.encode("ascii")
bio = _new_mem_buf(buffer)
diff --git a/tests/test_ssl.py b/tests/test_ssl.py
index e604164..ffc505d 100644
--- a/tests/test_ssl.py
+++ b/tests/test_ssl.py
@@ -32,8 +32,6 @@ import pytest
from pretend import raiser
-from six import PY2, text_type
-
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
@@ -166,9 +164,6 @@ i5s5yYK7a/0eWxxRr2qraYaUj8RwDpH9CwIBAg==
"""
-skip_if_py3 = pytest.mark.skipif(not PY2, reason="Python 2 only")
-
-
def socket_any_family():
try:
return socket(AF_INET)
@@ -197,7 +192,7 @@ def join_bytes_or_unicode(prefix, suffix):
return join(prefix, suffix)
# Otherwise, coerce suffix to the type of prefix.
- if isinstance(prefix, text_type):
+ if isinstance(prefix, str):
return join(prefix, suffix.decode(getfilesystemencoding()))
else:
return join(prefix, suffix.encode(getfilesystemencoding()))
@@ -1751,7 +1746,7 @@ class TestContext(object):
"""
context = Context(SSLv23_METHOD)
with pytest.raises(TypeError):
- context.set_tlsext_use_srtp(text_type("SRTP_AES128_CM_SHA1_80"))
+ context.set_tlsext_use_srtp(str("SRTP_AES128_CM_SHA1_80"))
def test_set_tlsext_use_srtp_invalid_profile(self):
"""
@@ -2285,10 +2280,8 @@ class TestConnection(object):
with pytest.raises(TypeError):
conn.set_tlsext_host_name(b"with\0null")
- if not PY2:
- # On Python 3.x, don't accidentally implicitly convert from text.
- with pytest.raises(TypeError):
- conn.set_tlsext_host_name(b"example.com".decode("ascii"))
+ with pytest.raises(TypeError):
+ conn.set_tlsext_host_name(b"example.com".decode("ascii"))
def test_pending(self):
"""
@@ -2858,8 +2851,8 @@ class TestConnection(object):
client.get_cipher_name(),
)
- assert isinstance(server_cipher_name, text_type)
- assert isinstance(client_cipher_name, text_type)
+ assert isinstance(server_cipher_name, str)
+ assert isinstance(client_cipher_name, str)
assert server_cipher_name == client_cipher_name
@@ -2883,8 +2876,8 @@ class TestConnection(object):
client.get_cipher_version(),
)
- assert isinstance(server_cipher_version, text_type)
- assert isinstance(client_cipher_version, text_type)
+ assert isinstance(server_cipher_version, str)
+ assert isinstance(client_cipher_version, str)
assert server_cipher_version == client_cipher_version
@@ -2922,8 +2915,8 @@ class TestConnection(object):
client_protocol_version_name = client.get_protocol_version_name()
server_protocol_version_name = server.get_protocol_version_name()
- assert isinstance(server_protocol_version_name, text_type)
- assert isinstance(client_protocol_version_name, text_type)
+ assert isinstance(server_protocol_version_name, str)
+ assert isinstance(client_protocol_version_name, str)
assert server_protocol_version_name == client_protocol_version_name
@@ -3066,18 +3059,6 @@ class TestConnectionSend(object):
assert count == 2
assert client.recv(2) == b"xy"
- @skip_if_py3
- def test_short_buffer(self):
- """
- When passed a buffer containing a small number of bytes,
- `Connection.send` transmits all of them and returns the number
- of bytes sent.
- """
- server, client = loopback()
- count = server.send(buffer(b"xy")) # noqa: F821
- assert count == 2
- assert client.recv(2) == b"xy"
-
@pytest.mark.skipif(
sys.maxsize < 2 ** 31,
reason="sys.maxsize < 2**31 - test requires 64 bit",
@@ -3273,17 +3254,6 @@ class TestConnectionSendall(object):
server.sendall(memoryview(b"x"))
assert client.recv(1) == b"x"
- @skip_if_py3
- def test_short_buffers(self):
- """
- When passed a buffer containing a small number of bytes,
- `Connection.sendall` transmits all of them.
- """
- server, client = loopback()
- count = server.sendall(buffer(b"xy")) # noqa: F821
- assert count == 2
- assert client.recv(2) == b"xy"
-
def test_long(self):
"""
`Connection.sendall` transmits all the bytes in the string passed to it
diff --git a/tests/util.py b/tests/util.py
index 75d2c8d..566146c 100644
--- a/tests/util.py
+++ b/tests/util.py
@@ -6,8 +6,6 @@ Helpers for the OpenSSL test suite, largely copied from
U{Twisted<http://twistedmatrix.com/>}.
"""
-from six import PY2
-
# This is the UTF-8 encoding of the SNOWMAN unicode code point.
NON_ASCII = b"\xe2\x98\x83".decode("utf-8")
@@ -154,7 +152,4 @@ class EqualityTestsMixin(object):
# The type name expected in warnings about using the wrong string type.
-if PY2:
- WARNING_TYPE_EXPECTED = "unicode"
-else:
- WARNING_TYPE_EXPECTED = "str"
+WARNING_TYPE_EXPECTED = "str"