Skip to content

Commit 037946d

Browse files
[3.10] pythongh-130025: Correct handling of symlinks during iOS testbed framework installation. (pythonGH-130026) (python#130073)
Correct handling of symlinks during iOS testbed framework installation. (cherry picked from commit 625470a) Co-authored-by: Russell Keith-Magee <[email protected]>
1 parent fc51691 commit 037946d

File tree

2 files changed

+47
-9
lines changed

2 files changed

+47
-9
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
The iOS testbed now correctly handles symlinks used as Python framework
2+
references.

iOS/testbed/__main__.py

+45-9
Original file line numberDiff line numberDiff line change
@@ -242,33 +242,69 @@ def clone_testbed(
242242
shutil.copytree(source, target, symlinks=True)
243243
print(" done")
244244

245+
xc_framework_path = target / "Python.xcframework"
246+
sim_framework_path = xc_framework_path / "ios-arm64_x86_64-simulator"
245247
if framework is not None:
246248
if framework.suffix == ".xcframework":
247249
print(" Installing XCFramework...", end="", flush=True)
248-
xc_framework_path = (target / "Python.xcframework").resolve()
249250
if xc_framework_path.is_dir():
250251
shutil.rmtree(xc_framework_path)
251252
else:
252-
xc_framework_path.unlink()
253+
xc_framework_path.unlink(missing_ok=True)
253254
xc_framework_path.symlink_to(
254255
relative_to(framework, xc_framework_path.parent)
255256
)
256257
print(" done")
257258
else:
258259
print(" Installing simulator framework...", end="", flush=True)
259-
sim_framework_path = (
260-
target / "Python.xcframework" / "ios-arm64_x86_64-simulator"
261-
).resolve()
262260
if sim_framework_path.is_dir():
263261
shutil.rmtree(sim_framework_path)
264262
else:
265-
sim_framework_path.unlink()
263+
sim_framework_path.unlink(missing_ok=True)
266264
sim_framework_path.symlink_to(
267265
relative_to(framework, sim_framework_path.parent)
268266
)
269267
print(" done")
270268
else:
271-
print(" Using pre-existing iOS framework.")
269+
if (
270+
xc_framework_path.is_symlink()
271+
and not xc_framework_path.readlink().is_absolute()
272+
):
273+
# XCFramework is a relative symlink. Rewrite the symlink relative
274+
# to the new location.
275+
print(" Rewriting symlink to XCframework...", end="", flush=True)
276+
orig_xc_framework_path = (
277+
source
278+
/ xc_framework_path.readlink()
279+
).resolve()
280+
xc_framework_path.unlink()
281+
xc_framework_path.symlink_to(
282+
orig_xc_framework_path.relative_to(
283+
xc_framework_path.parent, walk_up=True
284+
)
285+
)
286+
print(" done")
287+
elif (
288+
sim_framework_path.is_symlink()
289+
and not sim_framework_path.readlink().is_absolute()
290+
):
291+
print(" Rewriting symlink to simulator framework...", end="", flush=True)
292+
# Simulator framework is a relative symlink. Rewrite the symlink
293+
# relative to the new location.
294+
orig_sim_framework_path = (
295+
source
296+
/ "Python.XCframework"
297+
/ sim_framework_path.readlink()
298+
).resolve()
299+
sim_framework_path.unlink()
300+
sim_framework_path.symlink_to(
301+
orig_sim_framework_path.relative_to(
302+
sim_framework_path.parent, walk_up=True
303+
)
304+
)
305+
print(" done")
306+
else:
307+
print(" Using pre-existing iOS framework.")
272308

273309
for app_src in apps:
274310
print(f" Installing app {app_src.name!r}...", end="", flush=True)
@@ -384,8 +420,8 @@ def main():
384420

385421
if context.subcommand == "clone":
386422
clone_testbed(
387-
source=Path(__file__).parent,
388-
target=Path(context.location),
423+
source=Path(__file__).parent.resolve(),
424+
target=Path(context.location).resolve(),
389425
framework=Path(context.framework).resolve() if context.framework else None,
390426
apps=[Path(app) for app in context.apps],
391427
)

0 commit comments

Comments
 (0)