Skip to content

Commit e3d01eb

Browse files
committed
Fix packaging integration.
1 parent 057f10d commit e3d01eb

File tree

6 files changed

+399
-367
lines changed

6 files changed

+399
-367
lines changed

Lib/__np__/common.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,10 @@ def copytree(src, dst, symlinks=False, ignore=None, executable=False):
144144
if executable:
145145
os.chmod(d, 509) # 775
146146

147+
def cleanup_file_name(filename):
148+
if '?' in filename:
149+
filename = filename[:filename.index('?')]
150+
return filename
147151

148152
def download_file(url, destination):
149153
if str is bytes:
@@ -166,7 +170,7 @@ def download_file(url, destination):
166170
)
167171
else:
168172
destination_file = os.path.join(
169-
destination, os.path.basename(fp.geturl())
173+
destination, cleanup_file_name(os.path.basename(fp.geturl()))
170174
)
171175

172176
parent_dir = os.path.dirname(destination_file)
@@ -379,3 +383,26 @@ def write_linker_json(
379383
},
380384
f,
381385
)
386+
387+
def importFileAsModule(modulename, filename):
388+
"""Import Python module given as a file name.
389+
390+
Notes:
391+
Provides a Python version independent way to import any script files.
392+
393+
Args:
394+
filename: complete path of a Python script
395+
396+
Returns:
397+
Imported Python module with code from the filename.
398+
"""
399+
import importlib.machinery
400+
import importlib.util # pylint: disable=I0021,import-error,no-name-in-module
401+
402+
build_script_spec = importlib.util.spec_from_loader(
403+
modulename, importlib.machinery.SourceFileLoader(modulename, filename)
404+
)
405+
build_script_module = importlib.util.module_from_spec(build_script_spec)
406+
build_script_spec.loader.exec_module(build_script_module)
407+
return build_script_module
408+

Lib/__np__/metabuild.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import os
2+
import json
3+
import setuptools.build_meta
4+
import pip._vendor.pkg_resources as pkg_resources
5+
6+
import __np__.packaging
7+
8+
class ManagedBackend():
9+
def prepare_metadata_for_build_wheel(
10+
self, metadata_directory, config_settings=None
11+
):
12+
with open(os.path.join("..", "script.json")) as f:
13+
metadata = json.load(f)
14+
with open(os.path.join(metadata_directory, "METADATA"), 'w') as f:
15+
f.write("Metadata-Version: 2.1\n")
16+
f.write(f"Name: {metadata['name']}\n")
17+
f.write(f"Version: {metadata['version']}\n")
18+
19+
return "."
20+
21+
def build_wheel(
22+
self,
23+
wheel_directory,
24+
config_settings = None,
25+
metadata_directory = None,
26+
):
27+
with open(os.path.join("..", "script.json")) as f:
28+
metadata = json.load(f)
29+
30+
__np__.packaging.build_package(metadata['name'], metadata['version'], metadata['script_metadata'], wheel_directory)
31+
32+
33+
managed_build = ManagedBackend()

