Skip to content

Commit 7d14b00

Browse files
committed
[GR-44824] Standalone module - refactoring, cleanup.
PullRequest: graalpython/2874
2 parents 5957c70 + dc68f72 commit 7d14b00

File tree

8 files changed

+181
-143
lines changed

8 files changed

+181
-143
lines changed

graalpython/com.oracle.graal.python.test/src/tests/test_standalone.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ def test_polyglot_app():
101101

102102
with tempfile.TemporaryDirectory() as tmpdir:
103103

104-
target_dir = os.path.join(tmpdir, "polyglot_jp_app")
104+
target_dir = os.path.join(tmpdir, "polyglot_app_test")
105105

106106
cmd = [graalpy, "-m", "standalone", "--verbose", "polyglot_app", "-o", target_dir]
107107
p = subprocess.run(cmd, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
@@ -117,7 +117,7 @@ def test_polyglot_app():
117117
print(p.stderr.decode())
118118
assert "BUILD SUCCESS" in out
119119

120-
cmd = [os.path.join(target_dir, "target", "java_python_app")]
120+
cmd = [os.path.join(target_dir, "target", "polyglot_app")]
121121
p = subprocess.run(cmd, cwd=target_dir, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
122122
out = p.stdout.decode()
123123
print(out)
@@ -131,7 +131,7 @@ def test_polyglot_app():
131131
print(p.stderr.decode())
132132
assert "BUILD SUCCESS" in out
133133

134-
cmd = [java, "-jar", os.path.join(target_dir, "target", "java_python_app-1.0-SNAPSHOT.jar")]
134+
cmd = [java, "-jar", os.path.join(target_dir, "target", "polyglot_app-1.0-SNAPSHOT.jar")]
135135
p = subprocess.run(cmd, cwd=target_dir, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
136136
out = p.stdout.decode()
137137
print(out)

graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_lib2to3.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,6 @@
505505
*lib2to3.tests.test_parser.TestParserIdempotency.test_all_project_files
506506
*lib2to3.tests.test_parser.TestParserIdempotency.test_extended_unpacking
507507
*lib2to3.tests.test_parser.TestPgen2Caching.test_load_grammar_from_pickle
508-
*lib2to3.tests.test_parser.TestPgen2Caching.test_load_grammar_from_subprocess
509508
*lib2to3.tests.test_parser.TestPgen2Caching.test_load_grammar_from_txt_file
510509
*lib2to3.tests.test_parser.TestPgen2Caching.test_load_packaged_grammar
511510
*lib2to3.tests.test_parser.TestPickleableException.test_ParseError

graalpython/lib-graalpython/modules/standalone/__main__.py

Lines changed: 111 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@
5252
import argparse
5353
import io
5454
import os
55-
import re
5655
import shutil
5756
import subprocess
5857
import sys
@@ -62,16 +61,43 @@
6261

6362
assert sys.pycache_prefix is None
6463

65-
JAVA_LAUNCHER = "Py2BinLauncher"
66-
JAVA_LAUNCHER_FILE = f"{JAVA_LAUNCHER}.java"
67-
JAVA_LAUNCHER_PATH = f"launcher/{JAVA_LAUNCHER_FILE}"
64+
MVN_COMPILER_SOURCE = "17"
65+
MVN_COMPILER_TARGET = "17"
66+
MVN_JAR_PLUGIN = "3.1.0"
67+
MVN_GRAAL_SDK_VERSION = "23.0.0"
68+
MVN_NATIVE_IMAGE_MVN_PLUGIN = "0.9.23"
69+
70+
MVN_POM_FILE = "pom.xml"
71+
72+
VFS_PREFIX = "vfs"
73+
VFS_HOME = "home"
74+
VFS_HOME_PREFIX = f"{VFS_PREFIX}/{VFS_HOME}"
75+
VFS_VENV_PREFIX = VFS_PREFIX + "/venv"
76+
VFS_PROJ_PREFIX = VFS_PREFIX + "/proj"
77+
78+
VFS_JAVA_PKG = "package com.mycompany.javapython;"
79+
80+
VFS_JAVA_FILE = "VirtualFileSystem.java"
81+
VFS_JAVA_FILE_TEMPLATE = f"templates/{VFS_JAVA_FILE}"
82+
83+
JAVA_BINDING_LAUNCHER = "Py2BinLauncher"
84+
JAVA_BINDING_LAUNCHER_FILE = f"{JAVA_BINDING_LAUNCHER}.java"
85+
JAVA_BINDING_LAUNCHER_TEMPLATE_PATH = f"templates/{JAVA_BINDING_LAUNCHER_FILE}"
86+
JAVA_BINDING_POM_TEMPLATE_PATH = "templates/java_bindings_pom.xml"
87+
88+
NATIVE_EXEC_LAUNCHER = JAVA_BINDING_LAUNCHER
89+
90+
POLYGLOT_APP_LAUNCHER_FILE = "Main.java"
91+
POLYGLOT_APP_LAUNCHER_TEMPLATE_PATH = f"templates/{POLYGLOT_APP_LAUNCHER_FILE}"
92+
POLYGLOT_APP_POM_TEMPLATE_PATH = "templates/polyglot_app_pom.xml"
6893

69-
VIRTUAL_FILESYSTEM_TEMPLATE_FILE = "VirtualFileSystem.java"
70-
VIRTUAL_FILESYSTEM_TEMPLATE_PATH = f"shared/{VIRTUAL_FILESYSTEM_TEMPLATE_FILE}"
7194
NATIVE_IMAGE_PROXY_CONF_PATH = f"shared/native-image-proxy-configuration.json"
7295
NATIVE_IMAGE_RESOURCES_FILE = "native-image-resources.json"
7396
NATIVE_IMAGE_RESOURCES_PATH = f"shared/{NATIVE_IMAGE_RESOURCES_FILE}"
7497

98+
FILES_LIST_NAME = "fileslist.txt"
99+
FILES_LIST_PATH = VFS_PREFIX + "/" + FILES_LIST_NAME
100+
75101
CMD_NATIVE_EXECUTABLE = "native"
76102
CMD_JAVA_BINDINGS = "java_bindings"
77103
CMD_JAVA_PYTHON_APP = "polyglot_app"
@@ -80,46 +106,66 @@
80106
MVN_CODE_PREFIX = "src/main/java"
81107
MVN_RESOURCE_PREFIX = "src/main/resources"
82108

109+
def get_file(*paths):
110+
return os.path.join(os.path.dirname(__file__), *paths)
111+
83112
class AbstractStandalone:
84113

85114
def __init__(self, parsed_args):
86115
self.parsed_args = parsed_args
87-
self.virtual_filesystem_template = self.get_file(VIRTUAL_FILESYSTEM_TEMPLATE_PATH)
88-
vfs_prefix, vfs_fileslist_path = self.parse_vfs_prefix_constant()
89-
self.vfs_prefix = vfs_prefix
90-
self.vfs_fileslist_path = vfs_fileslist_path
91116

92117
@abc.abstractmethod
93118
def create(self):
94119
pass
95120

96-
@staticmethod
97-
def get_file(*paths):
98-
return os.path.join(os.path.dirname(__file__), *paths)
99-
100-
def create_virtual_filesystem_file(self, target_file, java_pkg=""):
101-
lines = open(self.virtual_filesystem_template, 'r').readlines()
102-
with open(target_file, 'w') as f:
121+
def create_virtual_filesystem_file(self, vfs_file, java_pkg=""):
122+
lines = open(get_file(VFS_JAVA_FILE_TEMPLATE), 'r').readlines()
123+
with open(vfs_file, 'w') as f:
103124
for line in lines:
104125
if "{java-pkg}" in line:
105126
line = line.replace("{java-pkg}", java_pkg)
127+
if "{vfs-prefix}" in line:
128+
line = line.replace("{vfs-prefix}", VFS_PREFIX)
129+
if "{files-list-name}" in line:
130+
line = line.replace("{files-list-name}", FILES_LIST_NAME)
106131
f.write(line)
107-
108-
def parse_vfs_prefix_constant(self):
109-
"""
110-
Determine the vitual filesystem prefix.
111-
"""
112-
113-
with open(self.virtual_filesystem_template) as f:
114-
content = f.read()
115-
vfs_prefix = re.search(
116-
'static final String VFS_PREFIX = "/([^"]+)"', content
117-
).group(1)
118-
fileslist_path = re.search(
119-
'static final String FILES_LIST_PATH = "/([^"]+)"', content
120-
).group(1)
121-
return vfs_prefix, fileslist_path
122-
132+
133+
def create_pom_file(self, template, pom):
134+
lines = open(template, 'r').readlines()
135+
with open(pom, 'w') as f:
136+
for line in lines:
137+
if "{mvn-compiler-source}" in line:
138+
line = line.replace("{mvn-compiler-source}", MVN_COMPILER_SOURCE)
139+
if "{mvn-compiler-target}" in line:
140+
line = line.replace("{mvn-compiler-target}", MVN_COMPILER_TARGET)
141+
if "{mvn-jar-plugin}" in line:
142+
line = line.replace("{mvn-jar-plugin}", MVN_JAR_PLUGIN)
143+
if "{graal-sdk-version}" in line:
144+
line = line.replace("{graal-sdk-version}", MVN_GRAAL_SDK_VERSION)
145+
if "{native-image-mvn-plugin}" in line:
146+
line = line.replace("{native-image-mvn-plugin}", MVN_NATIVE_IMAGE_MVN_PLUGIN)
147+
if "{vfs-prefix}" in line:
148+
line = line.replace("{vfs-prefix}", VFS_PREFIX)
149+
if "{vfs-home-prefix}" in line:
150+
line = line.replace("{vfs-home-prefix}", VFS_HOME_PREFIX)
151+
if "{vfs-venv-prefix}" in line:
152+
line = line.replace("{vfs-venv-prefix}", VFS_VENV_PREFIX)
153+
if "{files-list-name}" in line:
154+
line = line.replace("{files-list-name}", FILES_LIST_NAME)
155+
f.write(line)
156+
157+
def create_launcher_file(self, template, launcher):
158+
lines = open(template, 'r').readlines()
159+
with open(launcher, 'w') as f:
160+
for line in lines:
161+
if "{vfs-home-prefix}" in line:
162+
line = line.replace("{vfs-home-prefix}", VFS_HOME_PREFIX)
163+
if "{vfs-venv-prefix}" in line:
164+
line = line.replace("{vfs-venv-prefix}", VFS_VENV_PREFIX)
165+
if "{vfs-proj-prefix}" in line:
166+
line = line.replace("{vfs-proj-prefix}", VFS_PROJ_PREFIX)
167+
f.write(line)
168+
123169
def check_output_directory(self):
124170
if hasattr(self.parsed_args, "module") and os.path.abspath(self.parsed_args.output_directory).startswith(os.path.abspath(self.parsed_args.module)):
125171
print(
@@ -150,75 +196,46 @@ def create(self):
150196
# java sources
151197
shutil.copytree(os.path.join(os.path.dirname(__file__), "app/src"), os.path.join(target_dir, "src"))
152198

153-
virtual_filesystem_java_file = os.path.join(target_dir, MVN_CODE_PREFIX, "com", "mycompany", "javapython", VIRTUAL_FILESYSTEM_TEMPLATE_FILE)
154-
self.create_virtual_filesystem_file(virtual_filesystem_java_file, "package com.mycompany.javapython;")
199+
virtual_filesystem_java_file = os.path.join(target_dir, MVN_CODE_PREFIX, "com", "mycompany", "javapython", VFS_JAVA_FILE)
200+
self.create_virtual_filesystem_file(virtual_filesystem_java_file, VFS_JAVA_PKG)
201+
202+
launcher_java_file = os.path.join(target_dir, MVN_CODE_PREFIX, "com", "mycompany", "javapython", POLYGLOT_APP_LAUNCHER_FILE)
203+
self.create_launcher_file(get_file(POLYGLOT_APP_LAUNCHER_TEMPLATE_PATH), launcher_java_file)
155204

156205
# std lib
157-
vfs_home = os.path.join(target_dir, MVN_RESOURCE_PREFIX, self.vfs_prefix, "home")
206+
vfs_home = os.path.join(target_dir, MVN_RESOURCE_PREFIX, VFS_PREFIX, VFS_HOME)
158207
os.makedirs(vfs_home, exist_ok=True)
159208
shutil.copytree(__graalpython__.capi_home, os.path.join(vfs_home, "lib-graalpython"))
160209
shutil.copytree(__graalpython__.stdlib_home, os.path.join(vfs_home, "lib-python", "3"))
161210

162211
# misc
163-
shutil.copy(os.path.join(os.path.dirname(__file__), NATIVE_IMAGE_RESOURCES_PATH), target_dir)
164-
shutil.copy(os.path.join(os.path.dirname(__file__), NATIVE_IMAGE_PROXY_CONF_PATH), target_dir)
165-
shutil.copy(os.path.join(os.path.dirname(__file__), "app/pom.xml"), target_dir)
166-
212+
shutil.copy(get_file(NATIVE_IMAGE_RESOURCES_PATH), target_dir)
213+
shutil.copy(get_file(NATIVE_IMAGE_PROXY_CONF_PATH), target_dir)
214+
self.create_pom_file(get_file(POLYGLOT_APP_POM_TEMPLATE_PATH), os.path.join(target_dir, MVN_POM_FILE))
215+
167216
class Standalone(AbstractStandalone):
168217
def __init__(self, parsed_args):
169218
super().__init__(parsed_args)
170-
self.parsed_args = parsed_args
171-
172-
self.java_launcher_template = self.get_file(JAVA_LAUNCHER_PATH)
173-
174-
(home_prefix, venv_prefix, proj_prefix,) = self.parse_standalone_path_constants(self.java_launcher_template)
175-
self.home_prefix = home_prefix
176-
self.venv_prefix = venv_prefix
177-
self.proj_prefix = proj_prefix
178-
179-
def parse_standalone_path_constants(self, javafile):
180-
"""
181-
Determine the constants used by the Java launcher pertaining to the layout
182-
of the resources file.
183-
"""
184-
185-
with open(javafile) as f:
186-
content = f.read()
187-
188-
home_prefix = re.search(
189-
r'static final String HOME_PREFIX = VirtualFileSystem\.VFS_PREFIX \+ "/([^"]+)"', content
190-
).group(1)
191-
venv_prefix = re.search(
192-
r'static final String VENV_PREFIX = VirtualFileSystem\.VFS_PREFIX \+ "/([^"]+)"', content
193-
).group(1)
194-
proj_prefix = re.search(
195-
r'static final String PROJ_PREFIX = VirtualFileSystem\.VFS_PREFIX \+ "/([^"]+)"', content
196-
).group(1)
197-
return home_prefix, venv_prefix, proj_prefix
198219

199220
def create_target_directory(self):
200221
if self.parsed_args.verbose:
201222
print(f"Bundling Python resources into {self.target_dir}")
202223

203224
self.bundle_python_resources(
204-
os.path.join(self.target_dir, self.resource_prefix),
205-
self.vfs_prefix,
206-
self.home_prefix,
207-
self.venv_prefix,
208-
self.proj_prefix,
225+
os.path.join(self.target_dir, self.mvn_resource_prefix),
209226
self.parsed_args.module,
210227
self.parsed_args.venv,
211228
)
212229

213230
os.makedirs(os.path.dirname(self.launcher_file), exist_ok=True)
214-
shutil.copy(self.java_launcher_template, self.launcher_file)
231+
self.create_launcher_file(get_file(JAVA_BINDING_LAUNCHER_TEMPLATE_PATH), self.launcher_file)
215232

216-
virtual_filesystem_java_file = os.path.join(self.target_dir, self.code_prefix, VIRTUAL_FILESYSTEM_TEMPLATE_FILE)
233+
virtual_filesystem_java_file = os.path.join(self.target_dir, self.mvn_code_prefix, VFS_JAVA_FILE)
217234
self.create_virtual_filesystem_file(virtual_filesystem_java_file)
218235

219-
shutil.copy(self.get_file(NATIVE_IMAGE_RESOURCES_PATH), os.path.join(self.target_dir, NATIVE_IMAGE_RESOURCES_FILE))
236+
shutil.copy(get_file(NATIVE_IMAGE_RESOURCES_PATH), os.path.join(self.target_dir, NATIVE_IMAGE_RESOURCES_FILE))
220237

221-
def bundle_python_resources(self, target_dir, vfs_prefix, home_prefix, venv_prefix, proj_prefix, project, venv=None):
238+
def bundle_python_resources(self, target_dir, project, venv=None):
222239
"""
223240
Copy the Python core, stdlib, venv, and module into one folder.
224241
"""
@@ -228,28 +245,28 @@ def bundle_python_resources(self, target_dir, vfs_prefix, home_prefix, venv_pref
228245
self.copy_folder_to_target(
229246
target_dir,
230247
__graalpython__.capi_home,
231-
f"{vfs_prefix}/{home_prefix}/lib-graalpython",
248+
f"{VFS_HOME_PREFIX}/lib-graalpython",
232249
path_filter=lambda file=None, dir=None: file and file.endswith(".py"),
233250
)
234251

235252
self.copy_folder_to_target(
236253
target_dir,
237254
__graalpython__.stdlib_home,
238-
f"{vfs_prefix}/{home_prefix}/lib-python/3",
255+
f"{VFS_HOME_PREFIX}/lib-python/3",
239256
path_filter=lambda file=None, dir=None: dir
240257
and dir in ["idlelib", "ensurepip", "tkinter", "turtledemo"],
241258
)
242259

243-
if venv:
244-
self.copy_folder_to_target(target_dir, venv, f"{vfs_prefix}/{venv_prefix}")
260+
if venv:
261+
self.copy_folder_to_target(target_dir, venv, VFS_VENV_PREFIX)
245262

246263
if project and os.path.isdir(project):
247-
self.copy_folder_to_target(target_dir, project, f"{vfs_prefix}/{proj_prefix}")
264+
self.copy_folder_to_target(target_dir, project, VFS_PROJ_PREFIX)
248265
else:
249266
with tempfile.TemporaryDirectory() as tmpdir:
250267
name = os.path.join(tmpdir, "__main__.py")
251268
shutil.copy(project, name)
252-
self.copy_folder_to_target(target_dir, tmpdir, f"{vfs_prefix}/{proj_prefix}")
269+
self.copy_folder_to_target(target_dir, tmpdir, VFS_PROJ_PREFIX)
253270
os.unlink(name)
254271

255272
def copy_folder_to_target(self, resource_root, folder, prefix, path_filter=lambda file=None, dir=None: False):
@@ -294,32 +311,32 @@ def __init__(self, parsed_args):
294311
super().__init__(parsed_args)
295312

296313
self.target_dir = parsed_args.output_directory
297-
self.code_prefix = MVN_CODE_PREFIX
298-
self.resource_prefix = MVN_RESOURCE_PREFIX
299-
self.launcher_file = os.path.join(self.target_dir, self.code_prefix, JAVA_LAUNCHER_FILE)
314+
self.mvn_code_prefix = MVN_CODE_PREFIX
315+
self.mvn_resource_prefix = MVN_RESOURCE_PREFIX
316+
self.launcher_file = os.path.join(self.target_dir, self.mvn_code_prefix, JAVA_BINDING_LAUNCHER_FILE)
300317

301318
def create(self):
302319
self.check_output_directory()
303320

304321
os.makedirs(self.target_dir, exist_ok=True)
305322
self.create_target_directory()
306-
shutil.copy(os.path.join(os.path.dirname(__file__), "launcher", "pom.xml"), self.target_dir)
323+
self.create_pom_file(get_file(JAVA_BINDING_POM_TEMPLATE_PATH), os.path.join(self.target_dir, MVN_POM_FILE))
307324

308325
class NativeExecutable(Standalone):
309326

310327
def __init__(self, parsed_args):
311328
super().__init__(parsed_args)
312329

313330
self.target_dir = tempfile.mkdtemp()
314-
self.code_prefix = ""
315-
self.resource_prefix = ""
316-
self.launcher_file = os.path.join(self.target_dir, self.code_prefix, JAVA_LAUNCHER_FILE)
331+
self.mvn_code_prefix = ""
332+
self.mvn_resource_prefix = ""
333+
self.launcher_file = os.path.join(self.target_dir, JAVA_BINDING_LAUNCHER_FILE)
317334

318335
def create(self):
319336
try:
320337
self.create_target_directory()
321-
files_list_path = os.path.join(self.target_dir, self.vfs_fileslist_path)
322-
dir_to_list = os.path.join(self.target_dir, self.vfs_prefix)
338+
files_list_path = os.path.join(self.target_dir, FILES_LIST_PATH)
339+
dir_to_list = os.path.join(self.target_dir, VFS_PREFIX)
323340
__graalpython__.list_files(dir_to_list, files_list_path)
324341
self.build_binary()
325342
finally:
@@ -390,12 +407,13 @@ def build_binary(self):
390407
"-Dpolyglot.engine.WarnInterpreterOnly=false",
391408
]
392409
cmd += [
410+
"--no-fallback",
393411
"--language:python",
394412
"-H:-CopyLanguageResources",
395413
"-H:ResourceConfigurationFiles=native-image-resources.json",
396414
"-o",
397415
output,
398-
JAVA_LAUNCHER,
416+
NATIVE_EXEC_LAUNCHER,
399417
]
400418
if self.parsed_args.verbose:
401419
print(f"Building Python standalone binary: {' '.join(cmd)}")
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@
5050
import org.graalvm.polyglot.Value;
5151

5252
public class Main {
53-
private static final String HOME_PREFIX = VirtualFileSystem.VFS_PREFIX + "/home";
54-
private static final String PROJ_PREFIX = VirtualFileSystem.VFS_PREFIX + "/proj";
55-
private static final String VENV_PREFIX = VirtualFileSystem.VFS_PREFIX + "/venv";
53+
private static final String HOME_PREFIX = "/{vfs-home-prefix}";
54+
private static final String VENV_PREFIX = "/{vfs-venv-prefix}";
55+
private static final String PROJ_PREFIX = "/{vfs-proj-prefix}";
5656

5757
private static String PYTHON = "python";
5858

graalpython/lib-graalpython/modules/standalone/launcher/Py2BinLauncher.java renamed to graalpython/lib-graalpython/modules/standalone/templates/Py2BinLauncher.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,9 @@
7979
* filesystem, as well as showing how to embed Python code into a single native image binary.
8080
*/
8181
public class Py2BinLauncher {
82-
private static final String HOME_PREFIX = VirtualFileSystem.VFS_PREFIX + "/home";
83-
private static final String VENV_PREFIX = VirtualFileSystem.VFS_PREFIX + "/venv";
84-
private static final String PROJ_PREFIX = VirtualFileSystem.VFS_PREFIX + "/proj";
82+
private static final String HOME_PREFIX = "/{vfs-home-prefix}";
83+
private static final String VENV_PREFIX = "/{vfs-venv-prefix}";
84+
private static final String PROJ_PREFIX = "/{vfs-proj-prefix}";
8585

8686
public static void main(String[] args) throws IOException {
8787
var builder = Context.newBuilder()

0 commit comments

Comments
 (0)