From 26308dfa311d850a32c3f96abeef7bf9e1d19f5a Mon Sep 17 00:00:00 2001 From: Miguel Grinberg Date: Fri, 17 Oct 2025 15:50:19 +0100 Subject: [PATCH] Add Python 3.14, drop 3.8 and 3.9 (#264) * Add Python 3.14, drop 3.8 and 3.9 * reformat code * disable ssl deprecation for min-deps test (cherry picked from commit 7e0404064e9f69c0b6b95256db168ad814084c9b) --- .github/workflows/ci.yml | 4 ++-- noxfile.py | 8 ++++---- setup.py | 5 ++--- tests/async_/test_async_transport.py | 7 ++++--- tests/test_httpserver.py | 12 ++++++++++++ tests/test_transport.py | 7 ++++--- 6 files changed, 28 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e4e679e8..807e063d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,12 +43,12 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] os: ["ubuntu-latest"] experimental: [false] nox-session: [''] include: - - python-version: "3.8" + - python-version: "3.10" os: "ubuntu-latest" experimental: false nox-session: "test-min-deps" diff --git a/noxfile.py b/noxfile.py index 141cae4b..e0281e6b 100644 --- a/noxfile.py +++ b/noxfile.py @@ -30,7 +30,7 @@ @nox.session() def format(session): session.install("black~=24.0", "isort", "pyupgrade") - session.run("black", "--target-version=py37", *SOURCE_FILES) + session.run("black", "--target-version=py310", *SOURCE_FILES) session.run("isort", *SOURCE_FILES) session.run("python", "utils/license-headers.py", "fix", *SOURCE_FILES) @@ -52,14 +52,14 @@ def lint(session): "python", "-m", "pip", "uninstall", "--yes", "types-urllib3", silent=True ) session.install(".[develop]") - session.run("black", "--check", "--target-version=py37", *SOURCE_FILES) + session.run("black", "--check", "--target-version=py310", *SOURCE_FILES) session.run("isort", "--check", *SOURCE_FILES) session.run("flake8", "--ignore=E501,W503,E203,E704", *SOURCE_FILES) session.run("python", "utils/license-headers.py", "check", *SOURCE_FILES) session.run("mypy", "--strict", "--show-error-codes", "elastic_transport/") -@nox.session(python=["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]) +@nox.session(python=["3.10", "3.11", "3.12", "3.13", "3.14"]) def test(session): session.install(".[develop]") session.run( @@ -71,7 +71,7 @@ def test(session): session.run("coverage", "report", "-m") -@nox.session(name="test-min-deps", python="3.8") +@nox.session(name="test-min-deps", python="3.10") def test_min_deps(session): session.install("-r", "requirements-min.txt", ".[develop]", silent=False) session.run( diff --git a/setup.py b/setup.py index 21832718..102e530c 100644 --- a/setup.py +++ b/setup.py @@ -53,7 +53,7 @@ "urllib3>=1.26.2, <3", "certifi", ], - python_requires=">=3.8", + python_requires=">=3.10", extras_require={ "develop": [ "pytest", @@ -83,12 +83,11 @@ "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", ], diff --git a/tests/async_/test_async_transport.py b/tests/async_/test_async_transport.py index 24a869ce..835e4ec0 100644 --- a/tests/async_/test_async_transport.py +++ b/tests/async_/test_async_transport.py @@ -295,9 +295,10 @@ async def test_mark_dead_error_doesnt_raise(): randomize_nodes_in_pool=False, ) bad_node = t.node_pool._all_nodes[NodeConfig("http", "localhost", 80)] - with mock.patch.object(t.node_pool, "mark_dead") as mark_dead, mock.patch.object( - t, "sniff" - ) as sniff: + with ( + mock.patch.object(t.node_pool, "mark_dead") as mark_dead, + mock.patch.object(t, "sniff") as sniff, + ): sniff.side_effect = TransportError("sniffing error!") await t.perform_request("GET", "/") mark_dead.assert_called_with(bad_node) diff --git a/tests/test_httpserver.py b/tests/test_httpserver.py index e7f7f766..4c956afc 100644 --- a/tests/test_httpserver.py +++ b/tests/test_httpserver.py @@ -18,14 +18,26 @@ import warnings import pytest +import requests +import urllib3 from elastic_transport import Transport @pytest.mark.parametrize("node_class", ["urllib3", "requests"]) def test_simple_request(node_class, https_server_ip_node_config): + # when testing minimum urllib3 and requests dependencies, we disable + # the deprecation warning for ssl.match_hostname() + silence_ssl_deprecation = ( + node_class == "urllib3" and urllib3.__version__ == "1.26.2" + ) or (node_class == "requests" and requests.__version__ == "2.26.0") + with warnings.catch_warnings(): warnings.simplefilter("error") + if silence_ssl_deprecation: + warnings.filterwarnings( + "ignore", ".*match_hostname.*deprecated", DeprecationWarning + ) t = Transport([https_server_ip_node_config], node_class=node_class) diff --git a/tests/test_transport.py b/tests/test_transport.py index 08d8e04f..335f50b5 100644 --- a/tests/test_transport.py +++ b/tests/test_transport.py @@ -309,9 +309,10 @@ def test_sniff_on_node_failure_error_doesnt_raise(): randomize_nodes_in_pool=False, ) bad_node = t.node_pool._all_nodes[NodeConfig("http", "localhost", 80)] - with mock.patch.object(t, "sniff") as sniff, mock.patch.object( - t.node_pool, "mark_dead" - ) as mark_dead: + with ( + mock.patch.object(t, "sniff") as sniff, + mock.patch.object(t.node_pool, "mark_dead") as mark_dead, + ): sniff.side_effect = TransportError("sniffing error!") t.perform_request("GET", "/") mark_dead.assert_called_with(bad_node)