Skip to content

Commit f974587

Browse files
committed
Merge branch 'master' into ep/db-spec-experiement-foundation-dict
2 parents ff55bad + e2dd162 commit f974587

11 files changed

Lines changed: 10514 additions & 5167 deletions

File tree

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,10 @@ typing = [
6767
"httpx2",
6868
"botocore-stubs",
6969
"werkzeug",
70+
"mcp>=2.0.0b1",
7071
"starlette>=1.3.1",
72+
"python-multipart>=0.0.32",
73+
"pydantic>=2.13.4",
7174
]
7275
test = [
7376
"dataclasses ; python_full_version < '3.7'",

scripts/populate_tox/package_dependencies.jsonl

Lines changed: 539 additions & 891 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/populate_tox/populate_tox.py

Lines changed: 59 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
import re
1313
import subprocess
1414
import sys
15-
import tempfile
1615
import time
1716
from bisect import bisect_left
1817
from collections import defaultdict
@@ -22,7 +21,6 @@
2221
from pathlib import Path
2322
from typing import Optional, Union
2423

25-
from packaging.requirements import Requirement
2624
from packaging.specifiers import SpecifierSet
2725
from packaging.version import Version
2826

@@ -165,12 +163,12 @@ def fetch_release(package: str, version: Version) -> Optional[dict]:
165163
return release
166164

167165

168-
def _get_dependency_probe_constraints(
166+
def _get_additional_test_dependencies(
169167
integration: str,
170168
release: Version,
171169
python_version: ThreadedVersion,
172170
) -> tuple[str, ...]:
173-
constraints = []
171+
additional_dependencies = []
174172
for rule, dependencies in TEST_SUITE_CONFIG[integration].get("deps", {}).items():
175173
# Skip if rule does not apply to current package or Python version
176174
if rule != "*" and (
@@ -182,17 +180,8 @@ def _get_dependency_probe_constraints(
182180
):
183181
continue
184182

185-
for dependency in dependencies:
186-
requirement = Requirement(dependency)
187-
188-
# Constraints are useful only when they actually constrain versions.
189-
if (
190-
requirement.specifier
191-
and not requirement.extras
192-
and requirement.url is None
193-
):
194-
constraints.append(dependency)
195-
return tuple(constraints)
183+
additional_dependencies += dependencies
184+
return tuple(additional_dependencies)
196185

197186

198187
@functools.cache
@@ -201,56 +190,57 @@ def fetch_package_dependencies(
201190
package: str,
202191
version: Version,
203192
python_version: ThreadedVersion,
193+
install_additional_targets: bool = False,
204194
) -> dict:
205-
"""Fetch package dependencies metadata from cache or, failing that, PyPI."""
195+
"""
196+
Fetch package dependencies metadata from cache or, failing that, PyPI.
197+
198+
With `install_additional_targets`, dependencies in `config.py` are also included (test dependencies).
199+
"""
206200
target = TEST_SUITE_CONFIG[integration]["package"]
207-
constraints = _get_dependency_probe_constraints(
208-
integration, version, python_version
209-
)
210-
constraints_hash = hashlib.md5(
211-
"\n".join([target, *constraints]).encode("utf-8")
212-
).hexdigest()
201+
targets = [f"{target}=={version}"]
202+
if install_additional_targets:
203+
targets += _get_additional_test_dependencies(
204+
integration, version, python_version
205+
)
206+
207+
install_targets_hash = hashlib.md5("\n".join(targets).encode("utf-8")).hexdigest()
208+
213209
package_dependencies = _fetch_package_dependencies_from_cache(
214-
package, version, python_version, constraints_hash
210+
package, version, python_version, install_targets_hash
215211
)
216212
if package_dependencies is not None:
217213
return package_dependencies
218214

215+
print(f" Resolving dependencies: {package}=={version} on Python {python_version}")
216+
219217
# Removing non-report output with -qqq may be brittle, but avoids file I/O.
220218
# Currently -qqq supresses all non-report output that would break json.loads().
221-
cmd = [
222-
"uv",
223-
"run",
224-
"--no-project",
225-
"--python",
226-
str(python_version),
227-
"--with",
228-
"pip",
229-
"python",
230-
"-m",
231-
"pip",
232-
"install",
233-
f"{target}=={version}",
234-
"--only-binary",
235-
"grpcio-tools", # Prevent source builds that hang CI. grpcio-tools is a build-time dependency pinned by apache-beam.
236-
"--dry-run",
237-
"--ignore-installed",
238-
"--report",
239-
"-",
240-
"-qqq",
241-
]
242-
243-
with tempfile.NamedTemporaryFile("w", encoding="utf-8") as f:
244-
f.write("\n".join(constraints))
245-
f.flush()
246-
print(
247-
f" Resolving dependencies: {package}=={version} on Python {python_version}"
248-
)
249-
result = subprocess.run(
250-
[*cmd, "--constraint", f.name],
251-
capture_output=True,
252-
text=True,
253-
)
219+
result = subprocess.run(
220+
[
221+
"uv",
222+
"run",
223+
"--no-project",
224+
"--python",
225+
str(python_version),
226+
"--with",
227+
"pip",
228+
"python",
229+
"-m",
230+
"pip",
231+
"install",
232+
*targets,
233+
"--only-binary",
234+
"grpcio-tools", # Prevent source builds that hang CI. grpcio-tools is a build-time dependency pinned by apache-beam.
235+
"--dry-run",
236+
"--ignore-installed",
237+
"--report",
238+
"-",
239+
"-qqq",
240+
],
241+
capture_output=True,
242+
text=True,
243+
)
254244

255245
if result.returncode != 0:
256246
# Some failures are expected because uv installs packages which pip rejects for having bad metadata.
@@ -263,7 +253,7 @@ def fetch_package_dependencies(
263253
version,
264254
python_version,
265255
dependencies_info,
266-
constraints_hash,
256+
install_targets_hash,
267257
)
268258

269259
return dependencies_info
@@ -282,13 +272,11 @@ def _fetch_package_dependencies_from_cache(
282272
package: str,
283273
version: Version,
284274
python_version: ThreadedVersion,
285-
constraints_hash: str,
275+
install_targets_hash: str,
286276
) -> Optional[dict]:
287277
package = _normalize_name(package)
288-
cache_entry = (
289-
DEPENDENCIES_CACHE[package].get(str(version), {}).get(str(python_version), None)
290-
)
291-
if cache_entry is not None and cache_entry["constraints_hash"] == constraints_hash:
278+
cache_entry = DEPENDENCIES_CACHE[str(python_version)].get(install_targets_hash)
279+
if cache_entry is not None:
292280
cache_entry["_accessed"] = True
293281
return cache_entry["dependencies"]
294282

@@ -308,29 +296,24 @@ def _save_to_package_dependencies_cache(
308296
version: Version,
309297
python_version: ThreadedVersion,
310298
release: Optional[dict],
311-
constraints_hash: str,
299+
install_targets_hash: str,
312300
) -> None:
313301
normalized_dependencies = _normalize_package_dependencies(release)
314302

315303
with open(DEPENDENCIES_CACHE_FILE, "a") as releases_cache:
316304
releases_cache.write(
317305
json.dumps(
318306
{
319-
"name": package,
320-
"version": str(version),
321307
"python_version": str(python_version),
322308
"dependencies": normalized_dependencies,
323-
"constraints_hash": constraints_hash,
309+
"install_targets_hash": install_targets_hash,
324310
}
325311
)
326312
+ "\n"
327313
)
328314

329-
DEPENDENCIES_CACHE[_normalize_name(package)].setdefault(str(version), {})[
330-
str(python_version)
331-
] = {
315+
DEPENDENCIES_CACHE[str(python_version)][install_targets_hash] = {
332316
"dependencies": normalized_dependencies,
333-
"constraints_hash": constraints_hash,
334317
"_accessed": True,
335318
}
336319

@@ -996,6 +979,7 @@ def _render_transitive_dependencies(
996979
package,
997980
release,
998981
python_version,
982+
install_additional_targets=True,
999983
):
1000984
name = dependency["metadata"]["name"]
1001985
version = dependency["metadata"]["version"]
@@ -1286,12 +1270,9 @@ def main() -> dict[str, list]:
12861270
with open(DEPENDENCIES_CACHE_FILE) as dependencies_cache:
12871271
for line in dependencies_cache:
12881272
release = json.loads(line)
1289-
name = _normalize_name(release["name"])
1290-
version = release["version"]
12911273
python_version = release["python_version"]
1292-
DEPENDENCIES_CACHE[name].setdefault(version, {})[python_version] = {
1274+
DEPENDENCIES_CACHE[python_version][release["install_targets_hash"]] = {
12931275
"dependencies": release["dependencies"],
1294-
"constraints_hash": release["constraints_hash"],
12951276
"_accessed": False,
12961277
}
12971278

@@ -1379,13 +1360,13 @@ def main() -> dict[str, list]:
13791360
releases = []
13801361
with open(DEPENDENCIES_CACHE_FILE) as releases_cache:
13811362
releases = [json.loads(line) for line in releases_cache]
1382-
releases.sort(key=lambda r: (r["name"], r["version"]))
1363+
releases.sort(key=lambda r: (r["python_version"], r["install_targets_hash"]))
13831364
with open(DEPENDENCIES_CACHE_FILE, "w") as releases_cache:
13841365
for release in releases:
13851366
if (
1386-
DEPENDENCIES_CACHE[_normalize_name(release["name"])][
1387-
release["version"]
1388-
][release["python_version"]]["_accessed"]
1367+
DEPENDENCIES_CACHE[release["python_version"]][
1368+
release["install_targets_hash"]
1369+
]["_accessed"]
13891370
is True
13901371
):
13911372
releases_cache.write(json.dumps(release) + "\n")

0 commit comments

Comments
 (0)