From 465494e94515268f7b728cb8c8f35fb5aeb48f66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20K=C5=82oczko?= Date: Fri, 17 May 2024 10:26:13 +0000 Subject: [PATCH 1/5] drop python<=3.7 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to https://endoflife.date/python 3.7 has been EOSed almost year ag. Filter all code over `pyupgrade --py38-plus`. Signed-off-by: Tomasz Kłoczko --- docs/sphinx/conf.py | 1 - elasticsearch/_otel.py | 2 +- examples/bulk-ingest/bulk-ingest.py | 2 +- setup.py | 1 - .../test_async/test_server/test_clients.py | 2 -- .../test_async/test_server/test_helpers.py | 18 +++++++++--------- .../test_server/test_rest_api_spec.py | 4 ++-- .../test_async/test_transport.py | 4 +--- test_elasticsearch/test_client/test_options.py | 1 - .../test_client/test_overrides.py | 1 - test_elasticsearch/test_client/test_utils.py | 2 -- test_elasticsearch/test_helpers.py | 3 +-- test_elasticsearch/test_serializer.py | 1 - test_elasticsearch/test_server/test_clients.py | 1 - test_elasticsearch/test_server/test_helpers.py | 6 +++--- .../test_server/test_rest_api_spec.py | 6 +++--- test_elasticsearch/test_transport.py | 3 +-- utils/build-dists.py | 2 +- utils/bump-version.py | 2 +- utils/license-headers.py | 4 ++-- 20 files changed, 26 insertions(+), 40 deletions(-) diff --git a/docs/sphinx/conf.py b/docs/sphinx/conf.py index e6fe394ec..d7c3f7751 100644 --- a/docs/sphinx/conf.py +++ b/docs/sphinx/conf.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright diff --git a/elasticsearch/_otel.py b/elasticsearch/_otel.py index 9264569b3..10f2b3079 100644 --- a/elasticsearch/_otel.py +++ b/elasticsearch/_otel.py @@ -49,7 +49,7 @@ def __init__( enabled: bool | None = None, tracer: trace.Tracer | None = None, # TODO import Literal at the top-level when dropping Python 3.7 - body_strategy: 'Literal["omit", "raw"]' | None = None, + body_strategy: Literal["omit", "raw"] | None = None, ): if enabled is None: enabled = os.environ.get(ENABLED_ENV_VAR, "true") == "true" diff --git a/examples/bulk-ingest/bulk-ingest.py b/examples/bulk-ingest/bulk-ingest.py index 4c5c34c86..e1619ecde 100644 --- a/examples/bulk-ingest/bulk-ingest.py +++ b/examples/bulk-ingest/bulk-ingest.py @@ -66,7 +66,7 @@ def generate_actions(): yields a single document. This function is passed into the bulk() helper to create many documents in sequence. """ - with open(DATASET_PATH, mode="r") as f: + with open(DATASET_PATH) as f: reader = csv.DictReader(f) for row in reader: diff --git a/setup.py b/setup.py index e9ee3a377..fb465c1fe 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright diff --git a/test_elasticsearch/test_async/test_server/test_clients.py b/test_elasticsearch/test_async/test_server/test_clients.py index 8ae5726c1..00de2c7fb 100644 --- a/test_elasticsearch/test_async/test_server/test_clients.py +++ b/test_elasticsearch/test_async/test_server/test_clients.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright @@ -16,7 +15,6 @@ # specific language governing permissions and limitations # under the License. -from __future__ import unicode_literals import pytest diff --git a/test_elasticsearch/test_async/test_server/test_helpers.py b/test_elasticsearch/test_async/test_server/test_helpers.py index 5d5ce3d17..225d74740 100644 --- a/test_elasticsearch/test_async/test_server/test_helpers.py +++ b/test_elasticsearch/test_async/test_server/test_helpers.py @@ -33,13 +33,13 @@ class AsyncMock(MagicMock): async def __call__(self, *args, **kwargs): - return super(AsyncMock, self).__call__(*args, **kwargs) + return super().__call__(*args, **kwargs) def __await__(self): return self().__await__() -class FailingBulkClient(object): +class FailingBulkClient: def __init__( self, client, @@ -68,7 +68,7 @@ def options(self, **_): return self -class TestStreamingBulk(object): +class TestStreamingBulk: async def test_actions_remain_unchanged(self, async_client): actions = [{"_id": 1}, {"_id": 2}] async for ok, item in helpers.async_streaming_bulk( @@ -295,7 +295,7 @@ async def streaming_bulk(): assert 4 == failing_client._called -class TestBulk(object): +class TestBulk: async def test_bulk_works_with_single_item(self, async_client): docs = [{"answer": 42, "_id": 1}] success, failed = await helpers.async_bulk( @@ -466,7 +466,7 @@ async def scan_teardown(async_client): await async_client.clear_scroll(scroll_id="_all") -class TestScan(object): +class TestScan: async def test_order_can_be_preserved(self, async_client, scan_teardown): bulk = [] for x in range(100): @@ -501,8 +501,8 @@ async def test_all_documents_are_read(self, async_client, scan_teardown): ] assert 100 == len(docs) - assert set(map(str, range(100))) == set(d["_id"] for d in docs) - assert set(range(100)) == set(d["_source"]["answer"] for d in docs) + assert set(map(str, range(100))) == {d["_id"] for d in docs} + assert set(range(100)) == {d["_source"]["answer"] for d in docs} async def test_scroll_error(self, async_client, scan_teardown): bulk = [] @@ -889,7 +889,7 @@ async def reindex_setup(async_client): yield -class TestReindex(object): +class TestReindex: async def test_reindex_passes_kwargs_to_scan_and_bulk( self, async_client, reindex_setup ): @@ -1039,7 +1039,7 @@ async def reindex_data_stream_setup(async_client): yield -class TestAsyncDataStreamReindex(object): +class TestAsyncDataStreamReindex: @pytest.mark.parametrize("op_type", [None, "create"]) async def test_reindex_index_datastream( self, op_type, async_client, reindex_data_stream_setup diff --git a/test_elasticsearch/test_async/test_server/test_rest_api_spec.py b/test_elasticsearch/test_async/test_server/test_rest_api_spec.py index fd4fd04e3..eee2364f6 100644 --- a/test_elasticsearch/test_async/test_server/test_rest_api_spec.py +++ b/test_elasticsearch/test_async/test_server/test_rest_api_spec.py @@ -228,9 +228,9 @@ async def _feature_enabled(self, name): if XPACK_FEATURES is None: try: xinfo = await self.client.xpack.info() - XPACK_FEATURES = set( + XPACK_FEATURES = { f for f in xinfo["features"] if xinfo["features"][f]["enabled"] - ) + } IMPLEMENTED_FEATURES.add("xpack") except RequestError: XPACK_FEATURES = set() diff --git a/test_elasticsearch/test_async/test_transport.py b/test_elasticsearch/test_async/test_transport.py index 4d34e23bc..c815193ee 100644 --- a/test_elasticsearch/test_async/test_transport.py +++ b/test_elasticsearch/test_async/test_transport.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright @@ -16,7 +15,6 @@ # specific language governing permissions and limitations # under the License. -from __future__ import unicode_literals import asyncio import re @@ -266,7 +264,7 @@ def test_kwargs_passed_on_to_node_pool(self): ) assert dt is client.transport.node_pool.dead_node_backoff_factor - class MyConnection(object): + class MyConnection: def __init__(self, *_, **__): pass diff --git a/test_elasticsearch/test_client/test_options.py b/test_elasticsearch/test_client/test_options.py index adf7a1d0d..b7fa3cfda 100644 --- a/test_elasticsearch/test_client/test_options.py +++ b/test_elasticsearch/test_client/test_options.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright diff --git a/test_elasticsearch/test_client/test_overrides.py b/test_elasticsearch/test_client/test_overrides.py index fd8ad9f65..28fa8708b 100644 --- a/test_elasticsearch/test_client/test_overrides.py +++ b/test_elasticsearch/test_client/test_overrides.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright diff --git a/test_elasticsearch/test_client/test_utils.py b/test_elasticsearch/test_client/test_utils.py index 3c245f397..e53145bfd 100644 --- a/test_elasticsearch/test_client/test_utils.py +++ b/test_elasticsearch/test_client/test_utils.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright @@ -16,7 +15,6 @@ # specific language governing permissions and limitations # under the License. -from __future__ import unicode_literals from elasticsearch._sync.client.utils import _quote diff --git a/test_elasticsearch/test_helpers.py b/test_elasticsearch/test_helpers.py index a8efb151c..c9284afc5 100644 --- a/test_elasticsearch/test_helpers.py +++ b/test_elasticsearch/test_helpers.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright @@ -75,7 +74,7 @@ def test_chunk_sent_from_different_threads(self, _process_bulk_chunk): chunk_size=2, ) ) - assert len(set([r[1] for r in results])) > 1 + assert len({r[1] for r in results}) > 1 class TestChunkActions: diff --git a/test_elasticsearch/test_serializer.py b/test_elasticsearch/test_serializer.py index 4f66ba9a2..ba5f1adec 100644 --- a/test_elasticsearch/test_serializer.py +++ b/test_elasticsearch/test_serializer.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright diff --git a/test_elasticsearch/test_server/test_clients.py b/test_elasticsearch/test_server/test_clients.py index e7c2a78e6..93720ed14 100644 --- a/test_elasticsearch/test_server/test_clients.py +++ b/test_elasticsearch/test_server/test_clients.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright diff --git a/test_elasticsearch/test_server/test_helpers.py b/test_elasticsearch/test_server/test_helpers.py index 0763be03c..9750b9e19 100644 --- a/test_elasticsearch/test_server/test_helpers.py +++ b/test_elasticsearch/test_server/test_helpers.py @@ -27,7 +27,7 @@ from elasticsearch.helpers import ScanError -class FailingBulkClient(object): +class FailingBulkClient: def __init__( self, client, @@ -471,8 +471,8 @@ def test_all_documents_are_read(sync_client): docs = list(helpers.scan(sync_client, index="test_index", size=2)) assert 100 == len(docs) - assert set(map(str, range(100))) == set(d["_id"] for d in docs) - assert set(range(100)) == set(d["_source"]["answer"] for d in docs) + assert set(map(str, range(100))) == {d["_id"] for d in docs} + assert set(range(100)) == {d["_source"]["answer"] for d in docs} @pytest.mark.usefixtures("scan_teardown") diff --git a/test_elasticsearch/test_server/test_rest_api_spec.py b/test_elasticsearch/test_server/test_rest_api_spec.py index e45625842..9abf85585 100644 --- a/test_elasticsearch/test_server/test_rest_api_spec.py +++ b/test_elasticsearch/test_server/test_rest_api_spec.py @@ -456,7 +456,7 @@ def _resolve(self, value): if isinstance(value, string_types): value = value.strip() elif isinstance(value, dict): - value = dict((k, self._resolve(v)) for (k, v) in value.items()) + value = {k: self._resolve(v) for (k, v) in value.items()} elif isinstance(value, list): value = list(map(self._resolve, value)) return value @@ -495,9 +495,9 @@ def _feature_enabled(self, name): if XPACK_FEATURES is None: try: xinfo = self.client.xpack.info() - XPACK_FEATURES = set( + XPACK_FEATURES = { f for f in xinfo["features"] if xinfo["features"][f]["enabled"] - ) + } IMPLEMENTED_FEATURES.add("xpack") except RequestError: XPACK_FEATURES = set() diff --git a/test_elasticsearch/test_transport.py b/test_elasticsearch/test_transport.py index b3b6de097..1f85a21e5 100644 --- a/test_elasticsearch/test_transport.py +++ b/test_elasticsearch/test_transport.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright @@ -297,7 +296,7 @@ def test_kwargs_passed_on_to_node_pool(self): assert dt is client.transport.node_pool.dead_node_backoff_factor def test_custom_node_class(self): - class MyConnection(object): + class MyConnection: def __init__(self, *_, **__): pass diff --git a/utils/build-dists.py b/utils/build-dists.py index b66869cad..dc1b370e4 100644 --- a/utils/build-dists.py +++ b/utils/build-dists.py @@ -50,7 +50,7 @@ def run(*argv, expect_exit_code=0): else: os.chdir(tmp_dir) - cmd = " ".join(shlex.quote(x) for x in argv) + cmd = shlex.join(argv) print("$ " + cmd) exit_code = os.system(cmd) if exit_code != expect_exit_code: diff --git a/utils/bump-version.py b/utils/bump-version.py index 821d92344..07507ea48 100644 --- a/utils/bump-version.py +++ b/utils/bump-version.py @@ -29,7 +29,7 @@ def find_and_replace(path, pattern, replace): # Does a find and replace within a file path and complains # if the given pattern isn't found in the file. - with open(path, "r") as f: + with open(path) as f: old_data = f.read() if re.search(pattern, old_data, flags=re.MULTILINE) is None: diff --git a/utils/license-headers.py b/utils/license-headers.py index b4fc7432b..4b7b978c5 100644 --- a/utils/license-headers.py +++ b/utils/license-headers.py @@ -66,7 +66,7 @@ def find_files_to_fix(sources: List[str]) -> Iterator[str]: def does_file_need_fix(filepath: str) -> bool: if not re.search(r"\.pyi?$", filepath): return False - with open(filepath, mode="r") as f: + with open(filepath) as f: first_license_line = None for line in f: if line == license_header_lines[0]: @@ -83,7 +83,7 @@ def does_file_need_fix(filepath: str) -> bool: def add_header_to_file(filepath: str) -> None: - with open(filepath, mode="r") as f: + with open(filepath) as f: lines = list(f) i = 0 for i, line in enumerate(lines): From eeb8402ffe51b81debc1e87dfb0dec0c150671f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20K=C5=82oczko?= Date: Fri, 17 May 2024 10:28:04 +0000 Subject: [PATCH 2/5] manuall updates for python>=3.8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomasz Kłoczko --- setup.py | 5 +---- test_elasticsearch/test_server/test_rest_api_spec.py | 3 +-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/setup.py b/setup.py index fb465c1fe..ddb5f4e6a 100644 --- a/setup.py +++ b/setup.py @@ -74,9 +74,6 @@ "License :: OSI Approved :: Apache Software License", "Intended Audience :: Developers", "Operating System :: OS Independent", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", @@ -85,7 +82,7 @@ "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", ], - python_requires=">=3.7", + python_requires=">=3.8", install_requires=["elastic-transport>=8.13,<9"], extras_require={ "requests": ["requests>=2.4.0, <3.0.0"], diff --git a/test_elasticsearch/test_server/test_rest_api_spec.py b/test_elasticsearch/test_server/test_rest_api_spec.py index 9abf85585..576f8ac8a 100644 --- a/test_elasticsearch/test_server/test_rest_api_spec.py +++ b/test_elasticsearch/test_server/test_rest_api_spec.py @@ -132,8 +132,7 @@ XPACK_FEATURES = None ES_VERSION = None RUN_ASYNC_REST_API_TESTS = ( - sys.version_info >= (3, 8) - and os.environ.get("PYTHON_CONNECTION_CLASS") == "requests" + os.environ.get("PYTHON_CONNECTION_CLASS") == "requests" ) FALSEY_VALUES = ("", None, False, 0, 0.0) From e35b08c84eb24be5ec6e98465cb8243029ace99c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20K=C5=82oczko?= Date: Fri, 17 May 2024 10:31:01 +0000 Subject: [PATCH 3/5] remove python 3.7 from CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomasz Kłoczko --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1b662f866..94c554900 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] nox-session: [""] runs-on: ["ubuntu-latest"] From 9b3e5cf343444edb5206a79f42a15ac22ea10a43 Mon Sep 17 00:00:00 2001 From: Quentin Pradet Date: Tue, 30 Jul 2024 14:33:36 +0200 Subject: [PATCH 4/5] Drop more Python 3.7 --- .buildkite/pipeline.yml | 3 +-- docs/guide/getting-started.asciidoc | 2 +- docs/sphinx/quickstart.rst | 2 +- elasticsearch/_otel.py | 6 +----- noxfile.py | 4 ++-- 5 files changed, 6 insertions(+), 11 deletions(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index f5e48c9eb..ff911719e 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -11,7 +11,6 @@ steps: matrix: setup: python: - - "3.7" - "3.8" - "3.9" - "3.10" @@ -24,7 +23,7 @@ steps: - "test" adjustments: - with: - python: "3.7" + python: "3.8" connection: "urllib3" nox_session: "test_otel" - with: diff --git a/docs/guide/getting-started.asciidoc b/docs/guide/getting-started.asciidoc index db0a8095b..1b964e50c 100644 --- a/docs/guide/getting-started.asciidoc +++ b/docs/guide/getting-started.asciidoc @@ -8,7 +8,7 @@ operations with it. [discrete] === Requirements -* https://www.python.org/[Python] 3.7 or newer +* https://www.python.org/[Python] 3.8 or newer * https://pip.pypa.io/en/stable/[`pip`], installed by default alongside Python [discrete] diff --git a/docs/sphinx/quickstart.rst b/docs/sphinx/quickstart.rst index 51938e921..563ea6f23 100644 --- a/docs/sphinx/quickstart.rst +++ b/docs/sphinx/quickstart.rst @@ -9,7 +9,7 @@ operations like indexing or searching documents. Requirements ------------ -- `Python `_ 3.7 or newer +- `Python `_ 3.8 or newer - `pip `_ diff --git a/elasticsearch/_otel.py b/elasticsearch/_otel.py index 10f2b3079..b73f17cc4 100644 --- a/elasticsearch/_otel.py +++ b/elasticsearch/_otel.py @@ -19,10 +19,7 @@ import contextlib import os -from typing import TYPE_CHECKING, Generator, Mapping - -if TYPE_CHECKING: - from typing import Literal +from typing import TYPE_CHECKING, Generator, Literal, Mapping try: from opentelemetry import trace @@ -48,7 +45,6 @@ def __init__( self, enabled: bool | None = None, tracer: trace.Tracer | None = None, - # TODO import Literal at the top-level when dropping Python 3.7 body_strategy: Literal["omit", "raw"] | None = None, ): if enabled is None: diff --git a/noxfile.py b/noxfile.py index 2c97b5679..69e53417f 100644 --- a/noxfile.py +++ b/noxfile.py @@ -45,14 +45,14 @@ def pytest_argv(): ] -@nox.session(python=["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]) +@nox.session(python=["3.8", "3.9", "3.10", "3.11", "3.12"]) def test(session): session.install(".[dev]", env=INSTALL_ENV, silent=False) session.run(*pytest_argv()) -@nox.session(python=["3.7", "3.12"]) +@nox.session(python=["3.8", "3.12"]) def test_otel(session): session.install( ".[dev]", From 875267d7e9a35e494a8c22d30be9f5bbac36cb30 Mon Sep 17 00:00:00 2001 From: Quentin Pradet Date: Tue, 30 Jul 2024 14:40:05 +0200 Subject: [PATCH 5/5] Fix lint --- elasticsearch/_otel.py | 2 +- test_elasticsearch/test_server/test_rest_api_spec.py | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/elasticsearch/_otel.py b/elasticsearch/_otel.py index b73f17cc4..039f7798b 100644 --- a/elasticsearch/_otel.py +++ b/elasticsearch/_otel.py @@ -19,7 +19,7 @@ import contextlib import os -from typing import TYPE_CHECKING, Generator, Literal, Mapping +from typing import Generator, Literal, Mapping try: from opentelemetry import trace diff --git a/test_elasticsearch/test_server/test_rest_api_spec.py b/test_elasticsearch/test_server/test_rest_api_spec.py index 576f8ac8a..6ede3b753 100644 --- a/test_elasticsearch/test_server/test_rest_api_spec.py +++ b/test_elasticsearch/test_server/test_rest_api_spec.py @@ -24,7 +24,6 @@ import json import os import re -import sys import warnings import zipfile from typing import Tuple, Union @@ -131,9 +130,7 @@ XPACK_FEATURES = None ES_VERSION = None -RUN_ASYNC_REST_API_TESTS = ( - os.environ.get("PYTHON_CONNECTION_CLASS") == "requests" -) +RUN_ASYNC_REST_API_TESTS = os.environ.get("PYTHON_CONNECTION_CLASS") == "requests" FALSEY_VALUES = ("", None, False, 0, 0.0)