Skip to content

Commit eb1c212

Browse files
committed
Add API function for using cleanly as a library #39
Signed-off-by: Tushar Goel <tushar.goel.dav@gmail.com>
1 parent 91016ff commit eb1c212

24 files changed

Lines changed: 12301 additions & 12093 deletions

src/python_inspector/api.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,9 @@ class Resolution(NamedTuple):
5858

5959
def to_dict(self):
6060
return {
61-
"resolution": self.resolution,
62-
"packages": [package for package in self.packages],
6361
"files": self.files,
62+
"packages": [package for package in self.packages],
63+
"resolution": self.resolution,
6464
}
6565

6666

@@ -83,7 +83,14 @@ def resolver_api(
8383
"""
8484
Resolve the dependencies for the package requirements listed in one or
8585
more ``requirement_files``, one or more ``specifiers`` and one setuptools
86-
``setup_py_file`` file and save the results as JSON to FILE.
86+
``setup_py_file`` file.
87+
88+
Resolve the dependencies for the requested ``python_version`` PYVER and
89+
``operating_system`` OS combination defaulting Python version 3.8 and
90+
linux OS.
91+
92+
Download from the provided PyPI simple index_urls INDEX(s) URLs defaulting
93+
to PyPI.org
8794
"""
8895

8996
if verbose:
@@ -198,7 +205,11 @@ def resolver_api(
198205
)
199206

200207
if not direct_dependencies:
201-
raise Exception("Error: no requirements requested.")
208+
return Resolution(
209+
packages=[],
210+
resolution={},
211+
files=files,
212+
)
202213

203214
if verbose:
204215
printer("direct_dependencies:")
@@ -266,7 +277,7 @@ def resolver_api(
266277
packages=packages,
267278
resolution=resolution,
268279
files=files,
269-
).to_dict()
280+
)
270281

271282

