1
1
# -*- coding: utf-8 -*-
2
2
import json , sys , re , platform , os , sysconfig
3
3
import re
4
- from winpython import utils
5
4
from collections import OrderedDict
6
5
from pip ._vendor .packaging .markers import Marker
7
-
6
+ from importlib .metadata import Distribution , distributions
7
+ from pathlib import Path
8
8
9
9
def normalize (this ):
10
10
"""apply https://peps.python.org/pep-0503/#normalized-names"""
@@ -25,6 +25,7 @@ def __init__(self, Target=None):
25
25
# req_version = version needed
26
26
# req_marker = marker of the requirement (if any)
27
27
# on current Python, use from importlib.metadata + Distribution.Discover() for 2x speed-up
28
+ # on other Python, use importlib.metadata + distributions(path=[str(Path(Target).parent /'lib'/'site-packages'),])
28
29
self .distro = {}
29
30
self .raw = {}
30
31
replacements = str .maketrans ({" " : "" , "[" : "" , "]" : "" , "'" : "" , '"' : "" })
@@ -45,20 +46,25 @@ def __init__(self, Target=None):
45
46
}
46
47
47
48
# 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
49
+ if Target == None :
50
+ Target = sys .executable
51
+
52
+ # faster then pip_inspect = utils.exec_shell_cmd(f'set pythonutf8=1 & python -X utf8=1 -m pip inspect', sys.prefix)
53
+ if sys .executable == Target :
54
+ # self-Distro inspection case (use all packages reachable per sys.path I presume )
52
55
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 :
56
+ else :
57
+ # not self-Distro inspection case , look at site-packages only)
58
+ pip_json_installed = distributions (path = [str (Path (Target ).parent / 'lib' / 'site-packages' ),])
59
+ for p in pip_json_installed :
60
+ meta = p .metadata
61
+ name = p .name
62
+ version = p .version
63
+ key = normalize (name )
64
+ requires = []
65
+ self .raw [key ] = meta
66
+ if p .requires :
67
+ for i in p .requires :
62
68
det = (i + ";" ).split (";" )
63
69
64
70
# req_nameextra is "python-jose[cryptography]"
@@ -81,60 +87,15 @@ def __init__(self, Target=None):
81
87
if not req_marker == "" :
82
88
req_add ["req_marker" ] = req_marker
83
89
requires += [req_add ]
84
- self .distro [key ] = {
90
+ self .distro [key ] = {
85
91
"name" : name ,
86
92
"version" : p .version ,
87
93
"summary" : meta ["Summary" ] if "Summary" in meta else "" ,
88
94
"requires_dist" : requires ,
89
95
"wanted_per" : [],
90
96
"description" : meta ["Description" ] if "Description" in meta else "" ,
91
97
}
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
98
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
- }
138
99
# On a second pass, complement distro in reverse mode with 'wanted-per':
139
100
# - get all downward links in 'requires_dist' of each package
140
101
# - feed the required packages 'wanted_per' as a reverse dict of dict
0 commit comments