Skip to content

Commit a21cb31

Browse files
Merge branch 'main' into llvm-20
2 parents 2e9ba92 + ac1ffd7 commit a21cb31

File tree

6 files changed

+91
-50
lines changed

6 files changed

+91
-50
lines changed

.github/workflows/reusable-wasi.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ env:
1313
jobs:
1414
build-wasi-reusable:
1515
name: 'build and test'
16-
runs-on: ubuntu-24.04
16+
runs-on: ubuntu-24.04-arm
1717
timeout-minutes: 60
1818
env:
19-
WASMTIME_VERSION: 38.0.2
19+
WASMTIME_VERSION: 38.0.3
2020
WASI_SDK_VERSION: 25
2121
WASI_SDK_PATH: /opt/wasi-sdk
2222
CROSS_BUILD_PYTHON: cross-build/build
@@ -40,7 +40,7 @@ jobs:
4040
if: steps.cache-wasi-sdk.outputs.cache-hit != 'true'
4141
run: |
4242
mkdir "${WASI_SDK_PATH}" && \
43-
curl -s -S --location "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_VERSION}/wasi-sdk-${WASI_SDK_VERSION}.0-x86_64-linux.tar.gz" | \
43+
curl -s -S --location "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_VERSION}/wasi-sdk-${WASI_SDK_VERSION}.0-arm64-linux.tar.gz" | \
4444
tar --strip-components 1 --directory "${WASI_SDK_PATH}" --extract --gunzip
4545
- name: "Configure ccache action"
4646
uses: hendrikmuhs/ccache-action@v1.2

Lib/enum.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
'FlagBoundary', 'STRICT', 'CONFORM', 'EJECT', 'KEEP',
1111
'global_flag_repr', 'global_enum_repr', 'global_str', 'global_enum',
1212
'EnumCheck', 'CONTINUOUS', 'NAMED_FLAGS', 'UNIQUE',
13-
'pickle_by_global_name', 'pickle_by_enum_name',
13+
'pickle_by_global_name', 'pickle_by_enum_name', 'show_flag_values',
14+
'bin',
1415
]
1516

1617

Lib/test/test_enum.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5324,7 +5324,7 @@ def __new__(cls, value, label):
53245324
class MiscTestCase(unittest.TestCase):
53255325

53265326
def test__all__(self):
5327-
support.check__all__(self, enum, not_exported={'bin', 'show_flag_values'})
5327+
support.check__all__(self, enum)
53285328

53295329
@cpython_only
53305330
def test_lazy_import(self):
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Warn when the WASI SDK version doesn't match what's supported.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add :func:`enum.show_flag_values` and ``enum.bin`` to ``enum.__all__``.

Tools/wasm/wasi/__main__.py

Lines changed: 83 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,30 @@
3737
WASMTIME_HOST_RUNNER_VAR = f"{{{WASMTIME_VAR_NAME}}}"
3838

3939

