Skip to content

Commit bc6ed13

Browse files
committed
[7.10] Test typing metadata in build-dist script
1 parent 1992ae1 commit bc6ed13

File tree

7 files changed

+235
-4
lines changed

7 files changed

+235
-4
lines changed

MANIFEST.in

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ include MANIFEST.in
66
include README.rst
77
include README
88
include setup.py
9-
recursive-include elasticsearch* py.typed
9+
recursive-include elasticsearch* py.typed *.pyi
1010
recursive-include docs/sphinx *
1111

1212
prune docs/sphinx/_build

noxfile.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ def lint(session):
5959
# Run mypy on the package and then the type examples separately for
6060
# the two different mypy use-cases, ourselves and our users.
6161
session.run("mypy", "--strict", "elasticsearch/")
62-
session.run("mypy", "--strict", "test_elasticsearch/test_types/")
62+
session.run("mypy", "--strict", "test_elasticsearch/test_types/sync_types.py")
63+
session.run("mypy", "--strict", "test_elasticsearch/test_types/async_types.py")
6364

6465
# Make sure we don't require aiohttp to be installed for users to
6566
# receive type hint information from mypy.

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
"Issue Tracker": "https://github.com/elastic/elasticsearch-py/issues",
7373
},
7474
packages=packages,
75-
package_data={"elasticsearch": ["py.typed"]},
75+
package_data={"elasticsearch": ["py.typed", "*.pyi"]},
7676
include_package_data=True,
7777
zip_safe=False,
7878
classifiers=[
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
# Licensed to Elasticsearch B.V. under one or more contributor
2+
# license agreements. See the NOTICE file distributed with
3+
# this work for additional information regarding copyright
4+
# ownership. Elasticsearch B.V. licenses this file to you under
5+
# the Apache License, Version 2.0 (the "License"); you may
6+
# not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
18+
from typing import Generator, Dict, Any, AsyncGenerator
19+
from elasticsearch7 import (
20+
Elasticsearch,
21+
Transport,
22+
RequestsHttpConnection,
23+
ConnectionPool,
24+
AsyncElasticsearch,
25+
AsyncTransport,
26+
AIOHttpConnection,
27+
)
28+
from elasticsearch7.helpers import (
29+
scan,
30+
streaming_bulk,
31+
reindex,
32+
bulk,
33+
async_scan,
34+
async_streaming_bulk,
35+
async_reindex,
36+
async_bulk,
37+
)
38+
39+
40+
es = Elasticsearch(
41+
[{"host": "localhost", "port": 9443}],
42+
transport_class=Transport,
43+
)
44+
t = Transport(
45+
[{}],
46+
connection_class=RequestsHttpConnection,
47+
connection_pool_class=ConnectionPool,
48+
sniff_on_start=True,
49+
sniffer_timeout=0.1,
50+
sniff_timeout=1,
51+
sniff_on_connection_fail=False,
52+
max_retries=1,
53+
retry_on_status={100, 400, 503},
54+
retry_on_timeout=True,
55+
send_get_body_as="source",
56+
)
57+
58+
59+
def sync_gen() -> Generator[Dict[Any, Any], None, None]:
60+
yield {}
61+
62+
63+
def scan_types() -> None:
64+
for _ in scan(
65+
es,
66+
query={"query": {"match_all": {}}},
67+
request_timeout=10,
68+
clear_scroll=True,
69+
scroll_kwargs={"request_timeout": 10},
70+
):
71+
pass
72+
for _ in scan(
73+
es,
74+
raise_on_error=False,
75+
preserve_order=False,
76+
scroll="10m",
77+
size=10,
78+
request_timeout=10.0,
79+
):
80+
pass
81+
82+
83+
def streaming_bulk_types() -> None:
84+
for _ in streaming_bulk(es, sync_gen()):
85+
pass
86+
for _ in streaming_bulk(es, sync_gen().__iter__()):
87+
pass
88+
for _ in streaming_bulk(es, [{}]):
89+
pass
90+
for _ in streaming_bulk(es, ({},)):
91+
pass
92+
93+
94+
def bulk_types() -> None:
95+
_, _ = bulk(es, sync_gen())
96+
_, _ = bulk(es, sync_gen().__iter__())
97+
_, _ = bulk(es, [{}])
98+
_, _ = bulk(es, ({},))
99+
100+
101+
def reindex_types() -> None:
102+
_, _ = reindex(
103+
es, "src-index", "target-index", query={"query": {"match": {"key": "val"}}}
104+
)
105+
_, _ = reindex(
106+
es, source_index="src-index", target_index="target-index", target_client=es
107+
)
108+
_, _ = reindex(
109+
es,
110+
"src-index",
111+
"target-index",
112+
chunk_size=1,
113+
scroll="10m",
114+
scan_kwargs={"request_timeout": 10},
115+
bulk_kwargs={"request_timeout": 10},
116+
)
117+
118+
119+
es2 = AsyncElasticsearch(
120+
[{"host": "localhost", "port": 9443}],
121+
transport_class=AsyncTransport,
122+
)
123+
t2 = AsyncTransport(
124+
[{}],
125+
connection_class=AIOHttpConnection,
126+
connection_pool_class=ConnectionPool,
127+
sniff_on_start=True,
128+
sniffer_timeout=0.1,
129+
sniff_timeout=1,
130+
sniff_on_connection_fail=False,
131+
max_retries=1,
132+
retry_on_status={100, 400, 503},
133+
retry_on_timeout=True,
134+
send_get_body_as="source",
135+
)
136+
137+
138+
async def async_gen() -> AsyncGenerator[Dict[Any, Any], None]:
139+
yield {}
140+
141+
142+
async def async_scan_types() -> None:
143+
async for _ in async_scan(
144+
es2,
145+
query={"query": {"match_all": {}}},
146+
request_timeout=10,
147+
clear_scroll=True,
148+
scroll_kwargs={"request_timeout": 10},
149+
):
150+
pass
151+
async for _ in async_scan(
152+
es2,
153+
raise_on_error=False,
154+
preserve_order=False,
155+
scroll="10m",
156+
size=10,
157+
request_timeout=10.0,
158+
):
159+
pass
160+
161+
162+
async def async_streaming_bulk_types() -> None:
163+
async for _ in async_streaming_bulk(es2, async_gen()):
164+
pass
165+
async for _ in async_streaming_bulk(es2, async_gen().__aiter__()):
166+
pass
167+
async for _ in async_streaming_bulk(es2, [{}]):
168+
pass
169+
async for _ in async_streaming_bulk(es2, ({},)):
170+
pass
171+
172+
173+
async def async_bulk_types() -> None:
174+
_, _ = await async_bulk(es2, async_gen())
175+
_, _ = await async_bulk(es2, async_gen().__aiter__())
176+
_, _ = await async_bulk(es2, [{}])
177+
_, _ = await async_bulk(es2, ({},))
178+
179+
180+
async def async_reindex_types() -> None:
181+
_, _ = await async_reindex(
182+
es2, "src-index", "target-index", query={"query": {"match": {"key": "val"}}}
183+
)
184+
_, _ = await async_reindex(
185+
es2, source_index="src-index", target_index="target-index", target_client=es2
186+
)
187+
_, _ = await async_reindex(
188+
es2,
189+
"src-index",
190+
"target-index",
191+
chunk_size=1,
192+
scroll="10m",
193+
scan_kwargs={"request_timeout": 10},
194+
bulk_kwargs={"request_timeout": 10},
195+
)

utils/build_dists.py

+33-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def test_dist(dist):
6666
# Build the venv and install the dist
6767
run("python", "-m", "venv", os.path.join(tmp_dir, "venv"))
6868
venv_python = os.path.join(tmp_dir, "venv/bin/python")
69-
run(venv_python, "-m", "pip", "install", "-U", "pip")
69+
run(venv_python, "-m", "pip", "install", "-U", "pip", "mypy")
7070
run(venv_python, "-m", "pip", "install", dist)
7171

7272
# Test the sync namespaces
@@ -106,6 +106,17 @@ def test_dist(dist):
106106
f"from {dist_name}.helpers import async_scan, async_bulk, async_streaming_bulk, async_reindex",
107107
)
108108