Lib/__np__/packaging.py

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
import os
2+
import sys
3+
import platform
4+
import json
5+
import fnmatch
6+
7+
import __np__
8+
9+
PACKAGE_BASE_URL = os.environ.get(
10+
"NUITKA_PYTHON_PACKAGE_URL",
11+
"https://raw.githubusercontent.com/Nuitka/Nuitka-Python-packages/master",
12+
)
13+
14+
15+
def getPackageUrl(section, name):
16+
if platform.system() == "Windows":
17+
if str is bytes:
18+
section += "/np27-windows"
19+
else:
20+
section += "/np{0}{1}-windows".format(sys.version_info.major, sys.version_info.minor)
21+
elif platform.system() == "Linux":
22+
if str is bytes:
23+
section += "/np27-linux"
24+
else:
25+
section += "/np{0}{1}-linux".format(sys.version_info.major, sys.version_info.minor)
26+
elif platform.system() == "Darwin":
27+
if str is bytes:
28+
section += "/np27-macos"
29+
else:
30+
section += "/np{0}{1}-macos".format(sys.version_info.major, sys.version_info.minor)
31+
32+
return "{PACKAGE_BASE_URL}/{section}/{name}".format(
33+
PACKAGE_BASE_URL=PACKAGE_BASE_URL, section=section, name=name
34+
)
35+
36+
37+
def getPackageJson(section, name):
38+
package_dir_url = getPackageUrl(section, name)
39+
with __np__.TemporaryDirectory() as temp_dir:
40+
data_filename = __np__.download_file(
41+
"{package_dir_url}/index.json".format(**locals()),
42+
temp_dir,
43+
)
44+
45+
with open(data_filename) as data_file:
46+
return json.loads(data_file.read())
47+
48+
49+
def getBuildScriptName(dir_name, name):
50+
return "build_script_" + os.path.basename(dir_name).replace("-", "_") + "_" + name
51+
52+
def install_build_tool(name):
53+
package_index = getPackageJson("build_tools", name)
54+
package_dir_url = getPackageUrl("build_tools", name)
55+
56+
if "build_tools" in package_index:
57+
for tool in package_index["build_tools"]:
58+
install_build_tool(tool)
59+
60+
if os.path.isfile(
61+
os.path.join(__np__.getToolsInstallDir(), name, "version.txt")
62+
):
63+
with open(
64+
os.path.join(__np__.getToolsInstallDir(), name, "version.txt"), "r"
65+
) as f:
66+
version = f.read()
67+
if version == package_index["version"]:
68+
print("Skipping installed build tool {name}.".format(**locals()))
69+
return
70+
71+
print("Setting up build tool {name}...".format(**locals()))
72+
73+
with __np__.TemporaryDirectory() as temp_dir:
74+
for file in package_index["files"]:
75+
__np__.download_file(
76+
"{package_dir_url}/{file}".format(**locals()),
77+
temp_dir,
78+
)
79+
80+
build_script_module_name = getBuildScriptName(temp_dir, name)
81+
initcwd = os.getcwd()
82+
initenviron = dict(os.environ)
83+
84+
build_script_module = __np__.importFileAsModule(
85+
build_script_module_name,
86+
os.path.join(temp_dir, package_index["build_script"]),
87+
)
88+
try:
89+
build_script_module.run(temp_dir)
90+
finally:
91+
if build_script_module_name in sys.modules:
92+
del sys.modules[build_script_module_name]
93+
try:
94+
del build_script_module
95+
except NameError:
96+
pass
97+
os.chdir(initcwd)
98+
os.environ.clear()
99+
os.environ.update(initenviron)
100+
101+
with open(
102+
os.path.join(__np__.getToolsInstallDir(), name, "version.txt"), "w"
103+
) as f:
104+
f.write(package_index["version"])
105+
106+
107+
def install_dependency(name):
108+
package_index = getPackageJson("dependencies", name)
109+
package_dir_url = getPackageUrl("dependencies", name)
110+
111+
if "build_tools" in package_index:
112+
for tool in package_index["build_tools"]:
113+
install_build_tool(tool)
114+
if "dependencies" in package_index:
115+
for dep in package_index["dependencies"]:
116+
install_dependency(dep)
117+
118+
if os.path.isfile(
119+
os.path.join(__np__.getDependencyInstallDir(), name, "version.txt")
120+
):
121+
with open(
122+
os.path.join(__np__.getDependencyInstallDir(), name, "version.txt"), "r"
123+
) as f:
124+
version = f.read()
125+
if version == package_index["version"]:
126+
print("Skipping installed dependency {name}.".format(**locals()))
127+
return
128+
129+
print("Compiling dependency {name}...".format(**locals()))
130+
131+
with __np__.TemporaryDirectory() as temp_dir:
132+
for file in package_index["files"]:
133+
__np__.download_file(
134+
"{package_dir_url}/{file}".format(**locals()),
135+
temp_dir,
136+
)
137+
138+
build_script_module_name = getBuildScriptName(temp_dir, name)
139+
initcwd = os.getcwd()
140+
initenviron = dict(os.environ)
141+
142+
build_script_module = __np__.importFileAsModule(
143+
build_script_module_name,
144+
os.path.join(temp_dir, package_index["build_script"]),
145+
)
146+
try:
147+
build_script_module.run(temp_dir)
148+
finally:
149+
if build_script_module_name in sys.modules:
150+
del sys.modules[build_script_module_name]
151+
try:
152+
del build_script_module
153+
except NameError:
154+
pass
155+
os.chdir(initcwd)
156+
os.environ.clear()
157+
os.environ.update(initenviron)
158+
159+
with open(
160+
os.path.join(__np__.getDependencyInstallDir(), name, "version.txt"), "w"
161+
) as f:
162+
f.write(package_index["version"])
163+
164+
165+
def build_package(package_name, version, script_metadata, wheel_directory):
166+
install_temp_dir = os.path.dirname(os.getcwd())
167+
168+
if "build_tools" in script_metadata:
169+
for dep in script_metadata["build_tools"]:
170+
install_build_tool(dep)
171+
172+
if "dependencies" in script_metadata:
173+
for dep in script_metadata["dependencies"]:
174+
install_dependency(dep)
175+
176+
for file in script_metadata["files"]:
177+
package_dir_url = getPackageUrl("packages", package_name)
178+
__np__.download_file(
179+
"{package_dir_url}/{file}".format(**locals()),
180+
install_temp_dir,
181+
)
182+
183+
build_script_module_name = getBuildScriptName(install_temp_dir, package_name)
184+
185+
initcwd = os.getcwd()
186+
initenviron = dict(os.environ)
187+
build_script_module = __np__.importFileAsModule(
188+
build_script_module_name,
189+
os.path.join(install_temp_dir, script_metadata["build_script"]),
190+
)
191+
192+
result = None
193+
try:
194+
result = build_script_module.run(wheel_directory)
195+
196+
assert isinstance(result, str)
197+
finally:
198+
if build_script_module_name in sys.modules:
199+
del sys.modules[build_script_module_name]
200+
try:
201+
del build_script_module
202+
except NameError:
203+
pass
204+
os.chdir(initcwd)
205+
os.environ.clear()
206+
os.environ.update(initenviron)
207+
208+
return result
209+
210+
211+
def find_source_by_link(package_name, link):
212+
try:
213+
package_index = getPackageJson("packages", package_name)
214+
except __np__.NoSuchURL:
215+
return None
216+
217+
if "sources" in package_index:
218+
for source in package_index["sources"]:
219+
if source["link"] == link:
220+
return source
221+
222+
return None
223+
224+
def get_extra_sources_for_package(package_name):
225+
try:
226+
package_index = getPackageJson("packages", package_name)
227+
except __np__.NoSuchURL:
228+
return []
229+
230+
package_sources = []
231+
if "sources" in package_index:
232+
from pip._internal.models.candidate import InstallationCandidate
233+
from pip._internal.models.link import Link
234+
235+
for source in package_index["sources"]:
236+
package_sources.append(
237+
InstallationCandidate(
238+
package_name, source["version"], Link(source["link"])
239+
)
240+
)
241+
return package_sources
242+
243+
def find_build_script_for_package(package_name, version):
244+
try:
245+
package_index = getPackageJson("packages", package_name)
246+
except __np__.NoSuchURL:
247+
return None
248+
249+
matched_source = None
250+
for source in package_index["scripts"]:
251+
matched_metadata = True
252+
if "metadata" in source and "Version" in source["metadata"]:
253+
matched_metadata = fnmatch.fnmatch(version, source["metadata"]["Version"])
254+
255+
if matched_metadata:
256+
matched_source = source
257+
break
258+
259+
return matched_source

Lib/ensurepip/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from importlib import resources
99

1010

11-
__all__ = ["version", "bootstrap", "_SETUPTOOLS_VERSION", "_get_packages"]
11+
__all__ = ["version", "bootstrap", "_PROJECTS", "_get_packages"]
1212
_PACKAGE_NAMES = ('setuptools', 'pip', 'wheel')
1313
_SETUPTOOLS_VERSION = "75.2.0.post20241019"
1414
_PIP_VERSION = "23.3.2"
Binary file not shown.

0 commit comments

Comments
 (0)