40+
def separator():
41+
"""Print a separator line across the terminal width."""
42+
try:
43+
tput_output = subprocess.check_output(
44+
["tput", "cols"], encoding="utf-8"
45+
)
46+
except subprocess.CalledProcessError:
47+
terminal_width = 80
48+
else:
49+
terminal_width = int(tput_output.strip())
50+
print("⎯" * terminal_width)
51+
52+
53+
def log(emoji, message, *, spacing=None):
54+
"""Print a notification with an emoji.
55+
56+
If 'spacing' is None, calculate the spacing based on the number of code points
57+
in the emoji as terminals "eat" a space when the emoji has multiple code points.
58+
"""
59+
if spacing is None:
60+
spacing = " " if len(emoji) == 1 else " "
61+
print("".join([emoji, spacing, message]))
62+
63+
4064
def updated_env(updates={}):
4165
"""Create a new dict representing the environment to use.
4266
@@ -60,9 +84,10 @@ def updated_env(updates={}):
6084
if os.environ.get(key) != value:
6185
env_diff[key] = value
6286

63-
print("🌎 Environment changes:")
64-
for key in sorted(env_diff.keys()):
65-
print(f" {key}={env_diff[key]}")
87+
env_vars = (
88+
f"\n {key}={item}" for key, item in sorted(env_diff.items())
89+
)
90+
log("🌎", f"Environment changes:{''.join(env_vars)}")
6691

6792
return environment
6893

@@ -77,22 +102,14 @@ def wrapper(context):
77102

78103
if callable(working_dir):
79104
working_dir = working_dir(context)
80-
try:
81-
tput_output = subprocess.check_output(
82-
["tput", "cols"], encoding="utf-8"
83-
)
84-
except subprocess.CalledProcessError:
85-
terminal_width = 80
86-
else:
87-
terminal_width = int(tput_output.strip())
88-
print("⎯" * terminal_width)
89-
print("📁", working_dir)
105+
separator()
106+
log("📁", os.fsdecode(working_dir))
90107
if (
91108
clean_ok
92109
and getattr(context, "clean", False)
93110
and working_dir.exists()
94111
):
95-
print("🚮 Deleting directory (--clean)...")
112+
log("🚮", "Deleting directory (--clean)...")
96113
shutil.rmtree(working_dir)
97114

98115
working_dir.mkdir(parents=True, exist_ok=True)
@@ -116,7 +133,7 @@ def call(command, *, context=None, quiet=False, logdir=None, **kwargs):
116133
elif quiet and logdir is None:
117134
raise ValueError("When quiet is True, logdir must be specified")
118135

119-
print("❯", " ".join(map(str, command)))
136+
log("❯", " ".join(map(str, command)), spacing=" ")
120137
if not quiet:
121138
stdout = None
122139
stderr = None
@@ -130,7 +147,7 @@ def call(command, *, context=None, quiet=False, logdir=None, **kwargs):
130147
suffix=".log",
131148
)
132149
stderr = subprocess.STDOUT
133-
print(f"📝 Logging output to {stdout.name} (--quiet)...")
150+
log("📝", f"Logging output to {stdout.name} (--quiet)...")
134151

135152
subprocess.check_call(command, **kwargs, stdout=stdout, stderr=stderr)
136153

@@ -163,11 +180,11 @@ def configure_build_python(context, working_dir):
163180
"""Configure the build/host Python."""
164181
if LOCAL_SETUP.exists():
165182
if LOCAL_SETUP.read_bytes() == LOCAL_SETUP_MARKER:
166-
print(f"👍 {LOCAL_SETUP} exists ...")
183+
log("👍", f"{LOCAL_SETUP} exists ...")
167184
else:
168-
print(f"⚠️ {LOCAL_SETUP} exists, but has unexpected contents")
185+
log("⚠️", f"{LOCAL_SETUP} exists, but has unexpected contents")
169186
else:
170-
print(f"📝 Creating {LOCAL_SETUP} ...")
187+
log("📝", f"Creating {LOCAL_SETUP} ...")
171188
LOCAL_SETUP.write_bytes(LOCAL_SETUP_MARKER)
172189

173190
configure = [os.path.relpath(CHECKOUT / "configure", working_dir)]
@@ -191,30 +208,50 @@ def make_build_python(context, working_dir):
191208
]
192209
version = subprocess.check_output(cmd, encoding="utf-8").strip()
193210

194-
print(f"🎉 {binary} {version}")
211+
log("🎉", f"{binary} {version}")
195212

196213

197214
def find_wasi_sdk():
198215
"""Find the path to the WASI SDK."""
199-
if wasi_sdk_path := os.environ.get("WASI_SDK_PATH"):
200-
return pathlib.Path(wasi_sdk_path)
201-
202-
opt_path = pathlib.Path("/opt")
203-
# WASI SDK versions have a ``.0`` suffix, but it's a constant; the WASI SDK team
204-
# has said they don't plan to ever do a point release and all of their Git tags
205-
# lack the ``.0`` suffix.
206-
# Starting with WASI SDK 23, the tarballs went from containing a directory named
207-
# ``wasi-sdk-{WASI_SDK_VERSION}.0`` to e.g.
208-
# ``wasi-sdk-{WASI_SDK_VERSION}.0-x86_64-linux``.
209-
potential_sdks = [
210-
path
211-
for path in opt_path.glob(f"wasi-sdk-{WASI_SDK_VERSION}.0*")
212-
if path.is_dir()
213-
]
214-
if len(potential_sdks) == 1:
215-
return potential_sdks[0]
216-
elif (default_path := opt_path / "wasi-sdk").is_dir():
217-
return default_path
216+
wasi_sdk_path = None
217+
218+
if wasi_sdk_path_env_var := os.environ.get("WASI_SDK_PATH"):
219+
wasi_sdk_path = pathlib.Path(wasi_sdk_path_env_var)
220+
else:
221+
opt_path = pathlib.Path("/opt")
222+
# WASI SDK versions have a ``.0`` suffix, but it's a constant; the WASI SDK team
223+
# has said they don't plan to ever do a point release and all of their Git tags
224+
# lack the ``.0`` suffix.
225+
# Starting with WASI SDK 23, the tarballs went from containing a directory named
226+
# ``wasi-sdk-{WASI_SDK_VERSION}.0`` to e.g.
227+
# ``wasi-sdk-{WASI_SDK_VERSION}.0-x86_64-linux``.
228+
potential_sdks = [
229+
path
230+
for path in opt_path.glob(f"wasi-sdk-{WASI_SDK_VERSION}.0*")
231+
if path.is_dir()
232+
]
233+
if len(potential_sdks) == 1:
234+
wasi_sdk_path = potential_sdks[0]
235+
elif (default_path := opt_path / "wasi-sdk").is_dir():
236+
wasi_sdk_path = default_path
237+
238+
# Starting with WASI SDK 25, a VERSION file is included in the root
239+
# of the SDK directory that we can read to warn folks when they are using
240+
# an unsupported version.
241+
if wasi_sdk_path and (version_file := wasi_sdk_path / "VERSION").is_file():
242+
version_details = version_file.read_text(encoding="utf-8")
243+
found_version = version_details.splitlines()[0]
244+
# Make sure there's a trailing dot to avoid false positives if somehow the
245+
# supported version is a prefix of the found version (e.g. `25` and `2567`).
246+
if not found_version.startswith(f"{WASI_SDK_VERSION}."):
247+
major_version = found_version.partition(".")[0]
248+
log(
249+
"⚠️",
250+
f" Found WASI SDK {major_version}, "
251+
f"but WASI SDK {WASI_SDK_VERSION} is the supported version",
252+
)
253+
254+
return wasi_sdk_path
218255

219256

220257
def wasi_sdk_env(context):
@@ -330,7 +367,7 @@ def configure_wasi_python(context, working_dir):
330367
with exec_script.open("w", encoding="utf-8") as file:
331368
file.write(f'#!/bin/sh\nexec {host_runner} {python_wasm} "$@"\n')
332369
exec_script.chmod(0o755)
333-
print(f"🏃‍♀️ Created {exec_script} (--host-runner)... ")
370+
log("🏃", f"Created {exec_script} (--host-runner)... ")
334371
sys.stdout.flush()
335372

336373

@@ -345,9 +382,10 @@ def make_wasi_python(context, working_dir):
345382

346383
exec_script = working_dir / "python.sh"
347384
call([exec_script, "--version"], quiet=False)
348-
print(
349-
f"🎉 Use `{exec_script.relative_to(context.init_dir)}` "
350-
"to run CPython w/ the WASI host specified by --host-runner"
385+
log(
386+
"🎉",
387+
f"Use `{exec_script.relative_to(context.init_dir)}` "
388+
"to run CPython w/ the WASI host specified by --host-runner",
351389
)
352390

353391

@@ -366,12 +404,12 @@ def build_all(context):
366404
def clean_contents(context):
367405
"""Delete all files created by this script."""
368406
if CROSS_BUILD_DIR.exists():
369-
print(f"🧹 Deleting {CROSS_BUILD_DIR} ...")
407+
log("🧹", f"Deleting {CROSS_BUILD_DIR} ...")
370408
shutil.rmtree(CROSS_BUILD_DIR)
371409

372410
if LOCAL_SETUP.exists():
373411
if LOCAL_SETUP.read_bytes() == LOCAL_SETUP_MARKER:
374-
print(f"🧹 Deleting generated {LOCAL_SETUP} ...")
412+
log("🧹", f"Deleting generated {LOCAL_SETUP} ...")
375413

376414

377415
def main():

0 commit comments

Comments
 (0)