Skip to content

Commit 0cdeeb6

Browse files
[7.x] Remove yarl from [async] extra
Co-authored-by: Seth Michael Larson <seth.larson@elastic.co>
1 parent 9b8cee0 commit 0cdeeb6

File tree

5 files changed

+49
-13
lines changed

5 files changed

+49
-13
lines changed

elasticsearch/_async/_extra_imports.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@
3131

3232
import aiohttp
3333
import aiohttp.client_exceptions as aiohttp_exceptions
34-
import yarl
34+
35+
36+
# We do this because we don't explicitly require 'yarl'
37+
# within our [async] extra any more.
38+
# See AIOHttpConnection.request() for more information why.
39+
try:
40+
import yarl
41+
except ImportError:
42+
yarl = False
3543

3644
__all__ = ["aiohttp", "aiohttp_exceptions", "yarl"]

elasticsearch/_async/http_aiohttp.py

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -231,15 +231,30 @@ async def perform_request(
231231
method = "GET"
232232
is_head = True
233233

234-
# Provide correct URL object to avoid string parsing in low-level code
235-
url = yarl.URL.build(
236-
scheme=self.scheme,
237-
host=self.hostname,
238-
port=self.port,
239-
path=url_path,
240-
query_string=query_string,
241-
encoded=True,
242-
)
234+
# Top-tier tip-toeing happening here. Basically
235+
# because Pip's old resolver is bad and wipes out
236+
# strict pins in favor of non-strict pins of extras
237+
# our [async] extra overrides aiohttp's pin of
238+
# yarl. yarl released breaking changes, aiohttp pinned
239+
# defensively afterwards, but our users don't get
240+
# that nice pin that aiohttp set. :( So to play around
241+
# this super-defensively we try to import yarl, if we can't
242+
# then we pass a string into ClientSession.request() instead.
243+
if yarl:
244+
# Provide correct URL object to avoid string parsing in low-level code
245+
url = yarl.URL.build(
246+
scheme=self.scheme,
247+
host=self.hostname,
248+
port=self.port,
249+
path=url_path,
250+
query_string=query_string,
251+
encoded=True,
252+
)
253+
else:
254+
url = self.url_prefix + url
255+
if query_string:
256+
url = "%s?%s" % (url, query_string)
257+
url = self.host + url
243258

244259
timeout = aiohttp.ClientTimeout(
245260
total=timeout if timeout is not None else self.timeout

noxfile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def lint(session):
6363

6464
# Make sure we don't require aiohttp to be installed for users to
6565
# receive type hint information from mypy.
66-
session.run("python", "-m", "pip", "uninstall", "--yes", "aiohttp", "yarl")
66+
session.run("python", "-m", "pip", "uninstall", "--yes", "aiohttp")
6767
session.run("mypy", "--strict", "elasticsearch/")
6868
session.run("mypy", "--strict", "test_elasticsearch/test_types/sync_types.py")
6969

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
]
3939

4040
install_requires = [
41-
"urllib3>=1.21.1",
41+
"urllib3>=1.21.1, <2",
4242
"certifi",
4343
]
4444
tests_require = [
@@ -49,7 +49,7 @@
4949
"pytest",
5050
"pytest-cov",
5151
]
52-
async_require = ["aiohttp>=3,<4", "yarl"]
52+
async_require = ["aiohttp>=3,<4"]
5353

5454
docs_require = ["sphinx<1.7", "sphinx_rtd_theme"]
5555
generate_require = ["black", "jinja2"]

test_elasticsearch/test_async/test_server/test_clients.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,16 @@ async def test_bulk_works_with_bytestring_body(self, async_client):
4141

4242
assert response["errors"] is False
4343
assert len(response["items"]) == 1
44+
45+
46+
class TestYarlMissing:
47+
async def test_aiohttp_connection_works_without_yarl(
48+
self, async_client, monkeypatch
49+
):
50+
# This is a defensive test case for if aiohttp suddenly stops using yarl.
51+
from elasticsearch._async import http_aiohttp
52+
53+
monkeypatch.setattr(http_aiohttp, "yarl", False)
54+
55+
resp = await async_client.info(pretty=True)
56+
assert isinstance(resp, dict)

0 commit comments

Comments
 (0)