Skip to content

Commit 8aa2408

Browse files
committed
Support Python 3.6 to 3.11
1 parent b58e09f commit 8aa2408

File tree

16 files changed

+44
-193
lines changed

16 files changed

+44
-193
lines changed

.buildkite/pipeline.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ steps:
1010
matrix:
1111
setup:
1212
python:
13-
- "2.7"
1413
- "3.6"
1514
- "3.7"
1615
- "3.8"

.github/workflows/ci.yml

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,24 +23,14 @@ jobs:
2323
strategy:
2424
fail-fast: false
2525
matrix:
26-
python-version: ["3.7", "3.8", "3.9", "3.10"]
26+
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
2727
experimental: [false]
2828
runs-on: ["ubuntu-latest"]
2929
include:
30-
- python-version: 2.7
31-
experimental: false
32-
runs-on: "ubuntu-20.04"
33-
- python-version: 3.5
34-
experimental: false
35-
runs-on: "ubuntu-20.04"
3630
- python-version: 3.6
3731
experimental: false
3832
runs-on: "ubuntu-20.04"
3933

40-
- python-version: 3.11
41-
experimental: true
42-
runs-on: "ubuntu-20.04"
43-
4434
runs-on: ${{ matrix.runs-on }}
4535
name: test-${{ matrix.python-version }}
4636
continue-on-error: ${{ matrix.experimental }}
@@ -55,5 +45,8 @@ jobs:
5545
run: |
5646
python -m pip install -r dev-requirements.txt
5747
- name: Run Tests
58-
run: |
59-
python setup.py test
48+
run: python setup.py test
49+
env:
50+
# Workaround for development versions of Python
51+
# https://github.com/aio-libs/aiohttp/issues/7675
52+
AIOHTTP_NO_EXTENSIONS: 1

dev-requirements.txt

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,18 @@ sphinx
77
jinja2
88
python-dateutil
99

10-
# Testing the 'search_mvt' API response
11-
mapbox-vector-tile; python_version!="3.4.*"
12-
# For mapbox-vector-tile, package broke Python 2 support without an annotation.
13-
# See: protocolbuffers/protobuf#8984
14-
protobuf<3.18; python_version!="3.4.*"
10+
mapbox-vector-tile
1511

16-
# No wheels for Python 3.10 yet!
17-
numpy; python_version<"3.10"
18-
pandas; python_version<"3.10"
12+
numpy
13+
pandas
1914

20-
# PyYAML 5.3 dropped support for Python 3.4 while
21-
# not amending that requirement to the package. :(
22-
pyyaml>=5.4; python_version>="3.6"
23-
pyyaml<5.3; python_version<"3.6"
15+
pyyaml>=5.4
2416

2517
isort
26-
black; python_version>="3.6"
18+
black
2719
twine
2820

2921
# Requirements for testing [async] extra
30-
aiohttp; python_version>="3.6"
31-
pytest-asyncio; python_version>="3.6"
32-
unasync; python_version>="3.6"
22+
aiohttp
23+
pytest-asyncio
24+
unasync

elasticsearch/__init__.py

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,6 @@
8888
]
8989

9090
try:
91-
# Asyncio only supported on Python 3.6+
92-
if sys.version_info < (3, 6):
93-
raise ImportError
94-
9591
from ._async.client import AsyncElasticsearch
9692
from ._async.http_aiohttp import AIOHttpConnection, AsyncConnection
9793
from ._async.transport import AsyncTransport
@@ -104,13 +100,3 @@
104100
]
105101
except (ImportError, SyntaxError):
106102
pass
107-
108-
# Python earlier than 3.6 is deprecated and will be removed in 8.0.0
109-
if sys.version_info < (3, 6):
110-
warnings.warn(
111-
"Support for Python 3.5 and earlier is deprecated and will be removed "
112-
"in v8.0.0 (current instance is Python %d.%d) See https://github.com/elastic"
113-
"/elasticsearch-py/issues/1696 for details." % sys.version_info[:2],
114-
category=DeprecationWarning,
115-
stacklevel=2,
116-
)

elasticsearch/client/utils.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from functools import wraps
2626

2727
from .._version import __versionstr__
28-
from ..compat import PY2, quote, string_types, to_bytes, to_str, unquote, urlparse
28+
from ..compat import quote, string_types, to_bytes, to_str, unquote, urlparse
2929

3030
# parts of URL to be omitted
3131
SKIP_IN_PATH = (None, "", b"", [], ())
@@ -105,9 +105,7 @@ def _escape(value):
105105

106106
# encode strings to utf-8
107107
if isinstance(value, string_types):
108-
if PY2 and isinstance(value, unicode): # noqa: F821
109-
return value.encode("utf-8")
110-
if not PY2 and isinstance(value, str):
108+
if isinstance(value, str):
111109
return value.encode("utf-8")
112110

