Skip to content

Commit cfd8b4e

Browse files
authored
3.13 update (#292)
* Updates Python patch to 3.13.3 * Adds handling for .xcprivacy and .dSYM handling.
1 parent 594b180 commit cfd8b4e

File tree

10 files changed

+195
-34
lines changed

10 files changed

+195
-34
lines changed

.github/workflows/ci.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ jobs:
105105
- uses: actions/[email protected]
106106

107107
- name: Set up Python
108-
uses: actions/setup-python@v5.4.0
108+
uses: actions/setup-python@v5.6.0
109109
with:
110110
# Appending -dev ensures that we can always build the dev release.
111111
# It's a no-op for versions that have been published.
@@ -120,7 +120,7 @@ jobs:
120120
make ${{ matrix.target }} BUILD_NUMBER=${{ needs.config.outputs.BUILD_NUMBER }}
121121
122122
- name: Upload build artefacts
123-
uses: actions/[email protected].1
123+
uses: actions/[email protected].2
124124
with:
125125
name: Python-${{ needs.config.outputs.PYTHON_VER }}-${{ matrix.target }}-support.${{ needs.config.outputs.BUILD_NUMBER }}.tar.gz
126126
path: dist/Python-${{ needs.config.outputs.PYTHON_VER }}-${{ matrix.target }}-support.${{ needs.config.outputs.BUILD_NUMBER }}.tar.gz

.github/workflows/publish.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
- uses: actions/checkout@v4
1212

1313
- name: Set up Python environment
14-
uses: actions/setup-python@v5.4.0
14+
uses: actions/setup-python@v5.6.0
1515
with:
1616
python-version: "3.X"
1717

@@ -48,3 +48,6 @@ jobs:
4848
# watchOS build
4949
curl -o watchOS-artefact.tar.gz -L https://github.com/beeware/Python-Apple-support/releases/download/${{ steps.build-vars.outputs.TAG }}/Python-${{ steps.build-vars.outputs.PYTHON_VER }}-watchOS-support.${{ steps.build-vars.outputs.BUILD_NUMBER }}.tar.gz
5050
aws s3 cp watchOS-artefact.tar.gz s3://briefcase-support/python/${{ steps.build-vars.outputs.PYTHON_VER }}/watchOS/Python-${{ steps.build-vars.outputs.PYTHON_VER }}-watchOS-support.${{ steps.build-vars.outputs.BUILD_NUMBER }}.tar.gz
51+
# visionOS build
52+
curl -o visionOS-artefact.tar.gz -L https://github.com/beeware/Python-Apple-support/releases/download/${{ steps.build-vars.outputs.TAG }}/Python-${{ steps.build-vars.outputs.PYTHON_VER }}-visionOS-support.${{ steps.build-vars.outputs.BUILD_NUMBER }}.tar.gz
53+
aws s3 cp visionOS-artefact.tar.gz s3://briefcase-support/python/${{ steps.build-vars.outputs.PYTHON_VER }}/visionOS/Python-${{ steps.build-vars.outputs.PYTHON_VER }}-visionOS-support.${{ steps.build-vars.outputs.BUILD_NUMBER }}.tar.gz

.github/workflows/release.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ jobs:
4040
needs: [ config, ci ]
4141
steps:
4242
- name: Get build artifacts
43-
uses: actions/download-artifact@v4.1.9
43+
uses: actions/download-artifact@v4.3.0
4444
with:
4545
pattern: Python-*
4646
path: dist

CONTRIBUTING.md

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,44 @@
22

33
BeeWare <3's contributions!
44

5-
Please be aware, BeeWare operates under a Code of Conduct.
5+
Please be aware that BeeWare operates under a [Code of
6+
Conduct](https://beeware.org/community/behavior/code-of-conduct/).
67

7-
See [CONTRIBUTING to BeeWare](https://beeware.org/contributing) for details.
8+
See [CONTRIBUTING to BeeWare](https://beeware.org/contributing) for general
9+
project contribution guidelines.
810

11+
Unless a fix is version specific, PRs should genereally be made against the
12+
`main` branch of this repo, targeting the current development version of Python.
13+
Project maintainers will manage the process of backporting changes to older
14+
Python versions.
15+
16+
## Changes to `Python.patch`
17+
18+
Additional handling is required if you need to make modifications to the patch
19+
applied to Python sources (`patch/Python/Python.patch`).
20+
21+
Any iOS or macOS-specific changes should be submitted to the [upstream CPython
22+
repository](https://github.com/python/cpython). macOS and iOS are both
23+
officially supported Python platforms, and the code distributed by this project
24+
for those platforms is unmodified from the official repository.
25+
26+
Changes to to support other platforms can be included in a PR for this repo, but
27+
they must also be submitted as a pull request against the `MAJOR.MINOR-patched`
28+
branch on [the `freakboy3742` fork of the CPython
29+
repo](https://github.com/freakboy3742/cpython). This is required to ensure that
30+
any contributed changes can be easily reproduced in future patches as more
31+
changes are made.
32+
33+
Note that the `MAJOR.MINOR-patched` branch of that fork is maintained in the format
34+
of a *patch tree*, which is a branch that consists of an entirely linear sequence of
35+
commits applied on top of another branch (in the case of the fork, `MAJOR.MINOR`),
36+
each of which adds a significant new feature. Therefore, a bug fix for an existing commit
37+
in the patch tree *will* be merged when appropriate, but its changes will get combined
38+
with that existing commit that adds the feature. A feature addition PR will be squashed
39+
into a single, new commit, and then put on top of the patch tree.
40+
41+
This also means that if another contributor gets a pull request merged into
42+
`MAJOR.MINOR-patched`, you must *rebase* your changes on top of the updated
43+
`MAJOR.MINOR-patched` branch, as opposed to *merging* `MAJOR.MINOR-patched` into your
44+
branch, since the "history" of a patch tree is likely to change in a way that is
45+
incompatible with merge commits.

Makefile

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,24 +33,28 @@ OPENSSL_VERSION=3.0.16-2
3333
XZ_VERSION=5.6.4-2
3434

3535
# Supported OS
36-
OS_LIST=macOS iOS tvOS watchOS
36+
OS_LIST=macOS iOS tvOS watchOS visionOS
3737

3838
CURL_FLAGS=--disable --fail --location --create-dirs --progress-bar
3939

4040
# macOS targets
4141
TARGETS-macOS=macosx.x86_64 macosx.arm64
42+
TRIPLE_OS-macOS=macos
4243
VERSION_MIN-macOS=11.0
4344

4445
# iOS targets
4546
TARGETS-iOS=iphonesimulator.x86_64 iphonesimulator.arm64 iphoneos.arm64
47+
TRIPLE_OS-iOS=ios
4648
VERSION_MIN-iOS=13.0
4749

4850
# tvOS targets
4951
TARGETS-tvOS=appletvsimulator.x86_64 appletvsimulator.arm64 appletvos.arm64
52+
TRIPLE_OS-tvOS=tvos
5053
VERSION_MIN-tvOS=12.0
5154

5255
# watchOS targets
5356
TARGETS-watchOS=watchsimulator.x86_64 watchsimulator.arm64 watchos.arm64_32
57+
TRIPLE_OS-watchOS=watchos
5458
VERSION_MIN-watchOS=4.0
5559

5660
# The architecture of the machine doing the build
@@ -128,10 +132,10 @@ ARCH-$(target)=$$(subst .,,$$(suffix $(target)))
128132

129133
ifneq ($(os),macOS)
130134
ifeq ($$(findstring simulator,$$(SDK-$(target))),)
131-
TARGET_TRIPLE-$(target)=$$(ARCH-$(target))-apple-$$(OS_LOWER-$(target))$$(VERSION_MIN-$(os))
135+
TARGET_TRIPLE-$(target)=$$(ARCH-$(target))-apple-$$(TRIPLE_OS-$(os))$$(VERSION_MIN-$(os))
132136
IS_SIMULATOR-$(target)=False
133137
else
134-
TARGET_TRIPLE-$(target)=$$(ARCH-$(target))-apple-$$(OS_LOWER-$(target))$$(VERSION_MIN-$(os))-simulator
138+
TARGET_TRIPLE-$(target)=$$(ARCH-$(target))-apple-$$(TRIPLE_OS-$(os))$$(VERSION_MIN-$(os))-simulator
135139
IS_SIMULATOR-$(target)=True
136140
endif
137141
endif
@@ -398,15 +402,13 @@ define build-sdk
398402
sdk=$1
399403
os=$2
400404

401-
OS_LOWER-$(sdk)=$(shell echo $(os) | tr '[:upper:]' '[:lower:]')
402-
403405
SDK_TARGETS-$(sdk)=$$(filter $(sdk).%,$$(TARGETS-$(os)))
404406
SDK_ARCHES-$(sdk)=$$(sort $$(subst .,,$$(suffix $$(SDK_TARGETS-$(sdk)))))
405407

406408
ifeq ($$(findstring simulator,$(sdk)),)
407-
SDK_SLICE-$(sdk)=$$(OS_LOWER-$(sdk))-$$(shell echo $$(SDK_ARCHES-$(sdk)) | sed "s/ /_/g")
409+
SDK_SLICE-$(sdk)=$$(TRIPLE_OS-$(os))-$$(shell echo $$(SDK_ARCHES-$(sdk)) | sed "s/ /_/g")
408410
else
409-
SDK_SLICE-$(sdk)=$$(OS_LOWER-$(sdk))-$$(shell echo $$(SDK_ARCHES-$(sdk)) | sed "s/ /_/g")-simulator
411+
SDK_SLICE-$(sdk)=$$(TRIPLE_OS-$(os))-$$(shell echo $$(SDK_ARCHES-$(sdk)) | sed "s/ /_/g")-simulator
410412
endif
411413

412414
# Expand the build-target macro for target on this OS
@@ -450,6 +452,7 @@ $$(PYTHON_LIB-$(sdk)): $$(foreach target,$$(SDK_TARGETS-$(sdk)),$$(PYTHON_LIB-$$
450452
mkdir -p $$(dir $$(PYTHON_LIB-$(sdk)))
451453
lipo -create -output $$@ $$^ \
452454
2>&1 | tee -a install/$(os)/$(sdk)/python-$(PYTHON_VERSION).lipo.log
455+
dsymutil $$@ -o $$(PYTHON_INSTALL-$(sdk))/Python.dSYM
453456

454457
$$(PYTHON_FRAMEWORK-$(sdk))/Info.plist: $$(PYTHON_LIB-$(sdk))
455458
@echo ">>> Install Info.plist for the $(sdk) SDK"
@@ -481,11 +484,15 @@ $$(PYTHON_INCLUDE-$(sdk))/pyconfig.h: $$(PYTHON_LIB-$(sdk))
481484
mkdir -p $$(PYTHON_INSTALL-$(sdk))/include
482485
ln -si ../Python.framework/Headers $$(PYTHON_INSTALL-$(sdk))/include/python$(PYTHON_VER)
483486

487+
ifeq ($(os), visionOS)
488+
echo "Skipping arch-specific header copying for visionOS"
489+
else
484490
# Add the individual headers from each target in an arch-specific name
485491
$$(foreach target,$$(SDK_TARGETS-$(sdk)),cp $$(PYTHON_INCLUDE-$$(target))/pyconfig.h $$(PYTHON_INCLUDE-$(sdk))/pyconfig-$$(ARCH-$$(target)).h; )
486492

487493
# Copy the cross-target header from the source folder of the first target in the $(sdk) SDK
488494
cp $$(PYTHON_SRCDIR-$$(firstword $$(SDK_TARGETS-$(sdk))))/$(os)/Resources/pyconfig.h $$(PYTHON_INCLUDE-$(sdk))/pyconfig.h
495+
endif
489496

490497

491498
$$(PYTHON_STDLIB-$(sdk))/LICENSE.TXT: $$(PYTHON_LIB-$(sdk)) $$(PYTHON_FRAMEWORK-$(sdk))/Info.plist $$(PYTHON_INCLUDE-$(sdk))/pyconfig.h $$(foreach target,$$(SDK_TARGETS-$(sdk)),$$(PYTHON_PLATFORM_SITECUSTOMIZE-$$(target)))
@@ -510,6 +517,14 @@ $$(PYTHON_STDLIB-$(sdk))/LICENSE.TXT: $$(PYTHON_LIB-$(sdk)) $$(PYTHON_FRAMEWORK-
510517
# Merge the binary modules from each target in the $(sdk) SDK into a single binary
511518
$$(foreach module,$$(wildcard $$(PYTHON_STDLIB-$$(firstword $$(SDK_TARGETS-$(sdk))))/lib-dynload/*),lipo -create -output $$(PYTHON_STDLIB-$(sdk))/lib-dynload/$$(notdir $$(module)) $$(foreach target,$$(SDK_TARGETS-$(sdk)),$$(PYTHON_STDLIB-$$(target))/lib-dynload/$$(notdir $$(module))); )
512519

520+
# Create dSYM files for each module
521+
$$(foreach module,$$(wildcard $$(PYTHON_STDLIB-$$(firstword $$(SDK_TARGETS-$(sdk))))/lib-dynload/*),dsymutil $$(PYTHON_STDLIB-$(sdk))/lib-dynload/$$(notdir $$(module)); )
522+
523+
# Copy in known-required xcprivacy files.
524+
# Libraries linking OpenSSL must provide a privacy manifest. The one in this repository
525+
# has been sourced from https://github.com/openssl/openssl/blob/openssl-3.0/os-dep/Apple/PrivacyInfo.xcprivacy
526+
cp $(PROJECT_DIR)/patch/Python/OpenSSL.xcprivacy $$(PYTHON_STDLIB-$(sdk))/lib-dynload/_hashlib.xcprivacy
527+
cp $(PROJECT_DIR)/patch/Python/OpenSSL.xcprivacy $$(PYTHON_STDLIB-$(sdk))/lib-dynload/_ssl.xcprivacy
513528
endif
514529

515530
$(sdk): $$(PYTHON_STDLIB-$(sdk))/LICENSE.TXT
@@ -647,10 +662,11 @@ $$(PYTHON_XCFRAMEWORK-$(os))/Info.plist: \
647662
$$(foreach sdk,$$(SDKS-$(os)),cp -r $$(PYTHON_INSTALL-$$(sdk))/bin $$(PYTHON_XCFRAMEWORK-$(os))/$$(SDK_SLICE-$$(sdk)); )
648663
$$(foreach sdk,$$(SDKS-$(os)),cp -r $$(PYTHON_INSTALL-$$(sdk))/lib $$(PYTHON_XCFRAMEWORK-$(os))/$$(SDK_SLICE-$$(sdk)); )
649664
$$(foreach sdk,$$(SDKS-$(os)),cp -r $$(PYTHON_INSTALL-$$(sdk))/platform-config $$(PYTHON_XCFRAMEWORK-$(os))/$$(SDK_SLICE-$$(sdk)); )
665+
$$(foreach sdk,$$(SDKS-$(os)),cp -r $$(PYTHON_INSTALL-$$(sdk))/Python.dSYM $$(PYTHON_XCFRAMEWORK-$(os))/$$(SDK_SLICE-$$(sdk)); )
650666

651-
ifeq ($(os),iOS)
667+
ifeq ($(filter $(os),iOS visionOS),$(os))
652668
@echo ">>> Clone testbed project for $(os)"
653-
$(HOST_PYTHON) $$(PYTHON_SRCDIR-$$(firstword $$(SDK_TARGETS-$$(firstword $$(SDKS-$(os))))))/iOS/testbed clone --framework $$(PYTHON_XCFRAMEWORK-$(os)) support/$(PYTHON_VER)/$(os)/testbed
669+
$(HOST_PYTHON) $$(PYTHON_SRCDIR-$$(firstword $$(SDK_TARGETS-$$(firstword $$(SDKS-$(os))))))/$(os)/testbed clone --framework $$(PYTHON_XCFRAMEWORK-$(os)) support/$(PYTHON_VER)/$(os)/testbed
654670
endif
655671

656672
@echo ">>> Create VERSIONS file for $(os)"

README.rst

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Python Apple Support
22
====================
33

44
This is a meta-package for building a version of Python that can be embedded
5-
into a macOS, iOS, tvOS or watchOS project.
5+
into a macOS, iOS, tvOS, watchOS, or visionOS project.
66

77
**This branch builds a packaged version of Python 3.13**.
88
Other Python versions are available by cloning other branches of the main
@@ -16,21 +16,24 @@ repository:
1616

1717
It works by downloading, patching, and building a fat binary of Python and
1818
selected pre-requisites, and packaging them as frameworks that can be
19-
incorporated into an XCode project. The binary modules in the Python standard
19+
incorporated into an Xcode project. The binary modules in the Python standard
2020
library are distributed as binaries that can be dynamically loaded at runtime.
2121

2222
The macOS package is a re-bundling of the official macOS binary, modified so that
2323
it is relocatable, with the IDLE, Tkinter and turtle packages removed, and the
2424
App Store compliance patch applied.
2525

26-
The iOS, tvOS and watchOS packages compiled by this project use the official
27-
`PEP 730 <https://peps.python.org/pep-0730/>`__ code that is part of Python 3.13
28-
to provide iOS support; the relevant patches have been backported to 3.9-3.12.
29-
Additional patches have been applied to add tvOS and watchOS support.
26+
The iOS, tvOS, watchOS, and visionOS packages compiled by this project use the
27+
official `PEP 730 <https://peps.python.org/pep-0730/>`__ code that is part of
28+
Python 3.13 to provide iOS support; the relevant patches have been backported
29+
to 3.9-3.12. Additional patches have been applied to add tvOS, watchOS, and
30+
visionOS support.
3031

3132
The binaries support x86_64 and arm64 for macOS; arm64 for iOS and appleTV
32-
devices; and arm64_32 for watchOS devices. It also supports device simulators on
33-
both x86_64 and M1 hardware. This should enable the code to run on:
33+
devices; arm64_32 for watchOS devices; and arm64 for visionOS devices. It also
34+
supports device simulators on both x86_64 and M1 hardware, except for visionOS,
35+
for which x86_64 simulators are officially unsupported. This should enable the
36+
code to run on:
3437

3538
* macOS 11 (Big Sur) or later, on:
3639
* MacBook (including MacBooks using Apple Silicon)
@@ -49,6 +52,8 @@ both x86_64 and M1 hardware. This should enable the code to run on:
4952
* Apple TV (4th gen or later)
5053
* watchOS 4.0 or later, on:
5154
* Apple Watch (4th gen or later)
55+
* visionOS 2.0 or later, on:
56+
* Apple Vision Pro
5257

5358
Quickstart
5459
----------
@@ -69,23 +74,24 @@ repository, and then in the root directory, and run:
6974
* ``make iOS`` to build everything for iOS.
7075
* ``make tvOS`` to build everything for tvOS.
7176
* ``make watchOS`` to build everything for watchOS.
77+
* ``make visionOS`` to build everything for visionOS.
7278

7379
This should:
7480

7581
1. Download the original source packages
7682
2. Patch them as required for compatibility with the selected OS
7783
3. Build the packages as Xcode-compatible XCFrameworks.
7884

79-
The resulting support packages will be packaged as a ``.tar.gz`` file
85+
The resulting support packages will be packaged as ``.tar.gz`` files
8086
in the ``dist`` folder.
8187

8288
Each support package contains:
8389

8490
* ``VERSIONS``, a text file describing the specific versions of code used to build the
8591
support package;
86-
* ``Python.xcframework``, a multi-architecture build of the Python runtime library
92+
* ``Python.xcframework``, a multi-architecture build of the Python runtime library.
8793

88-
On iOS/tvOS/watchOS, the ``Python.xcframework`` contains a
94+
On iOS/tvOS/watchOS/visionOS, the ``Python.xcframework`` contains a
8995
slice for each supported ABI (device and simulator). The folder containing the
9096
slice can also be used as a ``PYTHONHOME``, as it contains a ``bin``, ``include``
9197
and ``lib`` directory.
@@ -131,8 +137,8 @@ Building binary wheels
131137
This project packages the Python standard library, but does not address building
132138
binary wheels. Binary wheels for macOS can be obtained from PyPI. `Mobile Forge
133139
<https://github.com/beeware/mobile-forge>`__ is a project that provides the
134-
tooling to build build binary wheels for iOS (and potentially for tvOS and
135-
watchOS, although that hasn't been tested).
140+
tooling to build build binary wheels for iOS (and potentially for tvOS, watchOS,
141+
and visionOS, although that hasn't been tested).
136142

137143
Historical support
138144
------------------

USAGE.md

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
## The easy way
44

5-
The easist way to use these packages is by creating a project with `Briefcase
6-
<https://github.com/beeware/briefcase>`__. Briefcase will download pre-compiled
7-
versions of these support packages, and add them to an Xcode project (or
8-
pre-build stub application, in the case of macOS).
5+
The easist way to use these packages is by creating a project with
6+
(Briefcase)[https://github.com/beeware/briefcase]. Briefcase will download
7+
pre-compiled versions of these support packages, and add them to an Xcode project
8+
(or pre-build stub application, in the case of macOS).
99

1010
## The manual way
1111

@@ -22,8 +22,72 @@ guides:
2222
* [macOS](https://docs.python.org/3/using/mac.html)
2323
* [iOS](https://docs.python.org/3/using/ios.html#adding-python-to-an-ios-project)
2424

25-
For tvOS and watchOS, you should be able to broadly follow the instructions in
26-
the iOS guide.
25+
For tvOS, watchOS, and visionOS, you should be able to broadly follow the instructions
26+
in the iOS guide, changing some platform names in the first script. The testbed projects
27+
generated on iOS and visionOS may be used as rough references as well.
28+
29+
### Using Objective C
30+
31+
Once you've added the Python XCframework to your project, you'll need to
32+
initialize the Python runtime in your Objective C code (This is step 10 of the
33+
iOS guide linked above). This initialization should generally be done as early
34+
as possible in the application's lifecycle, but definitely needs to be done
35+
before you invoke Python code.
36+
37+
As a *bare minimum*, you can do the following:
38+
39+
1. Import the Python C API headers:
40+
```objc
41+
#include <Python/Python.h>
42+
```
43+
44+
2. Initialize the Python interpreter:
45+
```objc
46+
NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
47+
NSString *pythonHome = [NSString stringWithFormat:@"%@/python", resourcePath, nil];
48+
NSString *appPath = [NSString stringWithFormat:@"%@/app", resourcePath, nil];
49+
50+
setenv("PYTHONHOME", [pythonHome UTF8String], 1);
51+
setenv("PYTHONPATH", [appPath UTF8String], 1);
52+
53+
Py_Initialize();
54+
55+
// we now have a Python interpreter ready to be used
56+
```
57+
58+
Again - this is the *bare minimum* initialization. In practice, you will likely
59+
need to configure other aspects of the Python interpreter using the
60+
`PyPreConfig` and `PyConfig` mechanisms. Consult the [Python documentation on
61+
interpreter configuration](https://docs.python.org/3/c-api/init_config.html) for
62+
more details on the configuration options that are available. You may find the
63+
[bootstrap mainline code used by
64+
Briefcase](https://github.com/beeware/briefcase-iOS-Xcode-template/blob/main/%7B%7B%20cookiecutter.format%20%7D%7D/%7B%7B%20cookiecutter.class_name%20%7D%7D/main.m)
65+
a helpful point of comparison.
66+
67+
### Using Swift
68+
69+
If you want to use Swift instead of Objective C, the bare minimum initialization
70+
code will look something like this:
71+
72+
1. Import the Python framework:
73+
```swift
74+
import Python
75+
```
76+
77+
2. Initialize the Python interpreter:
78+
```swift
79+
guard let pythonHome = Bundle.main.path(forResource: "python", ofType: nil) else { return }
80+
let appPath = Bundle.main.path(forResource: "app", ofType: nil)
81+
82+
setenv("PYTHONHOME", pythonHome, 1)
83+
setenv("PYTHONPATH", appPath, 1)
84+
Py_Initialize()
85+
// we now have a Python interpreter ready to be used
86+
```
87+
88+
Again, references to a specific Python version should reflect the version of
89+
Python you are using; and you will likely need to use `PyPreConfig` and
90+
`PreConfig` APIs.
2791

2892
### Using Objective C
2993

0 commit comments

Comments
 (0)