@@ -60,22 +60,32 @@ def _get_extra_deps_from_dist(dist):
60
60
return extra_deps
61
61
62
62
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 ):
64
64
dependencies = []
65
65
if not extra_deps :
66
66
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
68
71
all_deps = extra_deps .get ("all" , [])
69
72
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 )
71
79
if not dversion :
72
80
continue
73
81
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
+ )
77
87
dependencies .append ({
78
- "name" : dep [ "name" ] ,
88
+ "name" : dep_name ,
79
89
"version" : dversion ,
80
90
"versionSpecifiers" : dversionSpecifiers ,
81
91
"purl" : dpurl ,
@@ -104,7 +114,7 @@ def get_installed_with_extras():
104
114
# map each extra → its extra-only dependencies
105
115
extra_deps = _get_extra_deps_from_dist (dist )
106
116
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 () )
108
118
result [purl ] = {
109
119
'name' : name ,
110
120
'version' : version ,
0 commit comments