diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cede8bec..6881550b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,6 +7,7 @@ jobs: linux: runs-on: ${{ matrix.PYTHON.OS || 'ubuntu-22.04' }} strategy: + fail-fast: false matrix: PYTHON: # Base builds @@ -66,6 +67,7 @@ jobs: runs-on: ubuntu-latest container: ghcr.io/pyca/cryptography-runner-${{ matrix.TEST.CONTAINER }} strategy: + fail-fast: false matrix: TEST: # cryptographyMain used since there's no wheel diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 76d32c20..4901612a 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,7 +4,7 @@ Changelog Versions are year-based with a strict backward-compatibility policy. The third digit is only for regressions. -24.3.0 (UNRELEASED) +24.3.0 (2024-11-27) ------------------- Backward-incompatible changes: @@ -25,6 +25,7 @@ Deprecations: Changes: ^^^^^^^^ +* ``cryptography`` maximum version has been increased to 44.0.x. * ``OpenSSL.SSL.Connection.get_certificate``, ``OpenSSL.SSL.Connection.get_peer_certificate``, ``OpenSSL.SSL.Connection.get_peer_cert_chain``, and ``OpenSSL.SSL.Connection.get_verified_chain`` now take an ``as_cryptography`` keyword-argument. When ``True`` is passed then ``cryptography.x509.Certificate`` are returned, instead of ``OpenSSL.crypto.X509``. In the future, passing ``False`` (the default) will be deprecated. diff --git a/pyproject.toml b/pyproject.toml index e90fcd2b..1a45df95 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,6 +42,8 @@ testpaths = ["tests"] [tool.ruff] lint.select = ['E', 'F', 'I', 'W', 'UP', 'RUF'] line-length = 79 +# Remove if/when we move setup.py python-requires metadata to pyproject.toml +target-version = "py37" [tool.ruff.lint.isort] known-first-party = ["OpenSSL", "tests"] diff --git a/setup.py b/setup.py index 37c0fa26..fa546359 100644 --- a/setup.py +++ b/setup.py @@ -94,7 +94,7 @@ def find_meta(meta): packages=find_packages(where="src"), package_dir={"": "src"}, install_requires=[ - "cryptography>=41.0.5,<44", + "cryptography>=41.0.5,<45", ], extras_require={ "test": ["pytest-rerunfailures", "pretend", "pytest>=3.0.1"], diff --git a/src/OpenSSL/SSL.py b/src/OpenSSL/SSL.py index a7da79f4..eed27a03 100644 --- a/src/OpenSSL/SSL.py +++ b/src/OpenSSL/SSL.py @@ -4,11 +4,12 @@ import socket import typing import warnings +from collections.abc import Sequence from errno import errorcode from functools import partial, wraps from itertools import chain, count from sys import platform -from typing import Any, Callable, List, Optional, Sequence, TypeVar +from typing import Any, Callable, Optional, TypeVar from weakref import WeakValueDictionary from cryptography import x509 @@ -288,7 +289,7 @@ class _NoOverlappingProtocols: _ALPNSelectCallback = Callable[ [ "Connection", - typing.Union[List[bytes], _NoOverlappingProtocols], + typing.Union[typing.List[bytes], _NoOverlappingProtocols], ], None, ] @@ -766,7 +767,7 @@ def _asFileDescriptor(obj: Any) -> int: raise TypeError("argument must be an int, or have a fileno() method.") elif fd < 0: raise ValueError( - "file descriptor cannot be a negative integer (%i)" % (fd,) + f"file descriptor cannot be a negative integer ({fd:i})" ) return fd @@ -1952,18 +1953,16 @@ def _raise_ssl_error(self, ssl: Any, result: int) -> None: # TODO: This is untested. raise WantX509LookupError() elif error == _lib.SSL_ERROR_SYSCALL: - if _lib.ERR_peek_error() == 0: - if result < 0: - if platform == "win32": - errno = _ffi.getwinerror()[0] - else: - errno = _ffi.errno - - if errno != 0: - raise SysCallError(errno, errorcode.get(errno)) + if platform == "win32": + errno = _ffi.getwinerror()[0] + else: + errno = _ffi.errno + if _lib.ERR_peek_error() == 0 or errno != 0: + if result < 0 and errno != 0: + raise SysCallError(errno, errorcode.get(errno)) raise SysCallError(-1, "Unexpected EOF") else: - # TODO: This is untested. + # TODO: This is untested, but I think twisted hits it? _raise_current_error() elif error == _lib.SSL_ERROR_SSL and _lib.ERR_peek_error() != 0: # In 3.0.x an unexpected EOF no longer triggers syscall error diff --git a/src/OpenSSL/_util.py b/src/OpenSSL/_util.py index 7a102e6c..046e40c0 100644 --- a/src/OpenSSL/_util.py +++ b/src/OpenSSL/_util.py @@ -1,7 +1,9 @@ +from __future__ import annotations + import os import sys import warnings -from typing import Any, Callable, NoReturn, Type, Union +from typing import Any, Callable, NoReturn, Union from cryptography.hazmat.bindings.openssl.binding import Binding @@ -31,7 +33,7 @@ def text(charp: Any) -> str: return ffi.string(charp).decode("utf-8") -def exception_from_error_queue(exception_type: Type[Exception]) -> NoReturn: +def exception_from_error_queue(exception_type: type[Exception]) -> NoReturn: """ Convert an OpenSSL library failure into a Python exception. @@ -57,7 +59,7 @@ def exception_from_error_queue(exception_type: Type[Exception]) -> NoReturn: raise exception_type(errors) -def make_assert(error: Type[Exception]) -> Callable[[bool], Any]: +def make_assert(error: type[Exception]) -> Callable[[bool], Any]: """ Create an assert function that uses :func:`exception_from_error_queue` to raise an exception wrapped by *error*. diff --git a/src/OpenSSL/crypto.py b/src/OpenSSL/crypto.py index d3beb8ed..448a19a7 100644 --- a/src/OpenSSL/crypto.py +++ b/src/OpenSSL/crypto.py @@ -6,13 +6,12 @@ import typing import warnings from base64 import b16encode +from collections.abc import Iterable, Sequence from functools import partial from os import PathLike from typing import ( Any, Callable, - Iterable, - Sequence, Union, ) diff --git a/src/OpenSSL/version.py b/src/OpenSSL/version.py index 0cfb0653..9c802344 100644 --- a/src/OpenSSL/version.py +++ b/src/OpenSSL/version.py @@ -17,7 +17,7 @@ "__version__", ] -__version__ = "24.2.1" +__version__ = "24.3.0" __title__ = "pyOpenSSL" __uri__ = "https://pyopenssl.org/" diff --git a/tests/test_ssl.py b/tests/test_ssl.py index b009cd6f..ba3fa336 100644 --- a/tests/test_ssl.py +++ b/tests/test_ssl.py @@ -3832,7 +3832,10 @@ def test_unexpected_EOF(self): if platform == "win32": assert err.value.args == (10054, "WSAECONNRESET") else: - assert err.value.args == (-1, "Unexpected EOF") + assert err.value.args in [ + (-1, "Unexpected EOF"), + (54, "ECONNRESET"), + ] def _check_client_ca_list(self, func): """