109+
# Only need to test 'async_types' for non-aliased package
110+
# since 'aliased_types' tests both async and sync.
111+
if dist_name == "elasticsearch":
112+
run(
113+
venv_python,
114+
"-m",
115+
"mypy",
116+
"--strict",
117+
os.path.join(base_dir, "test_elasticsearch/test_types/async_types.py"),
118+
)
119+
109120
# Ensure that the namespaces are correct for the dist
110121
for suffix in ("", "1", "2", "5", "6", "7", "8", "9", "10"):
111122
distx_name = f"elasticsearch{suffix}"
@@ -116,6 +127,27 @@ def test_dist(dist):
116127
expect_exit_code=256 if distx_name != dist_name else 0,
117128
)
118129

130+
# Check that sync types work for 'elasticsearch' and
131+
# that aliased types work for 'elasticsearchX'
132+
if dist_name == "elasticsearch":
133+
run(
134+
venv_python,
135+
"-m",
136+
"mypy",
137+
"--strict",
138+
os.path.join(base_dir, "test_elasticsearch/test_types/sync_types.py"),
139+
)
140+
else:
141+
run(
142+
venv_python,
143+
"-m",
144+
"mypy",
145+
"--strict",
146+
os.path.join(
147+
base_dir, "test_elasticsearch/test_types/aliased_types.py"
148+
),
149+
)
150+
119151
# Uninstall the dist, see that we can't import things anymore
120152
run(venv_python, "-m", "pip", "uninstall", "--yes", dist_name)
121153
run(

utils/templates/base

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
{{ api.description|replace("\n", " ")|wordwrap(wrapstring="\n ") }}
77
{% endif %}
88
{% if api.doc_url %}
9+
910
`<{{ api.doc_url }}>`_
1011
{% endif %}
1112
{% if api.params|list|length %}

utils/templates/func_params_pyi

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
{% if info.required %}{{ p }}: {{ info.type }}, {% endif %}
33
{% endfor %}
44

5+
*,
6+
57
{% if api.body %}
68
body{% if not api.body.required %}: Optional[Any]=...{% else %}: Any{% endif %},
79
{% endif %}

0 commit comments

Comments
 (0)