Skip to content

Commit

Permalink
[3.9] pythongh-120522: Apply App Store compliance patch during instal…
Browse files Browse the repository at this point in the history
…lation (pythonGH-121947) (python#122105)

pythongh-120522: Apply App Store compliance patch during installation (pythonGH-121947)

Adds a --with-app-store-compliance configuration option that patches out code known to be an issue with App Store review processes. This option is applied automatically on iOS, and optionally on macOS.
(cherry picked from commit 728432c)

Co-authored-by: Russell Keith-Magee <russell@keith-magee.com>
  • Loading branch information
miss-islington and freakboy3742 committed Sep 9, 2024
1 parent 2494c50 commit f35c708
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 2 deletions.
8 changes: 8 additions & 0 deletions Doc/library/urllib.parse.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ Resource Locators. It supports the following URL schemes: ``file``, ``ftp``,
``shttp``, ``sip``, ``sips``, ``snews``, ``svn``, ``svn+ssh``, ``telnet``,
``wais``, ``ws``, ``wss``.

.. impl-detail::

The inclusion of the ``itms-services`` URL scheme can prevent an app from
passing Apple's App Store review process for the macOS and iOS App Stores.
Handling for the ``itms-services`` scheme is always removed on iOS; on
macOS, it *may* be removed if CPython has been built with the
:option:`--with-app-store-compliance` option.

The :mod:`urllib.parse` module defines functions that fall into two broad
categories: URL parsing and URL quoting. These are covered in detail in
the following sections.
Expand Down
22 changes: 22 additions & 0 deletions Doc/using/mac.rst
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,28 @@ The standard tool for deploying standalone Python applications on the Mac is
at https://pypi.org/project/py2app/.


App Store Compliance
--------------------

Apps submitted for distribution through the macOS App Store must pass Apple's
app review process. This process includes a set of automated validation rules
that inspect the submitted application bundle for problematic code.

The Python standard library contains some code that is known to violate these
automated rules. While these violations appear to be false positives, Apple's
review rules cannot be challenged. Therefore, it is necessary to modify the
Python standard library for an app to pass App Store review.

The Python source tree contains
:source:`a patch file <Mac/Resources/app-store-compliance.patch>` that will remove
all code that is known to cause issues with the App Store review process. This
patch is applied automatically when CPython is configured with the
:option:`--with-app-store-compliance` option.

This patch is not normally required to use CPython on a Mac; nor is it required
if you are distributing an app *outside* the macOS App Store. It is *only*
required if you are using the macOS App Store as a distribution channel.

Other Resources
===============

Expand Down
Empty file.
26 changes: 24 additions & 2 deletions Makefile.pre.in
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,9 @@ EXPORTSFROM= @EXPORTSFROM@
EXE= @EXEEXT@
BUILDEXE= @BUILDEXEEXT@

# Name of the patch file to apply for app store compliance
APP_STORE_COMPLIANCE_PATCH=@APP_STORE_COMPLIANCE_PATCH@

# Short name and location for Mac OS X Python framework
UNIVERSALSDK=@UNIVERSALSDK@
PYTHONFRAMEWORK= @PYTHONFRAMEWORK@
Expand Down Expand Up @@ -483,7 +486,7 @@ DTRACE_DEPS = \

# Default target
all: @DEF_MAKE_ALL_RULE@
build_all: check-clean-src $(BUILDPYTHON) oldsharedmods sharedmods gdbhooks \
build_all: check-clean-src check-app-store-compliance $(BUILDPYTHON) oldsharedmods sharedmods gdbhooks \
Programs/_testembed python-config

# Check that the source is clean when building out of source.
Expand All @@ -495,6 +498,16 @@ check-clean-src:
exit 1; \
fi

# Check that the app store compliance patch can be applied (if configured).
# This is checked as a dry-run against the original library sources;
# the patch will be actually applied during the install phase.
.PHONY: check-app-store-compliance
check-app-store-compliance:
@if [ "$(APP_STORE_COMPLIANCE_PATCH)" != "" ]; then \
patch --dry-run --quiet --force --strip 1 --directory "$(abs_srcdir)" --input "$(abs_srcdir)/$(APP_STORE_COMPLIANCE_PATCH)"; \
echo "App store compliance patch can be applied."; \
fi

# Profile generation build must start from a clean tree.
profile-clean-stamp:
$(MAKE) clean
Expand Down Expand Up @@ -1626,7 +1639,16 @@ libinstall: build_all $(srcdir)/Modules/xxmodule.c
$(INSTALL_DATA) $(srcdir)/Modules/xxmodule.c \
$(DESTDIR)$(LIBDEST)/distutils/tests ; \
fi
-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
@ # If app store compliance has been configured, apply the patch to the
@ # installed library code. The patch has been previously validated against
@ # the original source tree, so we can ignore any errors that are raised
@ # due to files that are missing because of --disable-test-modules etc.
@if [ "$(APP_STORE_COMPLIANCE_PATCH)" != "" ]; then \
echo "Applying app store compliance patch"; \
patch --force --reject-file "$(abs_builddir)/app-store-compliance.rej" --strip 2 --directory "$(DESTDIR)$(LIBDEST)" --input "$(abs_srcdir)/$(APP_STORE_COMPLIANCE_PATCH)" || true ; \
fi
@ # Build PYC files for the 3 optimization levels (0, 1, 2)
-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
$(PYTHON_FOR_BUILD) -Wi $(DESTDIR)$(LIBDEST)/compileall.py \
-j0 -d $(LIBDEST) -f \
-x 'bad_coding|badsyntax|site-packages|lib2to3/tests/data' \
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Added a :option:`--with-app-store-compliance` option to patch out known
issues with macOS/iOS App Store review processes.
52 changes: 52 additions & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,7 @@ IPHONEOS_DEPLOYMENT_TARGET
EXPORT_MACOSX_DEPLOYMENT_TARGET
CONFIGURE_MACOSX_DEPLOYMENT_TARGET
_PYTHON_HOST_PLATFORM
APP_STORE_COMPLIANCE_PATCH
INSTALLTARGETS
FRAMEWORKINSTALLAPPSPREFIX
FRAMEWORKUNIXTOOLSPREFIX
Expand Down Expand Up @@ -820,6 +821,7 @@ enable_universalsdk
with_universal_archs
with_framework_name
enable_framework
with_app_store_compliance
with_cxx_main
with_suffix
enable_shared
Expand Down Expand Up @@ -1524,6 +1526,10 @@ Optional Packages:
specify the name for the python framework on macOS
only valid when --enable-framework is set. see
Mac/README.rst (default is 'Python')
--with-app-store-compliance=[PATCH-FILE]
Enable any patches required for compiliance with app
stores. Optional PATCH-FILE specifies the custom
patch to apply.
--with-cxx-main[=COMPILER]
compile main() and link Python executable with C++
compiler specified in COMPILER (default is $CXX)
Expand Down Expand Up @@ -3457,6 +3463,52 @@ cat >>confdefs.h <<_ACEOF
_ACEOF


{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-app-store-compliance" >&5
$as_echo_n "checking for --with-app-store-compliance... " >&6; }

# Check whether --with-app_store_compliance was given.
if test "${with_app_store_compliance+set}" = set; then :
withval=$with_app_store_compliance;
case "$withval" in
yes)
case $ac_sys_system in
Darwin|iOS)
# iOS is able to share the macOS patch
APP_STORE_COMPLIANCE_PATCH="Mac/Resources/app-store-compliance.patch"
;;
*) as_fn_error $? "no default app store compliance patch available for $ac_sys_system" "$LINENO" 5 ;;
esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: applying default app store compliance patch" >&5
$as_echo "applying default app store compliance patch" >&6; }
;;
*)
APP_STORE_COMPLIANCE_PATCH="${withval}"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: applying custom app store compliance patch" >&5
$as_echo "applying custom app store compliance patch" >&6; }
;;
esac