113111
return str(value)

elasticsearch/compat.py

Lines changed: 15 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -15,60 +15,30 @@
1515
# specific language governing permissions and limitations
1616
# under the License.
1717

18-
import sys
18+
import asyncio
1919

20-
PY2 = sys.version_info[0] == 2
20+
string_types = str, bytes
21+
from urllib.parse import quote, quote_plus, unquote, urlencode, urlparse
2122

22-
if PY2:
23-
string_types = (basestring,) # noqa: F821
24-
from itertools import imap as map
25-
from urllib import quote, quote_plus, unquote, urlencode
23+
map = map
24+
from queue import Queue
2625

27-
from Queue import Queue
28-
from urlparse import urlparse
2926

30-
def to_str(x, encoding="ascii"):
31-
if not isinstance(x, str):
32-
return x.encode(encoding)
33-
return x
27+
def to_str(x, encoding="ascii"):
28+
if not isinstance(x, str):
29+
return x.decode(encoding)
30+
return x
3431

35-
to_bytes = to_str
3632

37-
else:
38-
string_types = str, bytes
39-
from urllib.parse import quote, quote_plus, unquote, urlencode, urlparse
33+
def to_bytes(x, encoding="ascii"):
34+
if not isinstance(x, bytes):
35+
return x.encode(encoding)
36+
return x
4037

41-
map = map
42-
from queue import Queue
4338

44-
def to_str(x, encoding="ascii"):
45-
if not isinstance(x, str):
46-
return x.decode(encoding)
47-
return x
39+
from collections.abc import Mapping
4840

49-
def to_bytes(x, encoding="ascii"):
50-
if not isinstance(x, bytes):
51-
return x.encode(encoding)
52-
return x
53-
54-
55-
try:
56-
from collections.abc import Mapping
57-
except ImportError:
58-
from collections import Mapping
59-
60-
61-
try:
62-
reraise_exceptions = (RecursionError,)
63-
except NameError:
64-
reraise_exceptions = ()
65-
66-
try:
67-
import asyncio
68-
69-
reraise_exceptions += (asyncio.CancelledError,)
70-
except (ImportError, AttributeError):
71-
pass
41+
reraise_exceptions = (RecursionError, asyncio.CancelledError)
7242

7343
try:
7444
from threading import Lock

elasticsearch/compat.pyi

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import sys
1919
from typing import Callable, Tuple, Type, Union
2020

21-
PY2: bool
2221
string_types: Tuple[type, ...]
2322

2423
to_str: Callable[[Union[str, bytes]], str]

elasticsearch/connection/base.py

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import json
3030

