gh-114099: Add documentation for iOS platform (GH-117057)

Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
Co-authored-by: Jacob Coffee <jacob@z7x.org>
Co-authored-by: Malcolm Smith <smith@chaquo.com>
Co-authored-by: Ned Deily <nad@python.org>
This commit is contained in:
Russell Keith-Magee 2024-03-28 16:13:13 +08:00 committed by GitHub
parent f006338017
commit 0f27672c50
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 584 additions and 161 deletions

View File

@ -0,0 +1,8 @@
.. include for modules that don't work on WASM or iOS
.. availability:: not WASI, not iOS.
This module does not work or is not available on WebAssembly platforms, or
on iOS. See :ref:`wasm-availability` for more information on WASM
availability; see :ref:`iOS-availability` for more information on iOS
availability.

View File

@ -1,7 +1,6 @@
.. include for modules that don't work on WASM
.. availability:: not Emscripten, not WASI.
.. availability:: not WASI.
This module does not work or is not available on WebAssembly platforms
``wasm32-emscripten`` and ``wasm32-wasi``. See
This module does not work or is not available on WebAssembly. See
:ref:`wasm-availability` for more information.

View File

@ -21,6 +21,8 @@ for Windows, DOS, and possibly other systems as well. This extension module is
designed to match the API of ncurses, an open-source curses library hosted on
Linux and the BSD variants of Unix.
.. include:: ../includes/wasm-ios-notavail.rst
.. note::
Whenever the documentation mentions a *character* it can be specified

View File

@ -19,6 +19,7 @@ slow-but-simple implementation in module :mod:`dbm.dumb` will be used. There
is a `third party interface <https://www.jcea.es/programacion/pybsddb.htm>`_ to
the Oracle Berkeley DB.
.. include:: ../includes/wasm-ios-notavail.rst
.. exception:: error
@ -455,4 +456,3 @@ The :mod:`!dbm.dumb` module defines the following:
.. method:: dumbdbm.close()
Close the database.

View File

@ -38,7 +38,7 @@ when creating a virtual environment) or after explicitly uninstalling
:pep:`453`: Explicit bootstrapping of pip in Python installations
The original rationale and specification for this module.
.. include:: ../includes/wasm-notavail.rst
.. include:: ../includes/wasm-ios-notavail.rst
Command line interface
----------------------

View File

@ -18,7 +18,7 @@ interface to the :c:func:`fcntl` and :c:func:`ioctl` Unix routines.
See the :manpage:`fcntl(2)` and :manpage:`ioctl(2)` Unix manual pages
for full details.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
All functions in this module take a file descriptor *fd* as their first
argument. This can be an integer file descriptor, such as returned by

View File