else

case $ac_sys_system in
iOS)
# Always apply the compliance patch on iOS; we can use the macOS patch
APP_STORE_COMPLIANCE_PATCH="Mac/Resources/app-store-compliance.patch"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: applying default app store compliance patch" >&5
$as_echo "applying default app store compliance patch" >&6; }
;;
*)
# No default app compliance patching on any other platform
APP_STORE_COMPLIANCE_PATCH=
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not patching for app store compliance" >&5
$as_echo "not patching for app store compliance" >&6; }
;;
esac

fi





# Set name for machine-dependent library files
Expand Down
41 changes: 41 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,47 @@ AC_SUBST([INSTALLTARGETS])

AC_DEFINE_UNQUOTED(_PYTHONFRAMEWORK, "${PYTHONFRAMEWORK}", [framework name])

dnl quadrigraphs "@<:@" and "@:>@" produce "[" and "]" in the output
AC_MSG_CHECKING([for --with-app-store-compliance])
AC_ARG_WITH(
[app_store_compliance],
[AS_HELP_STRING(
[--with-app-store-compliance=@<:@PATCH-FILE@:>@],
[Enable any patches required for compiliance with app stores.
Optional PATCH-FILE specifies the custom patch to apply.]
)],[
case "$withval" in
yes)
case $ac_sys_system in
Darwin|iOS)
# iOS is able to share the macOS patch
APP_STORE_COMPLIANCE_PATCH="Mac/Resources/app-store-compliance.patch"
;;
*) AC_MSG_ERROR([no default app store compliance patch available for $ac_sys_system]) ;;
esac
AC_MSG_RESULT([applying default app store compliance patch])
;;
*)
APP_STORE_COMPLIANCE_PATCH="${withval}"
AC_MSG_RESULT([applying custom app store compliance patch])
;;
esac
],[
case $ac_sys_system in
iOS)
# Always apply the compliance patch on iOS; we can use the macOS patch
APP_STORE_COMPLIANCE_PATCH="Mac/Resources/app-store-compliance.patch"
AC_MSG_RESULT([applying default app store compliance patch])
;;
*)
# No default app compliance patching on any other platform
APP_STORE_COMPLIANCE_PATCH=
AC_MSG_RESULT([not patching for app store compliance])
;;
esac
])
AC_SUBST([APP_STORE_COMPLIANCE_PATCH])

AC_SUBST([_PYTHON_HOST_PLATFORM])

# Set name for machine-dependent library files
Expand Down

0 comments on commit f35c708

Please sign in to comment.