272283
def resolve(
@@ -345,6 +356,9 @@ def get_resolved_dependencies(
345356
def get_requirements_from_direct_dependencies(
346357
direct_dependencies: List[DependentPackage], environment_marker: Dict
347358
) -> List[Requirement]:
359+
"""
360+
Yield Requirements from a list of DependentPackages.
361+
"""
348362
for dependency in direct_dependencies:
349363
# FIXME We are skipping editable requirements
350364
# and other pip options for now

src/python_inspector/resolution.py

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -81,17 +81,9 @@ def get_requirements_from_distribution(
8181
if not os.path.exists(location):
8282
return []
8383
reqs = []
84-
try:
85-
for package_data in handler.parse(location):
86-
dependencies = package_data.dependencies
87-
reqs.extend(get_requirements_from_dependencies(dependencies=dependencies))
88-
except Exception as e:
89-
import subprocess
90-
91-
subprocess.check_call(["zip", "-T", location])
92-
raise Exception(
93-
f"Could not get requirements from pypi package at: {location!r}: {e}"
94-
) from e
84+
for package_data in handler.parse(location):
85+
dependencies = package_data.dependencies
86+
reqs.extend(get_requirements_from_dependencies(dependencies=dependencies))
9587
return reqs
9688

9789

src/python_inspector/resolve_cli.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,9 +253,9 @@ def resolve_dependencies(
253253
)
254254
output = dict(
255255
headers=headers,
256-
resolved_dependencies_graph=resolution_result.get("resolution"),
257-
files=resolution_result.get("files"),
258-
packages=resolution_result.get("packages"),
256+
files=resolution_result.files,
257+
packages=resolution_result.packages,
258+
resolved_dependencies_graph=resolution_result.resolution,
259259
)
260260
write_output_in_file(
261261
output=output,

src/python_inspector/setup_py_live_eval.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ def iter_requirements(level, extras, setup_file):
6060
with open(setup_file) as sf:
6161
exec(sf.read(), g)
6262
sys.path.pop()
63+
# removing the assertion `assert g["setup"]`` since this is not true for all cases
64+
# for example when setuptools.setup() is called instead of setup()
6365

6466
mock_args, mock_kwargs = mock_setup.call_args
6567
install_requires = mock_kwargs.get("install_requires", install_requires)

tests/data/azure-devops.req-310-expected.json

Lines changed: 103 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -14,109 +14,6 @@
1414
"warnings": [],
1515
"errors": []
1616
},
17-
"resolved_dependencies_graph": [
18-
{
19-
"package": "pkg:pypi/azure-core@1.26.0",
20-
"dependencies": [
21-
"pkg:pypi/requests@2.28.1",
22-
"pkg:pypi/six@1.16.0",
23-
"pkg:pypi/typing-extensions@4.4.0"
24-
]
25-
},
26-
{
27-
"package": "pkg:pypi/azure-devops@6.0.0b4",
28-
"dependencies": [
29-
"pkg:pypi/msrest@0.6.21"
30-
]
31-
},
32-
{
33-
"package": "pkg:pypi/azure-storage-blob@12.13.1",
34-
"dependencies": [
35-
"pkg:pypi/azure-core@1.26.0",
36-
"pkg:pypi/cryptography@38.0.2",
37-
"pkg:pypi/msrest@0.6.21"
38-
]
39-
},
40-
{
41-
"package": "pkg:pypi/certifi@2022.9.24",
42-
"dependencies": []
43-
},
44-
{
45-
"package": "pkg:pypi/cffi@1.15.1",
46-
"dependencies": [
47-
"pkg:pypi/pycparser@2.21"
48-
]
49-
},
50-
{
51-
"package": "pkg:pypi/charset-normalizer@2.1.1",
52-
"dependencies": []
53-
},
54-
{
55-
"package": "pkg:pypi/click@8.1.3",
56-
"dependencies": []
57-
},
58-
{
59-
"package": "pkg:pypi/cryptography@38.0.2",
60-
"dependencies": [
61-
"pkg:pypi/cffi@1.15.1"
62-
]
63-
},
64-
{
65-
"package": "pkg:pypi/idna@3.4",
66-
"dependencies": []
67-
},
68-
{
69-
"package": "pkg:pypi/isodate@0.6.1",
70-
"dependencies": [
71-
"pkg:pypi/six@1.16.0"
72-
]
73-
},
74-
{
75-
"package": "pkg:pypi/msrest@0.6.21",
76-
"dependencies": [
77-
"pkg:pypi/certifi@2022.9.24",
78-
"pkg:pypi/isodate@0.6.1",
79-
"pkg:pypi/requests-oauthlib@1.3.1",
80-
"pkg:pypi/requests@2.28.1"
81-
]
82-
},
83-
{
84-
"package": "pkg:pypi/oauthlib@3.2.2",
85-
"dependencies": []
86-
},
87-
{
88-
"package": "pkg:pypi/pycparser@2.21",
89-
"dependencies": []
90-
},
91-
{
92-
"package": "pkg:pypi/requests-oauthlib@1.3.1",
93-
"dependencies": [
94-
"pkg:pypi/oauthlib@3.2.2",
95-
"pkg:pypi/requests@2.28.1"
96-
]
97-
},
98-
{
99-
"package": "pkg:pypi/requests@2.28.1",
100-
"dependencies": [
101-
"pkg:pypi/certifi@2022.9.24",
102-
"pkg:pypi/charset-normalizer@2.1.1",
103-
"pkg:pypi/idna@3.4",
104-
"pkg:pypi/urllib3@1.26.12"
105-
]
106-
},
107-
{
108-
"package": "pkg:pypi/six@1.16.0",
109-
"dependencies": []
110-
},
111-
{
112-
"package": "pkg:pypi/typing-extensions@4.4.0",
113-
"dependencies": []
114-
},
115-
{
116-
"package": "pkg:pypi/urllib3@1.26.12",
117-
"dependencies": []
118-
}
119-
],
12017
"files": [
12118
{
12219
"type": "file",
@@ -2502,5 +2399,108 @@
25022399
"datasource_id": null,
25032400
"purl": "pkg:pypi/urllib3@1.26.12"
25042401
}
2402+
],
2403+
"resolved_dependencies_graph": [
2404+
{
2405+
"package": "pkg:pypi/azure-core@1.26.0",
2406+
"dependencies": [
2407+
"pkg:pypi/requests@2.28.1",
2408+
"pkg:pypi/six@1.16.0",
2409+
"pkg:pypi/typing-extensions@4.4.0"
2410+
]
2411+
},
2412+
{
2413+
"package": "pkg:pypi/azure-devops@6.0.0b4",
2414+
"dependencies": [
2415+
"pkg:pypi/msrest@0.6.21"
2416+
]
2417+
},
2418+
{
2419+
"package": "pkg:pypi/azure-storage-blob@12.13.1",
2420+
"dependencies": [
2421+
"pkg:pypi/azure-core@1.26.0",
2422+
"pkg:pypi/cryptography@38.0.2",
2423+
"pkg:pypi/msrest@0.6.21"
2424+
]
2425+
},
2426+
{
2427+
"package": "pkg:pypi/certifi@2022.9.24",
2428+
"dependencies": []
2429+
},
2430+
{
2431+
"package": "pkg:pypi/cffi@1.15.1",
2432+
"dependencies": [
2433+
"pkg:pypi/pycparser@2.21"
2434+
]
2435+
},
2436+
{
2437+
"package": "pkg:pypi/charset-normalizer@2.1.1",
2438+
"dependencies": []
2439+
},
2440+
{
2441+
"package": "pkg:pypi/click@8.1.3",
2442+
"dependencies": []
2443+
},
2444+
{
2445+
"package": "pkg:pypi/cryptography@38.0.2",
2446+
"dependencies": [
2447+
"pkg:pypi/cffi@1.15.1"
2448+
]
2449+
},
2450+
{
2451+
"package": "pkg:pypi/idna@3.4",
2452+
"dependencies": []
2453+
},
2454+
{
2455+
"package": "pkg:pypi/isodate@0.6.1",
2456+
"dependencies": [
2457+
"pkg:pypi/six@1.16.0"
2458+
]
2459+
},
2460+
{
2461+
"package": "pkg:pypi/msrest@0.6.21",
2462+
"dependencies": [
2463+
"pkg:pypi/certifi@2022.9.24",
2464+
"pkg:pypi/isodate@0.6.1",
2465+
"pkg:pypi/requests-oauthlib@1.3.1",
2466+
"pkg:pypi/requests@2.28.1"
2467+
]
2468+
},
2469+
{
2470+
"package": "pkg:pypi/oauthlib@3.2.2",
2471+
"dependencies": []
2472+
},
2473+
{
2474+
"package": "pkg:pypi/pycparser@2.21",
2475+
"dependencies": []
2476+
},
2477+
{
2478+
"package": "pkg:pypi/requests-oauthlib@1.3.1",
2479+
"dependencies": [
2480+
"pkg:pypi/oauthlib@3.2.2",
2481+
"pkg:pypi/requests@2.28.1"
2482+
]
2483+
},
2484+
{
2485+
"package": "pkg:pypi/requests@2.28.1",
2486+
"dependencies": [
2487+
"pkg:pypi/certifi@2022.9.24",
2488+
"pkg:pypi/charset-normalizer@2.1.1",
2489+
"pkg:pypi/idna@3.4",
2490+
"pkg:pypi/urllib3@1.26.12"
2491+
]
2492+
},
2493+
{
2494+
"package": "pkg:pypi/six@1.16.0",
2495+
"dependencies": []
2496+
},
2497+
{
2498+
"package": "pkg:pypi/typing-extensions@4.4.0",
2499+
"dependencies": []
2500+
},
2501+
{
2502+
"package": "pkg:pypi/urllib3@1.26.12",
2503+
"dependencies": []
2504+
}
25052505
]
25062506
}

0 commit comments

Comments
 (0)