3131
from .. import __versionstr__
32-
from ..compat import PY2
3332
from ..exceptions import (
3433
HTTP_EXCEPTIONS,
3534
ElasticsearchWarning,
@@ -259,9 +258,6 @@ def log_request_success(
259258
except AttributeError:
260259
pass
261260

262-
if response is not None:
263-
response = loggable_response_body(response)
264-
265261
logger.info(
266262
"%s %s [status:%s request:%.3fs]", method, full_url, status_code, duration
267263
)
@@ -302,9 +298,6 @@ def log_request_fail(
302298
except AttributeError:
303299
pass
304300

305-
if response is not None:
306-
response = loggable_response_body(response)
307-
308301
logger.debug("> %s", body)
309302

310303
self._log_trace(method, path, body, status_code, response, duration)
@@ -342,18 +335,3 @@ def _get_api_key_header_val(self, api_key):
342335
s = "{0}:{1}".format(api_key[0], api_key[1]).encode("utf-8")
343336
return "ApiKey " + binascii.b2a_base64(s).rstrip(b"\r\n").decode("utf-8")
344337
return "ApiKey " + api_key
345-
346-
347-
def loggable_response_body(response):
348-
# If 'response' isn't unicode we need to try converting it to
349-
# unicode otherwise it's likely binary so should be encoded
350-
# properly. On Python 3.x this works out fine.
351-
if PY2 and not isinstance(response, unicode): # noqa
352-
try:
353-
response = response.decode("utf-8")
354-
except (AttributeError, UnicodeError):
355-
# Encodes unprintable characters to '\xXX' hex
356-
# like how is done in Python 3.x in bytes.__repr__
357-
response = u"b" + repr(response).decode("utf-8")
358-
359-
return response

elasticsearch/helpers/__init__.py

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import sys
1919

20+
from .._async.helpers import async_bulk, async_reindex, async_scan, async_streaming_bulk
2021
from .actions import (
2122
_chunk_actions,
2223
_process_bulk_chunk,
@@ -40,21 +41,8 @@
4041
"reindex",
4142
"_chunk_actions",
4243
"_process_bulk_chunk",
44+
"async_scan",
45+
"async_bulk",
46+
"async_reindex",
47+
"async_streaming_bulk",
4348
]
44-
45-
46-
try:
47-
# Asyncio only supported on Python 3.6+
48-
if sys.version_info < (3, 6):
49-
raise ImportError
50-
51-
from .._async.helpers import (
52-
async_bulk,
53-
async_reindex,
54-
async_scan,
55-
async_streaming_bulk,
56-
)
57-
58-
__all__ += ["async_scan", "async_bulk", "async_reindex", "async_streaming_bulk"]
59-
except (ImportError, SyntaxError):
60-
pass

elasticsearch/helpers/__init__.pyi

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717

1818
import sys
1919

20+
from .._async.helpers import async_bulk as async_bulk
21+
from .._async.helpers import async_reindex as async_reindex
22+
from .._async.helpers import async_scan as async_scan
23+
from .._async.helpers import async_streaming_bulk as async_streaming_bulk
2024
from .actions import _chunk_actions as _chunk_actions
2125
from .actions import _process_bulk_chunk as _process_bulk_chunk
2226
from .actions import bulk as bulk
@@ -27,15 +31,3 @@ from .actions import scan as scan
2731
from .actions import streaming_bulk as streaming_bulk
2832
from .errors import BulkIndexError as BulkIndexError
2933
from .errors import ScanError as ScanError
30-
31-
try:
32-
# Asyncio only supported on Python 3.6+
33-
if sys.version_info < (3, 6):
34-
raise ImportError
35-
36-
from .._async.helpers import async_bulk as async_bulk
37-
from .._async.helpers import async_reindex as async_reindex
38-
from .._async.helpers import async_scan as async_scan
39-
from .._async.helpers import async_streaming_bulk as async_streaming_bulk
40-
except (ImportError, SyntaxError):
41-
pass

noxfile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
)
2727

2828

29-
@nox.session(python=["2.7", "3.4", "3.5", "3.6", "3.7", "3.8", "3.9"])
29+
@nox.session(python=["3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"])
3030
def test(session):
3131
session.install(".")
3232
session.install("-r", "dev-requirements.txt")

setup.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,19 +95,17 @@
9595
"Intended Audience :: Developers",
9696
"Operating System :: OS Independent",
9797
"Programming Language :: Python",
98-
"Programming Language :: Python :: 2",
99-
"Programming Language :: Python :: 2.7",
10098
"Programming Language :: Python :: 3",
101-
"Programming Language :: Python :: 3.4",
102-
"Programming Language :: Python :: 3.5",
10399
"Programming Language :: Python :: 3.6",
104100
"Programming Language :: Python :: 3.7",
105101
"Programming Language :: Python :: 3.8",
106102
"Programming Language :: Python :: 3.9",
103+
"Programming Language :: Python :: 3.10",
104+
"Programming Language :: Python :: 3.11",
107105
"Programming Language :: Python :: Implementation :: CPython",
108106
"Programming Language :: Python :: Implementation :: PyPy",
109107
],
110-
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4",
108+
python_requires=">=3.6",
111109
install_requires=install_requires,
112110
test_suite="test_elasticsearch.run_tests.run_all",
113111
tests_require=tests_require,

test_elasticsearch/run_tests.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,6 @@ def run_all(argv=None):
9494
]
9595

9696
ignores = []
97-
# Python 3.6+ is required for async
98-
if sys.version_info < (3, 6):
99-
ignores.append("test_elasticsearch/test_async/")
100-
10197
# GitHub Actions, run non-server tests
10298
if "GITHUB_ACTION" in environ:
10399
ignores.extend(

test_elasticsearch/test_client/test_utils.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import pytest
2525

2626
from elasticsearch.client.utils import _bulk_body, _escape, _make_path, query_params
27-
from elasticsearch.compat import PY2
2827

2928
from ..test_cases import SkipTest, TestCase
3029

@@ -446,14 +445,6 @@ def test_handles_unicode(self):
446445
"/some-index/type/%E4%B8%AD%E6%96%87", _make_path("some-index", "type", id)
447446
)
448447

449-
def test_handles_utf_encoded_string(self):
450-
if not PY2:
451-
raise SkipTest("Only relevant for py2")
452-
id = "中文".encode("utf-8")
453-
self.assertEqual(
454-
"/some-index/type/%E4%B8%AD%E6%96%87", _make_path("some-index", "type", id)
455-
)
456-
457448

458449
class TestEscape(TestCase):
459450
def test_handles_ascii(self):

0 commit comments

Comments
 (0)