Skip to content

Commit 53df2b7

Browse files
authored
Handle recursion errors while constructing the pip dependency tree (#2224)
* Handle recursion errors while constructing the pip dependency tree Signed-off-by: Prabhu Subramanian <[email protected]> Improved requirements file parsing logic Signed-off-by: Prabhu Subramanian <[email protected]> Create structured env markers Signed-off-by: Prabhu Subramanian <[email protected]> * Added some missing pypi aliases Signed-off-by: Prabhu Subramanian <[email protected]> * Added some missing pypi aliases Signed-off-by: Prabhu Subramanian <[email protected]> --------- Signed-off-by: Prabhu Subramanian <[email protected]>
1 parent 35ed2ab commit 53df2b7

File tree

9 files changed

+629
-186
lines changed

9 files changed

+629
-186
lines changed

contrib/piptree.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,22 +60,32 @@ def _get_extra_deps_from_dist(dist):
6060
return extra_deps
6161

6262

63-
def _get_deps_from_extras(name_version_cache, name_dist_cache, extra_deps):
63+
def _get_deps_from_extras(name_version_cache, name_dist_cache, extra_deps, visited=None):
6464
dependencies = []
6565
if not extra_deps:
6666
return dependencies
67-
# Treat an extra with the name all as dependencies
67+
if visited is None:
68+
visited = set()
69+
70+
# Treat an extra with the name 'all' as dependencies
6871
all_deps = extra_deps.get("all", [])
6972
for dep in all_deps:
70-
dversion = name_version_cache.get(dep["name"])
73+
dep_name = dep["name"]
74+
if dep_name in visited:
75+
continue # Avoid cycles
76+
visited.add(dep_name)
77+
78+
dversion = name_version_cache.get(dep_name)
7179
if not dversion:
7280
continue
7381
dversionSpecifiers = dep.get("versionSpecifiers")
74-
dpurl = f"""pkg:pypi/{dep["name"].lower()}@{dversion}"""
75-
dextra_deps = _get_extra_deps_from_dist(name_dist_cache.get(dep["name"]))
76-
ddependencies = _get_deps_from_extras(name_version_cache, name_dist_cache, dextra_deps)
82+
dpurl = f"pkg:pypi/{dep_name.lower()}@{dversion}"
83+
dextra_deps = _get_extra_deps_from_dist(name_dist_cache.get(dep_name))
84+
ddependencies = _get_deps_from_extras(
85+
name_version_cache, name_dist_cache, dextra_deps, visited.copy()
86+
)
7787
dependencies.append({
78-
"name": dep["name"],
88+
"name": dep_name,
7989
"version": dversion,
8090
"versionSpecifiers": dversionSpecifiers,
8191
"purl": dpurl,
@@ -104,7 +114,7 @@ def get_installed_with_extras():
104114
# map each extra → its extra-only dependencies
105115
extra_deps = _get_extra_deps_from_dist(dist)
106116
purl = f"pkg:pypi/{name.lower()}@{version}"
107-
dependencies = _get_deps_from_extras(name_version_cache, name_dist_cache, extra_deps)
117+
dependencies = _get_deps_from_extras(name_version_cache, name_dist_cache, extra_deps, set())
108118
result[purl] = {
109119
'name': name,
110120
'version': version,

data/pypi-pkg-aliases.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,7 @@
569569
"daterangefilter": "django-daterangefilter",
570570
"dateutil": "python-dateutil",
571571
"dawg": "dawg",
572+
"dbruntime": "databricks-sdk",
572573
"deb822": "python-debian",
573574
"debian": "python-debian",
574575
"debug-toolbar": "django-debug-toolbar",
@@ -831,6 +832,7 @@
831832
"openid": "python-openid",
832833
"opensearchsdk": "ali-opensearch",
833834
"openssl": "pyopenssl",
835+
"opentelemetry": "opentelemetry-api",
834836
"oslo-i18n": "oslo.i18n",
835837
"oslo-serialization": "oslo.serialization",
836838
"oslo-utils": "oslo.utils",
@@ -1085,6 +1087,7 @@
10851087
"stemmer": "pystemmer",
10861088
"stoneagehtml": "stoneagehtml",
10871089
"storages": "django-storages",
1090+
"strands-tools": "strands-agents-tools",
10881091
"stubout": "mox",
10891092
"suds": "suds-jurko",
10901093
"swiftclient": "python-swiftclient",

0 commit comments

Comments
 (0)