Skip to content

Commit 980c4f7

Browse files
committed
speed-up wppm in the common case
now as fast as "pip list"
1 parent 3d636a9 commit 980c4f7

File tree

2 files changed

+73
-29
lines changed

2 files changed

+73
-29
lines changed

winpython/piptree.py

Lines changed: 71 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,10 @@ def normalize(this):
1212

1313

1414
class pipdata:
15-
"""Wrapper aroud pip inspect"""
15+
"""Wrapper around Distribution.discover() or pip inspect"""
1616

1717
def __init__(self, Target=None):
1818

19-
# get pip_inpsect raw data in json form
20-
#os.environ["pythonutf8"] = "1" causes issues in movable, so limit to there
21-
if Target == None:
22-
#pip_inspect = utils.exec_run_cmd(["pip", "inspect"])
23-
pip_inspect = utils.exec_shell_cmd(f'set pythonutf8=1 & python -X utf8=1 -m pip inspect', sys.prefix)
24-
else:
25-
#pip_inspect = utils.exec_run_cmd([Target , "-X" ,"utf8=1", "-m", "pip", "inspect"])
26-
pip_inspect = utils.exec_shell_cmd(f'set pythonutf8=1 & "{Target}" -X utf8=1 -m pip inspect', sys.prefix)
27-
pip_json = json.loads(pip_inspect)
28-
2919
# create a distro{} dict of Packages
3020
# key = normalised package name
3121
# string_elements = 'name', 'version', 'summary'
@@ -34,6 +24,7 @@ def __init__(self, Target=None):
3424
# req_extra = extra branch needed of the package_key ('all' or '')
3525
# req_version = version needed
3626
# req_marker = marker of the requirement (if any)
27+
# on current Python, use from importlib.metadata + Distribution.Discover() for 2x speed-up
3728
self.distro = {}
3829
self.raw = {}
3930
replacements = str.maketrans({" ": "", "[": "", "]": "", "'": "", '"': ""})
@@ -53,14 +44,21 @@ def __init__(self, Target=None):
5344
"sys_platform": sys.platform,
5445
}
5546

56-
for p in pip_json["installed"]:
57-
meta = p["metadata"]
58-
name = meta["name"]
59-
key = normalize(name)
60-
requires = []
61-
self.raw[key] = meta
62-
if "requires_dist" in meta:
63-
for i in meta["requires_dist"]:
47+
# get pip_inpsect raw data in json form
48+
if Target == None or sys.executable==Target:
49+
# self-Distro inspection case
50+
# faster then pip_inspect = utils.exec_shell_cmd(f'set pythonutf8=1 & python -X utf8=1 -m pip inspect', sys.prefix)
51+
from importlib.metadata import Distribution
52+
pip_json_installed=Distribution.discover()
53+
for p in pip_json_installed:
54+
meta = p.metadata
55+
name = p.name
56+
version = p.version
57+
key = normalize(name)
58+
requires = []
59+
self.raw[key] = meta
60+
if p.requires:
61+
for i in p.requires:
6462
det = (i + ";").split(";")
6563

6664
# req_nameextra is "python-jose[cryptography]"
@@ -83,14 +81,60 @@ def __init__(self, Target=None):
8381
if not req_marker == "":
8482
req_add["req_marker"] = req_marker
8583
requires += [req_add]
86-
self.distro[key] = {
87-
"name": name,
88-
"version": meta["version"],
89-
"summary": meta["summary"] if "summary" in meta else "",
90-
"requires_dist": requires,
91-
"wanted_per": [],
92-
"description": meta["description"] if "description" in meta else "",
93-
}
84+
self.distro[key] = {
85+
"name": name,
86+
"version": p.version,
87+
"summary": meta["Summary"] if "Summary" in meta else "",
88+
"requires_dist": requires,
89+
"wanted_per": [],
90+
"description": meta["Description"] if "Description" in meta else "",
91+
}
92+
else:
93+
# General Any Distro inspection case
94+
# unreliable to utf-8: pip_inspect = utils.exec_run_cmd([Target , "-X" ,"utf8=1", "-m", "pip", "inspect"])
95+
# os.environ["pythonutf8"] = "1" causes issues in movable function, so limit to this moment
96+
pip_inspect = utils.exec_shell_cmd(f'set pythonutf8=1 & "{Target}" -X utf8=1 -m pip inspect', sys.prefix)
97+
pip_json = json.loads(pip_inspect)
98+
99+
100+
for p in pip_json["installed"]:
101+
meta = p["metadata"]
102+
name = meta["name"]
103+
key = normalize(name)
104+
requires = []
105+
self.raw[key] = meta
106+
if "requires_dist" in meta:
107+
for i in meta["requires_dist"]:
108+
det = (i + ";").split(";")
109+
110+
# req_nameextra is "python-jose[cryptography]"
111+
# from fastapi "python-jose[cryptography]<4.0.0,>=3.3.0
112+
# req_nameextra is "google-cloud-storage"
113+
# from "google-cloud-storage (<2.0.0,>=1.26.0)
114+
req_nameextra = re.split(" |;|==|!|>|<", det[0] + ";")[0]
115+
req_nameextra = normalize(req_nameextra)
116+
req_key = normalize((req_nameextra + "[").split("[")[0])
117+
req_key_extra = req_nameextra[len(req_key) + 1 :].split("]")[0]
118+
req_version = det[0][len(req_nameextra) :].translate(replacements)
119+
req_marker = det[1]
120+
121+
req_add = {
122+
"req_key": req_key,
123+
"req_version": req_version,
124+
"req_extra": req_key_extra,
125+
}
126+
# add the marker of the requirement, if not nothing:
127+
if not req_marker == "":
128+
req_add["req_marker"] = req_marker
129+
requires += [req_add]
130+
self.distro[key] = {
131+
"name": name,
132+
"version": meta["version"],
133+
"summary": meta["summary"] if "summary" in meta else "",
134+
"requires_dist": requires,
135+
"wanted_per": [],
136+
"description": meta["description"] if "description" in meta else "",
137+
}
94138
# On a second pass, complement distro in reverse mode with 'wanted-per':
95139
# - get all downward links in 'requires_dist' of each package
96140
# - feed the required packages 'wanted_per' as a reverse dict of dict

winpython/wppm.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -870,10 +870,10 @@ def main(test=False):
870870
title = f"** Package: {l[0]} **"
871871
print("\n"+"*"*len(title), f"\n{title}", "\n"+"*"*len(title) )
872872
for key, value in pip.raw[l[0]].items():
873-
rawtext=json.dumps(value, indent=2)
873+
rawtext=json.dumps(value, indent=2, ensure_ascii=False)
874874
lines = [l for l in rawtext.split(r"\n") if len(l.strip()) > 2]
875875
if key.lower() != 'description' or args.verbose==True:
876-
print(f"{key}: ","\n".join(lines).replace('"', ""))
876+
print(f"{key}: ", "\n".join(lines).replace('"', ""))
877877
sys.exit()
878878
if args.registerWinPython:
879879
print(registerWinPythonHelp)

0 commit comments

Comments
 (0)