@ -10,7 +10,7 @@
This module provides access to the Unix group database. It is available on all
Unix versions.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI, not iOS.
Group database entries are reported as a tuple-like object, whose attributes
correspond to the members of the ``group`` structure (Attribute field below, see

View File

@ -58,7 +58,7 @@ Notes on availability
operating system.
* If not separately noted, all functions that claim "Availability: Unix" are
supported on macOS, which builds on a Unix core.
supported on macOS and iOS, both of which build on a Unix core.
* If an availability note contains both a minimum Kernel version and a minimum
libc version, then both conditions must hold. For example a feature with note
@ -119,3 +119,44 @@ DOM APIs as well as limited networking capabilities with JavaScript's
.. _wasmtime: https://wasmtime.dev/
.. _Pyodide: https://pyodide.org/
.. _PyScript: https://pyscript.net/
.. _iOS-availability:
iOS
---
iOS is, in most respects, a POSIX operating system. File I/O, socket handling,
and threading all behave as they would on any POSIX operating system. However,
there are several major differences between iOS and other POSIX systems.
* iOS can only use Python in "embedded" mode. There is no Python REPL, and no
ability to execute binaries that are part of the normal Python developer
experience, such as :program:`pip`. To add Python code to your iOS app, you must use
the :ref:`Python embedding API <embedding>` to add a Python interpreter to an
iOS app created with Xcode. See the :ref:`iOS usage guide <using-ios>` for
more details.
* An iOS app cannot use any form of subprocessing, background processing, or
inter-process communication. If an iOS app attempts to create a subprocess,
the process creating the subprocess will either lock up, or crash. An iOS app
has no visibility of other applications that are running, nor any ability to
communicate with other running applications, outside of the iOS-specific APIs
that exist for this purpose.
* iOS apps have limited access to modify system resources (such as the system
clock). These resources will often be *readable*, but attempts to modify
those resources will usually fail.
* iOS apps have a limited concept of console input and output. ``stdout`` and
``stderr`` *exist*, and content written to ``stdout`` and ``stderr`` will be
visible in logs when running in Xcode, but this content *won't* be recorded
in the system log. If a user who has installed your app provides their app
logs as a diagnostic aid, they will not include any detail written to
``stdout`` or ``stderr``.
iOS apps have no concept of ``stdin`` at all. While iOS apps can have a
keyboard, this is a software feature, not something that is attached to
``stdin``.
As a result, Python library that involve console manipulation (such as
:mod:`curses` and :mod:`readline`) are not available on iOS.

View File

@ -8,7 +8,7 @@
--------------
.. include:: ../includes/wasm-notavail.rst
.. include:: ../includes/wasm-ios-notavail.rst
Introduction
------------

View File

@ -34,12 +34,12 @@ Notes on the availability of these functions:
* On VxWorks, os.popen, os.fork, os.execv and os.spawn*p* are not supported.
* On WebAssembly platforms ``wasm32-emscripten`` and ``wasm32-wasi``, large
parts of the :mod:`os` module are not available or behave differently. API
related to processes (e.g. :func:`~os.fork`, :func:`~os.execve`), signals
(e.g. :func:`~os.kill`, :func:`~os.wait`), and resources
(e.g. :func:`~os.nice`) are not available. Others like :func:`~os.getuid`
and :func:`~os.getpid` are emulated or stubs.
* On WebAssembly platforms, and on iOS, large parts of the :mod:`os` module are
not available or behave differently. API related to processes (e.g.
:func:`~os.fork`, :func:`~os.execve`) and resources (e.g. :func:`~os.nice`)
are not available. Others like :func:`~os.getuid` and :func:`~os.getpid` are
emulated or stubs. WebAssembly platforms also lack support for signals (e.g.
:func:`~os.kill`, :func:`~os.wait`).
.. note::
@ -178,7 +178,7 @@ process and user.
Return the filename corresponding to the controlling terminal of the process.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. data:: environ
@ -355,7 +355,7 @@ process and user.
Return the effective group id of the current process. This corresponds to the
"set id" bit on the file being executed in the current process.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. function:: geteuid()
@ -364,7 +364,7 @@ process and user.
Return the current process's effective user id.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. function:: getgid()
@ -375,8 +375,8 @@ process and user.
.. availability:: Unix.
The function is a stub on Emscripten and WASI, see
:ref:`wasm-availability` for more information.
The function is a stub on WASI, see :ref:`wasm-availability` for more
information.
.. function:: getgrouplist(user, group, /)
@ -386,7 +386,7 @@ process and user.
field from the password record for *user*, because that group ID will
otherwise be potentially omitted.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. versionadded:: 3.3
@ -395,7 +395,7 @@ process and user.
Return list of supplemental group ids associated with the current process.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. note::
@ -423,7 +423,7 @@ process and user.
falls back to ``pwd.getpwuid(os.getuid())[0]`` to get the login name of the
current real user id.
.. availability:: Unix, Windows, not Emscripten, not WASI.
.. availability:: Unix, Windows, not WASI.
.. function:: getpgid(pid)
@ -431,7 +431,7 @@ process and user.
Return the process group id of the process with process id *pid*. If *pid* is 0,
the process group id of the current process is returned.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. function:: getpgrp()
@ -439,7 +439,7 @@ process and user.
Return the id of the current process group.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. function:: getpid()
@ -448,8 +448,8 @@ process and user.
Return the current process id.
The function is a stub on Emscripten and WASI, see
:ref:`wasm-availability` for more information.
The function is a stub on WASI, see :ref:`wasm-availability` for more
information.
.. function:: getppid()
@ -459,7 +459,7 @@ process and user.
the id returned is the one of the init process (1), on Windows it is still
the same id, which may be already reused by another process.
.. availability:: Unix, Windows, not Emscripten, not WASI.
.. availability:: Unix, Windows, not WASI.
.. versionchanged:: 3.2
Added support for Windows.
@ -477,7 +477,7 @@ process and user.
(respectively) the calling process, the process group of the calling process,
or the real user ID of the calling process.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. versionadded:: 3.3
@ -488,7 +488,7 @@ process and user.
Parameters for the :func:`getpriority` and :func:`setpriority` functions.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. versionadded:: 3.3
@ -509,7 +509,7 @@ process and user.
Return a tuple (ruid, euid, suid) denoting the current process's
real, effective, and saved user ids.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. versionadded:: 3.2
@ -519,7 +519,7 @@ process and user.
Return a tuple (rgid, egid, sgid) denoting the current process's
real, effective, and saved group ids.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. versionadded:: 3.2
@ -532,8 +532,8 @@ process and user.
.. availability:: Unix.
The function is a stub on Emscripten and WASI, see
:ref:`wasm-availability` for more information.
The function is a stub on WASI, see :ref:`wasm-availability` for more
information.
.. function:: initgroups(username, gid, /)
@ -542,7 +542,7 @@ process and user.
the groups of which the specified username is a member, plus the specified
group id.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. versionadded:: 3.2
@ -576,21 +576,21 @@ process and user.
Set the current process's effective group id.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. function:: seteuid(euid, /)
Set the current process's effective user id.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. function:: setgid(gid, /)
Set the current process' group id.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. function:: setgroups(groups, /)
@ -599,7 +599,7 @@ process and user.
*groups*. *groups* must be a sequence, and each element must be an integer
identifying a group. This operation is typically available only to the superuser.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. note:: On macOS, the length of *groups* may not exceed the
system-defined maximum number of effective group ids, typically 16.
@ -649,7 +649,7 @@ process and user.
Call the system call :c:func:`!setpgrp` or ``setpgrp(0, 0)`` depending on
which version is implemented (if any). See the Unix manual for the semantics.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. function:: setpgid(pid, pgrp, /)
@ -658,7 +658,7 @@ process and user.
process with id *pid* to the process group with id *pgrp*. See the Unix manual
for the semantics.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. function:: setpriority(which, who, priority)
@ -675,7 +675,7 @@ process and user.
*priority* is a value in the range -20 to 19. The default priority is 0;
lower priorities cause more favorable scheduling.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. versionadded:: 3.3
@ -684,14 +684,14 @@ process and user.
Set the current process's real and effective group ids.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. function:: setresgid(rgid, egid, sgid, /)
Set the current process's real, effective, and saved group ids.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. versionadded:: 3.2
@ -700,7 +700,7 @@ process and user.
Set the current process's real, effective, and saved user ids.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. versionadded:: 3.2
@ -709,21 +709,21 @@ process and user.
Set the current process's real and effective user ids.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. function:: getsid(pid, /)
Call the system call :c:func:`!getsid`. See the Unix manual for the semantics.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. function:: setsid()
Call the system call :c:func:`!setsid`. See the Unix manual for the semantics.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. function:: setuid(uid, /)
@ -732,7 +732,7 @@ process and user.
Set the current process's user id.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. placed in this section since it relates to errno.... a little weak
@ -755,8 +755,8 @@ process and user.
Set the current numeric umask and return the previous umask.
The function is a stub on Emscripten and WASI, see
:ref:`wasm-availability` for more information.
The function is a stub on WASI, see :ref:`wasm-availability` for more
information.
.. function:: uname()
@ -1008,8 +1008,8 @@ as internal buffering of data.
.. availability:: Unix, Windows.
The function is limited on Emscripten and WASI, see
:ref:`wasm-availability` for more information.
The function is limited on WASI, see :ref:`wasm-availability` for more
information.
.. versionchanged:: 3.13
Added support on Windows.
@ -1026,8 +1026,8 @@ as internal buffering of data.
.. availability:: Unix.
The function is limited on Emscripten and WASI, see
:ref:`wasm-availability` for more information.
The function is limited on WASI, see :ref:`wasm-availability` for more
information.
.. function:: fdatasync(fd)
@ -1117,8 +1117,8 @@ as internal buffering of data.
.. availability:: Unix, Windows.
The function is limited on Emscripten and WASI, see
:ref:`wasm-availability` for more information.
The function is limited on WASI, see :ref:`wasm-availability` for more
information.
On Windows, this function is limited to pipes.
@ -1136,7 +1136,7 @@ as internal buffering of data.
Calls the C standard library function :c:func:`grantpt`.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. versionadded:: 3.13
@ -1180,7 +1180,7 @@ as internal buffering of data.
Make the calling process a session leader; make the tty the controlling tty,
the stdin, the stdout, and the stderr of the calling process; close fd.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. versionadded:: 3.11
@ -1364,7 +1364,7 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo
descriptors are :ref:`non-inheritable <fd_inheritance>`. For a (slightly) more
portable approach, use the :mod:`pty` module.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. versionchanged:: 3.4
The new file descriptors are now non-inheritable.
@ -1390,7 +1390,7 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo
Return a pair of file descriptors ``(r, w)`` usable for reading and writing,
respectively.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. versionadded:: 3.3
@ -1400,7 +1400,7 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo
Ensures that enough disk space is allocated for the file specified by *fd*
starting from *offset* and continuing for *len* bytes.
.. availability:: Unix, not Emscripten.
.. availability:: Unix.
.. versionadded:: 3.3
@ -1460,7 +1460,7 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo
If the value :data:`O_CLOEXEC` is available on the system, it is added to
*oflag*.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. versionadded:: 3.13
@ -1532,7 +1532,7 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo
it is available; otherwise, the C standard library function
:c:func:`ptsname`, which is not guaranteed to be thread-safe, is called.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. versionadded:: 3.13
@ -1659,7 +1659,7 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo
Cross-platform applications should not use *headers*, *trailers* and *flags*
arguments.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. note::
@ -1679,7 +1679,7 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo
Parameters to the :func:`sendfile` function, if the implementation supports
them.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. versionadded:: 3.3
@ -1688,7 +1688,7 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo
Parameter to the :func:`sendfile` function, if the implementation supports
it. The data won't be cached in the virtual memory and will be freed afterwards.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. versionadded:: 3.11
@ -1702,8 +1702,8 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo
.. availability:: Unix, Windows.
The function is limited on Emscripten and WASI, see
:ref:`wasm-availability` for more information.
The function is limited on WASI, see :ref:`wasm-availability` for more
information.
On Windows, this function is limited to pipes.
@ -1797,7 +1797,7 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo
Calls the C standard library function :c:func:`unlockpt`.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. versionadded:: 3.13
@ -1898,8 +1898,7 @@ Using the :mod:`subprocess` module, all file descriptors except standard
streams are closed, and inheritable handles are only inherited if the
*close_fds* parameter is ``False``.
On WebAssembly platforms ``wasm32-emscripten`` and ``wasm32-wasi``, the file
descriptor cannot be modified.
On WebAssembly platforms, the file descriptor cannot be modified.
.. function:: get_inheritable(fd, /)
@ -2085,7 +2084,7 @@ features:
.. audit-event:: os.chflags path,flags os.chflags
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. versionchanged:: 3.3
Added the *follow_symlinks* parameter.
@ -2131,8 +2130,8 @@ features:
constants or a corresponding integer value). All other bits are ignored.
The default value of *follow_symlinks* is ``False`` on Windows.
The function is limited on Emscripten and WASI, see
:ref:`wasm-availability` for more information.
The function is limited on WASI, see :ref:`wasm-availability` for more
information.
.. audit-event:: os.chmod path,mode,dir_fd os.chmod
@ -2164,8 +2163,8 @@ features:
.. availability:: Unix.
The function is limited on Emscripten and WASI, see
:ref:`wasm-availability` for more information.
The function is limited on WASI, see :ref:`wasm-availability` for more
information.
.. versionadded:: 3.3
Added support for specifying *path* as an open file descriptor,
@ -2179,7 +2178,7 @@ features:
Change the root directory of the current process to *path*.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. versionchanged:: 3.6
Accepts a :term:`path-like object`.
@ -2219,7 +2218,7 @@ features:
.. audit-event:: os.chflags path,flags os.lchflags
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. versionchanged:: 3.6
Accepts a :term:`path-like object`.
@ -2269,7 +2268,7 @@ features:
.. audit-event:: os.link src,dst,src_dir_fd,dst_dir_fd os.link
.. availability:: Unix, Windows, not Emscripten.
.. availability:: Unix, Windows.
.. versionchanged:: 3.2
Added Windows support.
@ -2505,7 +2504,7 @@ features:
FIFO for reading, and the client opens it for writing. Note that :func:`mkfifo`
doesn't open the FIFO --- it just creates the rendezvous point.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. versionchanged:: 3.3
Added the *dir_fd* parameter.
@ -2527,7 +2526,7 @@ features:
This function can also support :ref:`paths relative to directory descriptors
<dir_fd>`.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. versionchanged:: 3.3
Added the *dir_fd* parameter.
@ -3449,8 +3448,8 @@ features:
.. availability:: Unix, Windows.
The function is limited on Emscripten and WASI, see
:ref:`wasm-availability` for more information.
The function is limited on WASI, see :ref:`wasm-availability` for more
information.
.. versionchanged:: 3.2
Added support for Windows 6.0 (Vista) symbolic links.
@ -4276,7 +4275,7 @@ to be ignored.
.. audit-event:: os.exec path,args,env os.execl
.. availability:: Unix, Windows, not Emscripten, not WASI.
.. availability:: Unix, Windows, not WASI, not iOS.
.. versionchanged:: 3.3
Added support for specifying *path* as an open file descriptor
@ -4319,49 +4318,49 @@ written in Python, such as a mail server's external command delivery program.
Exit code that means the command was used incorrectly, such as when the wrong
number of arguments are given.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. data:: EX_DATAERR
Exit code that means the input data was incorrect.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. data:: EX_NOINPUT
Exit code that means an input file did not exist or was not readable.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. data:: EX_NOUSER
Exit code that means a specified user did not exist.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. data:: EX_NOHOST
Exit code that means a specified host did not exist.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. data:: EX_UNAVAILABLE
Exit code that means that a required service is unavailable.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. data:: EX_SOFTWARE
Exit code that means an internal software error was detected.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. data:: EX_OSERR
@ -4369,7 +4368,7 @@ written in Python, such as a mail server's external command delivery program.
Exit code that means an operating system error was detected, such as the
inability to fork or create a pipe.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. data:: EX_OSFILE
@ -4377,21 +4376,21 @@ written in Python, such as a mail server's external command delivery program.
Exit code that means some system file did not exist, could not be opened, or had
some other kind of error.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. data:: EX_CANTCREAT
Exit code that means a user specified output file could not be created.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. data:: EX_IOERR
Exit code that means that an error occurred while doing I/O on some file.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. data:: EX_TEMPFAIL
@ -4400,7 +4399,7 @@ written in Python, such as a mail server's external command delivery program.
that may not really be an error, such as a network connection that couldn't be
made during a retryable operation.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. data:: EX_PROTOCOL
@ -4408,7 +4407,7 @@ written in Python, such as a mail server's external command delivery program.
Exit code that means that a protocol exchange was illegal, invalid, or not
understood.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. data:: EX_NOPERM
@ -4416,21 +4415,21 @@ written in Python, such as a mail server's external command delivery program.
Exit code that means that there were insufficient permissions to perform the
operation (but not intended for file system problems).
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. data:: EX_CONFIG
Exit code that means that some kind of configuration error occurred.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. data:: EX_NOTFOUND
Exit code that means something like "an entry was not found".
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. function:: fork()
@ -4479,7 +4478,7 @@ written in Python, such as a mail server's external command delivery program.
for technical details of why we're surfacing this longstanding
platform compatibility problem to developers.
.. availability:: POSIX, not Emscripten, not WASI.
.. availability:: POSIX, not WASI, not iOS.
.. function:: forkpty()
@ -4506,7 +4505,7 @@ written in Python, such as a mail server's external command delivery program.
threads, this now raises a :exc:`DeprecationWarning`. See the
longer explanation on :func:`os.fork`.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI, not iOS.
.. function:: kill(pid, sig, /)
@ -4530,7 +4529,7 @@ written in Python, such as a mail server's external command delivery program.
.. audit-event:: os.kill pid,sig os.kill
.. availability:: Unix, Windows, not Emscripten, not WASI.
.. availability:: Unix, Windows, not WASI, not iOS.
.. versionchanged:: 3.2
Added Windows support.
@ -4546,14 +4545,14 @@ written in Python, such as a mail server's external command delivery program.
.. audit-event:: os.killpg pgid,sig os.killpg
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI, not iOS.
.. function:: nice(increment, /)
Add *increment* to the process's "niceness". Return the new niceness.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
.. function:: pidfd_open(pid, flags=0)
@ -4583,7 +4582,7 @@ written in Python, such as a mail server's external command delivery program.
Lock program segments into memory. The value of *op* (defined in
``<sys/lock.h>``) determines which segments are locked.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI, not iOS.
.. function:: popen(cmd, mode='r', buffering=-1)
@ -4615,7 +4614,7 @@ written in Python, such as a mail server's external command delivery program.
documentation for more powerful ways to manage and communicate with
subprocesses.
.. availability:: not Emscripten, not WASI.
.. availability:: not WASI, not iOS.
.. note::
The :ref:`Python UTF-8 Mode <utf8-mode>` affects encodings used
@ -4723,7 +4722,7 @@ written in Python, such as a mail server's external command delivery program.
``os.POSIX_SPAWN_CLOSEFROM`` is available on platforms where
:c:func:`!posix_spawn_file_actions_addclosefrom_np` exists.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI, not iOS.
.. function:: posix_spawnp(path, argv, env, *, file_actions=None, \
setpgroup=None, resetids=False, setsid=False, setsigmask=(), \
@ -4739,7 +4738,7 @@ written in Python, such as a mail server's external command delivery program.
.. versionadded:: 3.8
.. availability:: POSIX, not Emscripten, not WASI.
.. availability:: POSIX, not WASI, not iOS.
See :func:`posix_spawn` documentation.
@ -4772,7 +4771,7 @@ written in Python, such as a mail server's external command delivery program.
There is no way to unregister a function.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI, not iOS.
.. versionadded:: 3.7
@ -4841,7 +4840,7 @@ written in Python, such as a mail server's external command delivery program.
.. audit-event:: os.spawn mode,path,args,env os.spawnl
.. availability:: Unix, Windows, not Emscripten, not WASI.
.. availability:: Unix, Windows, not WASI, not iOS.
:func:`spawnlp`, :func:`spawnlpe`, :func:`spawnvp`
and :func:`spawnvpe` are not available on Windows. :func:`spawnle` and
@ -4965,7 +4964,7 @@ written in Python, such as a mail server's external command delivery program.
.. audit-event:: os.system command os.system
.. availability:: Unix, Windows, not Emscripten, not WASI.
.. availability:: Unix, Windows, not WASI, not iOS.
.. function:: times()
@ -5009,7 +5008,7 @@ written in Python, such as a mail server's external command delivery program.
:func:`waitstatus_to_exitcode` can be used to convert the exit status into an
exit code.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI, not iOS.
.. seealso::
@ -5043,7 +5042,7 @@ written in Python, such as a mail server's external command delivery program.
Otherwise, if there are no matching children
that could be waited for, :exc:`ChildProcessError` is raised.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI, not iOS.
.. versionadded:: 3.3
@ -5084,7 +5083,7 @@ written in Python, such as a mail server's external command delivery program.
:func:`waitstatus_to_exitcode` can be used to convert the exit status into an
exit code.
.. availability:: Unix, Windows, not Emscripten, not WASI.
.. availability:: Unix, Windows, not WASI, not iOS.
.. versionchanged:: 3.5
If the system call is interrupted and the signal handler does not raise an
@ -5104,7 +5103,7 @@ written in Python, such as a mail server's external command delivery program.
:func:`waitstatus_to_exitcode` can be used to convert the exit status into an
exitcode.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI, not iOS.
.. function:: wait4(pid, options)
@ -5118,7 +5117,7 @@ written in Python, such as a mail server's external command delivery program.
:func:`waitstatus_to_exitcode` can be used to convert the exit status into an
exitcode.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI, not iOS.
.. data:: P_PID
@ -5135,7 +5134,7 @@ written in Python, such as a mail server's external command delivery program.
* :data:`!P_PIDFD` - wait for the child identified by the file descriptor
*id* (a process file descriptor created with :func:`pidfd_open`).
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI, not iOS.
.. note:: :data:`!P_PIDFD` is only available on Linux >= 5.4.
@ -5150,7 +5149,7 @@ written in Python, such as a mail server's external command delivery program.
:func:`waitid` causes child processes to be reported if they have been
continued from a job control stop since they were last reported.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI, not iOS.
.. data:: WEXITED
@ -5161,7 +5160,7 @@ written in Python, such as a mail server's external command delivery program.
The other ``wait*`` functions always report children that have terminated,
so this option is not available for them.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI, not iOS.
.. versionadded:: 3.3
@ -5173,7 +5172,7 @@ written in Python, such as a mail server's external command delivery program.
This option is not available for the other ``wait*`` functions.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI, not iOS.
.. versionadded:: 3.3
@ -5186,7 +5185,7 @@ written in Python, such as a mail server's external command delivery program.
This option is not available for :func:`waitid`.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI, not iOS.
.. data:: WNOHANG
@ -5195,7 +5194,7 @@ written in Python, such as a mail server's external command delivery program.
:func:`waitid` to return right away if no child process status is available
immediately.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI, not iOS.
.. data:: WNOWAIT
@ -5205,7 +5204,7 @@ written in Python, such as a mail server's external command delivery program.
This option is not available for the other ``wait*`` functions.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI, not iOS.
.. data:: CLD_EXITED
@ -5218,7 +5217,7 @@ written in Python, such as a mail server's external command delivery program.
These are the possible values for :attr:`!si_code` in the result returned by
:func:`waitid`.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI, not iOS.
.. versionadded:: 3.3
@ -5253,7 +5252,7 @@ written in Python, such as a mail server's external command delivery program.
:func:`WIFEXITED`, :func:`WEXITSTATUS`, :func:`WIFSIGNALED`,
:func:`WTERMSIG`, :func:`WIFSTOPPED`, :func:`WSTOPSIG` functions.
.. availability:: Unix, Windows, not Emscripten, not WASI.
.. availability:: Unix, Windows, not WASI, not iOS.
.. versionadded:: 3.9
@ -5269,7 +5268,7 @@ used to determine the disposition of a process.
This function should be employed only if :func:`WIFSIGNALED` is true.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI, not iOS.
.. function:: WIFCONTINUED(status)
@ -5280,7 +5279,7 @@ used to determine the disposition of a process.
See :data:`WCONTINUED` option.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI, not iOS.
.. function:: WIFSTOPPED(status)
@ -5292,14 +5291,14 @@ used to determine the disposition of a process.
done using :data:`WUNTRACED` option or when the process is being traced (see
:manpage:`ptrace(2)`).
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI, not iOS.
.. function:: WIFSIGNALED(status)
Return ``True`` if the process was terminated by a signal, otherwise return
``False``.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI, not iOS.
.. function:: WIFEXITED(status)
@ -5308,7 +5307,7 @@ used to determine the disposition of a process.
by calling ``exit()`` or ``_exit()``, or by returning from ``main()``;
otherwise return ``False``.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI, not iOS.
.. function:: WEXITSTATUS(status)
@ -5317,7 +5316,7 @@ used to determine the disposition of a process.
This function should be employed only if :func:`WIFEXITED` is true.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI, not iOS.
.. function:: WSTOPSIG(status)
@ -5326,7 +5325,7 @@ used to determine the disposition of a process.
This function should be employed only if :func:`WIFSTOPPED` is true.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI, not iOS.
.. function:: WTERMSIG(status)
@ -5335,7 +5334,7 @@ used to determine the disposition of a process.
This function should be employed only if :func:`WIFSIGNALED` is true.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI, not iOS.
Interface to the scheduler

View File

@ -10,7 +10,7 @@
This module provides access to the Unix user account and password database. It
is available on all Unix versions.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI, not iOS.
Password database entries are reported as a tuple-like object, whose attributes
correspond to the members of the ``passwd`` structure (Attribute field below,

View File

@ -24,6 +24,8 @@ in the GNU Readline manual for information about the format and
allowable constructs of that file, and the capabilities of the
Readline library in general.
.. include:: ../includes/wasm-ios-notavail.rst
.. note::
The underlying Readline library API may be implemented by

View File

@ -13,7 +13,7 @@
This module provides basic mechanisms for measuring and controlling system
resources utilized by a program.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
Symbolic constants are used to specify particular system resources and to
request usage information about either the current process or its children.

View File

@ -26,9 +26,9 @@ explicitly reset (Python emulates the BSD style interface regardless of the
underlying implementation), with the exception of the handler for
:const:`SIGCHLD`, which follows the underlying implementation.
On WebAssembly platforms ``wasm32-emscripten`` and ``wasm32-wasi``, signals
are emulated and therefore behave differently. Several functions and signals
are not available on these platforms.
On WebAssembly platforms, signals are emulated and therefore behave
differently. Several functions and signals are not available on these
platforms.
Execution of Python signal handlers
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -1213,7 +1213,7 @@ The :mod:`socket` module also offers various network-related services:
buffer. Raises :exc:`OverflowError` if *length* is outside the
permissible range of values.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
Most Unix platforms.
@ -1236,7 +1236,7 @@ The :mod:`socket` module also offers various network-related services:
amount of ancillary data that can be received, since additional
data may be able to fit into the padding area.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI.
most Unix platforms.
@ -1276,7 +1276,7 @@ The :mod:`socket` module also offers various network-related services:
(index int, name string) tuples.
:exc:`OSError` if the system call fails.
.. availability:: Unix, Windows, not Emscripten, not WASI.
.. availability:: Unix, Windows, not WASI.
.. versionadded:: 3.3
@ -1303,7 +1303,7 @@ The :mod:`socket` module also offers various network-related services:
interface name.
:exc:`OSError` if no interface with the given name exists.
.. availability:: Unix, Windows, not Emscripten, not WASI.
.. availability:: Unix, Windows, not WASI.
.. versionadded:: 3.3
@ -1320,7 +1320,7 @@ The :mod:`socket` module also offers various network-related services:
interface index number.
:exc:`OSError` if no interface with the given index exists.
.. availability:: Unix, Windows, not Emscripten, not WASI.
.. availability:: Unix, Windows, not WASI.
.. versionadded:: 3.3
@ -1337,7 +1337,7 @@ The :mod:`socket` module also offers various network-related services:
The *fds* parameter is a sequence of file descriptors.
Consult :meth:`~socket.sendmsg` for the documentation of these parameters.
.. availability:: Unix, Windows, not Emscripten, not WASI.
.. availability:: Unix, Windows, not WASI.
Unix platforms supporting :meth:`~socket.sendmsg`
and :const:`SCM_RIGHTS` mechanism.
@ -1351,7 +1351,7 @@ The :mod:`socket` module also offers various network-related services:
Return ``(msg, list(fds), flags, addr)``.
Consult :meth:`~socket.recvmsg` for the documentation of these parameters.
.. availability:: Unix, Windows, not Emscripten, not WASI.
.. availability:: Unix, Windows, not WASI.
Unix platforms supporting :meth:`~socket.sendmsg`
and :const:`SCM_RIGHTS` mechanism.

View File

@ -25,7 +25,7 @@ modules and functions can be found in the following sections.
:pep:`324` -- PEP proposing the subprocess module
.. include:: ../includes/wasm-notavail.rst
.. include:: ../includes/wasm-ios-notavail.rst
Using the :mod:`subprocess` Module
----------------------------------

View File

@ -11,7 +11,7 @@ This module provides an interface to the Unix ``syslog`` library routines.
Refer to the Unix manual pages for a detailed description of the ``syslog``
facility.
.. availability:: Unix, not Emscripten, not WASI.
.. availability:: Unix, not WASI, not iOS.
This module wraps the system ``syslog`` family of routines. A pure Python
library that can speak to a syslog server is available in the

View File

@ -56,7 +56,7 @@ See :pep:`405` for more background on Python virtual environments.
`Python Packaging User Guide: Creating and using virtual environments
<https://packaging.python.org/guides/installing-using-pip-and-virtual-environments/#create-and-use-virtual-environments>`__
.. include:: ../includes/wasm-notavail.rst
.. include:: ../includes/wasm-ios-notavail.rst
Creating virtual environments
-----------------------------

View File

@ -164,7 +164,7 @@ class Availability(SphinxDirective):
Example::
.. availability:: Windows, Linux >= 4.2, not Emscripten, not WASI
.. availability:: Windows, Linux >= 4.2, not WASI
Arguments like "Linux >= 3.17 with glibc >= 2.27" are currently not
parsed into separate tokens.

View File

@ -881,7 +881,7 @@ Security Options
macOS Options
-------------
See ``Mac/README.rst``.
See :source:`Mac/README.rst`.
.. option:: --enable-universalsdk
.. option:: --enable-universalsdk=SDKDIR
@ -916,6 +916,20 @@ See ``Mac/README.rst``.
Specify the name for the python framework on macOS only valid when
:option:`--enable-framework` is set (default: ``Python``).
iOS Options
-----------
See :source:`iOS/README.rst`.
.. option:: --enable-framework=INSTALLDIR
Create a Python.framework. Unlike macOS, the *INSTALLDIR* argument
specifying the installation path is mandatory.
.. option:: --with-framework-name=FRAMEWORK
Specify the name for the framework (default: ``Python``).
Cross Compiling Options
-----------------------

View File

@ -18,4 +18,5 @@ interpreter and things that make working with Python easier.
configure.rst
windows.rst
mac.rst
ios.rst
editors.rst

314
Doc/using/ios.rst Normal file
View File

@ -0,0 +1,314 @@
.. _using-ios:
===================
Using Python on iOS
===================
:Authors:
Russell Keith-Magee (2024-03)
Python on iOS is unlike Python on desktop platforms. On a desktop platform,
Python is generally installed as a system resource that can be used by any user
of that computer. Users then interact with Python by running a :program:`python`
executable and entering commands at an interactive prompt, or by running a
Python script.
On iOS, there is no concept of installing as a system resource. The only unit
of software distribution is an "app". There is also no console where you could
run a :program:`python` executable, or interact with a Python REPL.
As a result, the only way you can use Python on iOS is in embedded mode - that
is, by writing a native iOS application, and embedding a Python interpreter
using ``libPython``, and invoking Python code using the :ref:`Python embedding
API <embedding>`. The full Python interpreter, the standard library, and all
your Python code is then packaged as a standalone bundle that can be
distributed via the iOS App Store.
If you're looking to experiment for the first time with writing an iOS app in
Python, projects such as `BeeWare <https://beeware.org>`__ and `Kivy
<https://kivy.org>`__ will provide a much more approachable user experience.
These projects manage the complexities associated with getting an iOS project
running, so you only need to deal with the Python code itself.
Python at runtime on iOS
========================
Platform identification
-----------------------
When executing on iOS, ``sys.platform`` will report as ``ios``. This value will
be returned on an iPhone or iPad, regardless of whether the app is running on
the simulator or a physical device.
Information about the specific runtime environment, including the iOS version,
device model, and whether the device is a simulator, can be obtained using
:func:`platform.ios_ver()`. :func:`platform.system()` will report ``iOS`` or
``iPadOS``, depending on the device.
:func:`os.uname()` reports kernel-level details; it will report a name of
``Darwin``.
Standard library availability
-----------------------------
The Python standard library has some notable omissions and restrictions on
iOS. See the :ref:`API availability guide for iOS <iOS-availability>` for
details.
Binary extension modules
------------------------
One notable difference about iOS as a platform is that App Store distribution
imposes hard requirements on the packaging of an application. One of these
requirements governs how binary extension modules are distributed.
The iOS App Store requires that *all* binary modules in an iOS app must be
dynamic libraries, contained in a framework with appropriate metadata, stored
in the ``Frameworks`` folder of the packaged app. There can be only a single
binary per framework, and there can be no executable binary material outside
the ``Frameworks`` folder.
This conflicts with the usual Python approach for distributing binaries, which
allows a binary extension module to be loaded from any location on
``sys.path``. To ensure compliance with App Store policies, an iOS project must
post-process any Python packages, converting ``.so`` binary modules into
individual standalone frameworks with appropriate metadata and signing. For
details on how to perform this post-processing, see the guide for :ref:`adding
Python to your project <adding-ios>`.
To help Python discover binaries in their new location, the original ``.so``
file on ``sys.path`` is replaced with a ``.fwork`` file. This file is a text
file containing the location of the framework binary, relative to the app
bundle. To allow the framework to resolve back to the original location, the
framework must contain a ``.origin`` file that contains the location of the
``.fwork`` file, relative to the app bundle.
For example, consider the case of an import ``from foo.bar import _whiz``,
where ``_whiz`` is implemented with the binary module
``sources/foo/bar/_whiz.abi3.so``, with ``sources`` being the location
registered on ``sys.path``, relative to the application bundle. This module
*must* be distributed as ``Frameworks/foo.bar._whiz.framework/foo.bar._whiz``
(creating the framework name from the full import path of the module), with an
``Info.plist`` file in the ``.framework`` directory identifying the binary as a
framework. The ``foo.bar._whiz`` module would be represented in the original
location with a ``sources/foo/bar/_whiz.abi3.fwork`` marker file, containing
the path ``Frameworks/foo.bar._whiz/foo.bar._whiz``. The framework would also
contain ``Frameworks/foo.bar._whiz.framework/foo.bar._whiz.origin``, containing
the path to the ``.fwork`` file.
When running on iOS, the Python interpreter will install an
:class:`~importlib.machinery.AppleFrameworkLoader` that is able to read and
import ``.fwork`` files. Once imported, the ``__file__`` attribute of the
binary module will report as the location of the ``.fwork`` file. However, the
:class:`~importlib.machinery.ModuleSpec` for the loaded module will report the
``origin`` as the location of the binary in the framework folder.
Compiler stub binaries
----------------------
Xcode doesn't expose explicit compilers for iOS; instead, it uses an ``xcrun``
script that resolves to a full compiler path (e.g., ``xcrun --sdk iphoneos
clang`` to get the ``clang`` for an iPhone device). However, using this script
poses two problems:
* The output of ``xcrun`` includes paths that are machine specific, resulting
in a sysconfig module that cannot be shared between users; and
* It results in ``CC``/``CPP``/``LD``/``AR`` definitions that include spaces.
There is a lot of C ecosystem tooling that assumes that you can split a
command line at the first space to get the path to the compiler executable;
this isn't the case when using ``xcrun``.
To avoid these problems, Python provided stubs for these tools. These stubs are
shell script wrappers around the underingly ``xcrun`` tools, distributed in a
``bin`` folder distributed alongside the compiled iOS framework. These scripts
are relocatable, and will always resolve to the appropriate local system paths.
By including these scripts in the bin folder that accompanies a framework, the
contents of the ``sysconfig`` module becomes useful for end-users to compile
their own modules. When compiling third-party Python modules for iOS, you
should ensure these stub binaries are on your path.
Installing Python on iOS
========================
Tools for building iOS apps
---------------------------
Building for iOS requires the use of Apple's Xcode tooling. It is strongly
recommended that you use the most recent stable release of Xcode. This will
require the use of the most (or second-most) recently released macOS version,
as Apple does not maintain Xcode for older macOS versions. The Xcode Command
Line Tools are not sufficient for iOS development; you need a *full* Xcode
install.
If you want to run your code on the iOS simulator, you'll also need to install
an iOS Simulator Platform. You should be prompted to select an iOS Simulator
Platform when you first run Xcode. Alternatively, you can add an iOS Simulator
Platform by selecting from the Platforms tab of the Xcode Settings panel.
.. _adding-ios:
Adding Python to an iOS project
-------------------------------
Python can be added to any iOS project, using either Swift or Objective C. The
following examples will use Objective C; if you are using Swift, you may find a
library like `PythonKit <https://github.com/pvieito/PythonKit>`__ to be
helpful.
To add Python to an iOS Xcode project:
1. Build or obtain a Python ``XCFramework``. See the instructions in
:source:`iOS/README.rst` (in the CPython source distribution) for details on
how to build a Python ``XCFramework``. At a minimum, you will need a build
that supports ``arm64-apple-ios``, plus one of either
``arm64-apple-ios-simulator`` or ``x86_64-apple-ios-simulator``.
2. Drag the ``XCframework`` into your iOS project. In the following
instructions, we'll assume you've dropped the ``XCframework`` into the root
of your project; however, you can use any other location that you want by
adjusting paths as needed.
3. Drag the ``iOS/Resources/dylib-Info-template.plist`` file into your project,
and ensure it is associated with the app target.
4. Add your application code as a folder in your Xcode project. In the
following instructions, we'll assume that your user code is in a folder
named ``app`` in the root of your project; you can use any other location by
adjusting paths as needed. Ensure that this folder is associated with your
app target.
5. Select the app target by selecting the root node of your Xcode project, then
the target name in the sidebar that appears.
6. In the "General" settings, under "Frameworks, Libraries and Embedded
Content", add ``Python.xcframework``, with "Embed & Sign" selected.
7. In the "Build Settings" tab, modify the following:
- Build Options
* User Script Sandboxing: No
* Enable Testability: Yes
- Search Paths
* Framework Search Paths: ``$(PROJECT_DIR)``
* Header Search Paths: ``"$(BUILT_PRODUCTS_DIR)/Python.framework/Headers"``
- Apple Clang - Warnings - All languages
* Quoted Include In Framework Header: No
8. Add a build step that copies the Python standard library into your app. In
the "Build Phases" tab, add a new "Run Script" build step *before* the
"Embed Frameworks" step, but *after* the "Copy Bundle Resources" step. Name
the step "Install Target Specific Python Standard Library", disable the
"Based on dependency analysis" checkbox, and set the script content to:
.. code-block:: bash
set -e
mkdir -p "$CODESIGNING_FOLDER_PATH/python/lib"
if [ "$EFFECTIVE_PLATFORM_NAME" = "-iphonesimulator" ]; then
echo "Installing Python modules for iOS Simulator"
rsync -au --delete "$PROJECT_DIR/Python.xcframework/ios-arm64_x86_64-simulator/lib/" "$CODESIGNING_FOLDER_PATH/python/lib/"
else
echo "Installing Python modules for iOS Device"
rsync -au --delete "$PROJECT_DIR/Python.xcframework/ios-arm64/lib/" "$CODESIGNING_FOLDER_PATH/python/lib/"
fi
Note that the name of the simulator "slice" in the XCframework may be
different, depending the CPU architectures your ``XCFramework`` supports.
9. Add a second build step that processes the binary extension modules in the
standard library into "Framework" format. Add a "Run Script" build step
*directly after* the one you added in step 8, named "Prepare Python Binary
Modules". It should also have "Based on dependency analysis" unchecked, with
the following script content:
.. code-block:: bash
set -e
install_dylib () {
INSTALL_BASE=$1
FULL_EXT=$2
# The name of the extension file
EXT=$(basename "$FULL_EXT")
# The location of the extension file, relative to the bundle
RELATIVE_EXT=${FULL_EXT#$CODESIGNING_FOLDER_PATH/}
# The path to the extension file, relative to the install base
PYTHON_EXT=${RELATIVE_EXT/$INSTALL_BASE/}
# The full dotted name of the extension module, constructed from the file path.
FULL_MODULE_NAME=$(echo $PYTHON_EXT | cut -d "." -f 1 | tr "/" ".");
# A bundle identifier; not actually used, but required by Xcode framework packaging
FRAMEWORK_BUNDLE_ID=$(echo $PRODUCT_BUNDLE_IDENTIFIER.$FULL_MODULE_NAME | tr "_" "-")
# The name of the framework folder.
FRAMEWORK_FOLDER="Frameworks/$FULL_MODULE_NAME.framework"
# If the framework folder doesn't exist, create it.
if [ ! -d "$CODESIGNING_FOLDER_PATH/$FRAMEWORK_FOLDER" ]; then
echo "Creating framework for $RELATIVE_EXT"
mkdir -p "$CODESIGNING_FOLDER_PATH/$FRAMEWORK_FOLDER"
cp "$CODESIGNING_FOLDER_PATH/dylib-Info-template.plist" "$CODESIGNING_FOLDER_PATH/$FRAMEWORK_FOLDER/Info.plist"
plutil -replace CFBundleExecutable -string "$FULL_MODULE_NAME" "$CODESIGNING_FOLDER_PATH/$FRAMEWORK_FOLDER/Info.plist"
plutil -replace CFBundleIdentifier -string "$FRAMEWORK_BUNDLE_ID" "$CODESIGNING_FOLDER_PATH/$FRAMEWORK_FOLDER/Info.plist"
fi
echo "Installing binary for $FRAMEWORK_FOLDER/$FULL_MODULE_NAME"
mv "$FULL_EXT" "$CODESIGNING_FOLDER_PATH/$FRAMEWORK_FOLDER/$FULL_MODULE_NAME"
# Create a placeholder .fwork file where the .so was
echo "$FRAMEWORK_FOLDER/$FULL_MODULE_NAME" > ${FULL_EXT%.so}.fwork
# Create a back reference to the .so file location in the framework
echo "${RELATIVE_EXT%.so}.fwork" > "$CODESIGNING_FOLDER_PATH/$FRAMEWORK_FOLDER/$FULL_MODULE_NAME.origin"
}
PYTHON_VER=$(ls -1 "$CODESIGNING_FOLDER_PATH/python/lib")
echo "Install Python $PYTHON_VER standard library extension modules..."
find "$CODESIGNING_FOLDER_PATH/python/lib/$PYTHON_VER/lib-dynload" -name "*.so" | while read FULL_EXT; do
install_dylib python/lib/$PYTHON_VER/lib-dynload/ "$FULL_EXT"
done
# Clean up dylib template
rm -f "$CODESIGNING_FOLDER_PATH/dylib-Info-template.plist"
echo "Signing frameworks as $EXPANDED_CODE_SIGN_IDENTITY_NAME ($EXPANDED_CODE_SIGN_IDENTITY)..."
find "$CODESIGNING_FOLDER_PATH/Frameworks" -name "*.framework" -exec /usr/bin/codesign --force --sign "$EXPANDED_CODE_SIGN_IDENTITY" ${OTHER_CODE_SIGN_FLAGS:-} -o runtime --timestamp=none --preserve-metadata=identifier,entitlements,flags --generate-entitlement-der "{}" \;
10. Add Objective C code to initialize and use a Python interpreter in embedded
mode. You should ensure that:
* :c:member:`UTF-8 mode <PyPreConfig.utf8_mode>` is *enabled*;
* :c:member:`Buffered stdio <PyConfig.buffered_stdio>` is *disabled*;
* :c:member:`Writing bytecode <PyConfig.write_bytecode>` is *disabled*;
* :c:member:`Signal handlers <PyConfig.install_signal_handlers>` are *enabled*;
* ``PYTHONHOME`` for the interpreter is configured to point at the
``python`` subfolder of your app's bundle; and
* The ``PYTHONPATH`` for the interpreter includes:
- the ``python/lib/python3.X`` subfolder of your app's bundle,
- the ``python/lib/python3.X/lib-dynload`` subfolder of your app's bundle, and
- the ``app`` subfolder of your app's bundle
Your app's bundle location can be determined using ``[[NSBundle mainBundle]
resourcePath]``.
Steps 8, 9 and 10 of these instructions assume that you have a single folder of
pure Python application code, named ``app``. If you have third-party binary
modules in your app, some additional steps will be required:
* You need to ensure that any folders containing third-party binaries are
either associated with the app target, or copied in as part of step 8. Step 8
should also purge any binaries that are not appropriate for the platform a
specific build is targetting (i.e., delete any device binaries if you're
building app app targeting the simulator).
* Any folders that contain third-party binaries must be processed into
framework form by step 9. The invocation of ``install_dylib`` that processes
the ``lib-dynload`` folder can be copied and adapted for this purpose.
* If you're using a separate folder for third-party packages, ensure that folder
is included as part of the ``PYTHONPATH`` configuration in step 10.

View File

@ -0,0 +1 @@
Add an iOS platform guide, and flag modules not available on iOS.

View File

@ -0,0 +1 @@
Remove compatibilty references to Emscripten.

View File

@ -182,7 +182,10 @@ This can be done by defining the ``LIBLZMA_CFLAGS``, ``LIBLZMA_LIBS``,
``BZIP2_CFLAGS``, ``BZIP2_LIBS``, ``LIBFFI_CFLAGS``, and ``LIBFFI_LIBS``
environment variables, and the ``--with-openssl`` configure option. Versions of
these libraries pre-compiled for iOS can be found in `this repository
<https://github.com/beeware/cpython-apple-source-deps/releases>`__.
<https://github.com/beeware/cpython-apple-source-deps/releases>`__. LibFFI is
especially important, as many parts of the standard library (including the
``platform``, ``sysconfig`` and ``webbrowser`` modules) require the use of the
``ctypes`` module at runtime.
By default, Python will be compiled with an iOS deployment target (i.e., the
minimum supported iOS version) of 12.0. To specify a different deployment
@ -248,16 +251,11 @@ the XCframework::
cp path/to/iphoneos/bin Python.xcframework/ios-arm64
cp path/to/iphoneos/lib Python.xcframework/ios-arm64
cp path/to/iphonesimulator/bin Python.xcframework/ios-arm64_x86-64-simulator
cp path/to/iphonesimulator/lib Python.xcframework/ios-arm64_x86-64-simulator
cp path/to/iphonesimulator/bin Python.xcframework/ios-arm64_x86_64-simulator
cp path/to/iphonesimulator/lib Python.xcframework/ios-arm64_x86_64-simulator
Note that the name of the architecture-specific slice for the simulator will
depend on the CPU architecture that you build.
Then, add symbolic links to "common" platform names for each slice::
ln -si ios-arm64 Python.xcframework/iphoneos
ln -si ios-arm64_x86-64-simulator Python.xcframework/iphonesimulator
depend on the CPU architecture(s) that you build.
You now have a Python.xcframework that can be used in a project.
@ -306,6 +304,49 @@ Debugging test failures
The easiest way to diagnose a single test failure is to open the testbed project
in Xcode and run the tests from there using the "Product > Test" menu item.
To test in Xcode, you must ensure the testbed project has a copy of a compiled
framework. If you've configured your build with the default install location of
``iOS/Frameworks``, you can copy from that location into the test project. To
test on an ARM64 simulator, run::
$ rm -rf iOS/testbed/Python.xcframework/ios-arm64_x86_64-simulator/*
$ cp -r iOS/Frameworks/arm64-iphonesimulator/* iOS/testbed/Python.xcframework/ios-arm64_x86_64-simulator
To test on an x86-64 simulator, run::
$ rm -rf iOS/testbed/Python.xcframework/ios-arm64_x86_64-simulator/*
$ cp -r iOS/Frameworks/x86_64-iphonesimulator/* iOS/testbed/Python.xcframework/ios-arm64_x86_64-simulator
To test on a physical device::
$ rm -rf iOS/testbed/Python.xcframework/ios-arm64/*
$ cp -r iOS/Frameworks/arm64-iphoneos/* iOS/testbed/Python.xcframework/ios-arm64
Alternatively, you can configure your build to install directly into the
testbed project. For a simulator, use::
--enable-framework=$(pwd)/iOS/testbed/Python.xcframework/ios-arm64_x86_64-simulator
For a physical device, use::
--enable-framework=$(pwd)/iOS/testbed/Python.xcframework/ios-arm64
Testing on an iOS device
^^^^^^^^^^^^^^^^^^^^^^^^
To test on an iOS device, the app needs to be signed with known developer
credentials. To obtain these credentials, you must have an iOS Developer
account, and your Xcode install will need to be logged into your account (see
the Accounts tab of the Preferences dialog).
Once the project is open, and you're signed into your Apple Developer account,
select the root node of the project tree (labeled "iOSTestbed"), then the
"Signing & Capabilities" tab in the details page. Select a development team
(this will likely be your own name), and plug in a physical device to your
macOS machine with a USB cable. You should then be able to select your physical
device from the list of targets in the pulldown in the Xcode titlebar.
Running specific tests
^^^^^^^^^^^^^^^^^^^^^^