Skip to content

Commit fe642c7

Browse files
[3.9] pythongh-120522: Apply App Store compliance patch during installation (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 <[email protected]>
1 parent cee4bde commit fe642c7

File tree

7 files changed

+149
-2
lines changed

7 files changed

+149
-2
lines changed

Doc/library/urllib.parse.rst

+8
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ Resource Locators. It supports the following URL schemes: ``file``, ``ftp``,
2727
``shttp``, ``sip``, ``sips``, ``snews``, ``svn``, ``svn+ssh``, ``telnet``,
2828
``wais``, ``ws``, ``wss``.
2929

30+
.. impl-detail::
31+
32+
The inclusion of the ``itms-services`` URL scheme can prevent an app from
33+
passing Apple's App Store review process for the macOS and iOS App Stores.
34+
Handling for the ``itms-services`` scheme is always removed on iOS; on
35+
macOS, it *may* be removed if CPython has been built with the
36+
:option:`--with-app-store-compliance` option.
37+
3038
The :mod:`urllib.parse` module defines functions that fall into two broad
3139
categories: URL parsing and URL quoting. These are covered in detail in
3240
the following sections.

Doc/using/mac.rst

+22
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,28 @@ The standard tool for deploying standalone Python applications on the Mac is
163163
at https://pypi.org/project/py2app/.
164164

165165

166+
App Store Compliance
167+
--------------------
168+
169+
Apps submitted for distribution through the macOS App Store must pass Apple's
170+
app review process. This process includes a set of automated validation rules
171+
that inspect the submitted application bundle for problematic code.
172+
173+
The Python standard library contains some code that is known to violate these
174+
automated rules. While these violations appear to be false positives, Apple's
175+
review rules cannot be challenged. Therefore, it is necessary to modify the
176+
Python standard library for an app to pass App Store review.
177+
178+
The Python source tree contains
179+
:source:`a patch file <Mac/Resources/app-store-compliance.patch>` that will remove
180+
all code that is known to cause issues with the App Store review process. This
181+
patch is applied automatically when CPython is configured with the
182+
:option:`--with-app-store-compliance` option.
183+
184+
This patch is not normally required to use CPython on a Mac; nor is it required
185+
if you are distributing an app *outside* the macOS App Store. It is *only*
186+
required if you are using the macOS App Store as a distribution channel.
187+
166188
Other Resources
167189
===============
168190

Mac/Resources/app-store-compliance.patch

Whitespace-only changes.

Makefile.pre.in

+24-2
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ EXPORTSFROM= @EXPORTSFROM@
168168
EXE= @EXEEXT@
169169
BUILDEXE= @BUILDEXEEXT@
170170

171+
# Name of the patch file to apply for app store compliance
172+
APP_STORE_COMPLIANCE_PATCH=@APP_STORE_COMPLIANCE_PATCH@
173+
171174
# Short name and location for Mac OS X Python framework
172175
UNIVERSALSDK=@UNIVERSALSDK@
173176
PYTHONFRAMEWORK= @PYTHONFRAMEWORK@
@@ -483,7 +486,7 @@ DTRACE_DEPS = \
483486

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

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

501+
# Check that the app store compliance patch can be applied (if configured).
502+
# This is checked as a dry-run against the original library sources;
503+
# the patch will be actually applied during the install phase.
504+
.PHONY: check-app-store-compliance
505+
check-app-store-compliance:
506+
@if [ "$(APP_STORE_COMPLIANCE_PATCH)" != "" ]; then \
507+
patch --dry-run --quiet --force --strip 1 --directory "$(abs_srcdir)" --input "$(abs_srcdir)/$(APP_STORE_COMPLIANCE_PATCH)"; \
508+
echo "App store compliance patch can be applied."; \
509+
fi
510+
498511
# Profile generation build must start from a clean tree.
499512
profile-clean-stamp:
500513
$(MAKE) clean
@@ -1626,7 +1639,16 @@ libinstall: build_all $(srcdir)/Modules/xxmodule.c
16261639
$(INSTALL_DATA) $(srcdir)/Modules/xxmodule.c \
16271640
$(DESTDIR)$(LIBDEST)/distutils/tests ; \
16281641
fi
1629-
-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
1642+
@ # If app store compliance has been configured, apply the patch to the
1643+
@ # installed library code. The patch has been previously validated against
1644+
@ # the original source tree, so we can ignore any errors that are raised
1645+
@ # due to files that are missing because of --disable-test-modules etc.
1646+
@if [ "$(APP_STORE_COMPLIANCE_PATCH)" != "" ]; then \
1647+
echo "Applying app store compliance patch"; \
1648+
patch --force --reject-file "$(abs_builddir)/app-store-compliance.rej" --strip 2 --directory "$(DESTDIR)$(LIBDEST)" --input "$(abs_srcdir)/$(APP_STORE_COMPLIANCE_PATCH)" || true ; \
1649+
fi
1650+
@ # Build PYC files for the 3 optimization levels (0, 1, 2)
1651+
-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
16301652
$(PYTHON_FOR_BUILD) -Wi $(DESTDIR)$(LIBDEST)/compileall.py \
16311653
-j0 -d $(LIBDEST) -f \
16321654
-x 'bad_coding|badsyntax|site-packages|lib2to3/tests/data' \
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Added a :option:`--with-app-store-compliance` option to patch out known
2+
issues with macOS/iOS App Store review processes.

configure

+52
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,7 @@ IPHONEOS_DEPLOYMENT_TARGET
737737
EXPORT_MACOSX_DEPLOYMENT_TARGET
738738
CONFIGURE_MACOSX_DEPLOYMENT_TARGET
739739
_PYTHON_HOST_PLATFORM
740+
APP_STORE_COMPLIANCE_PATCH
740741
INSTALLTARGETS
741742
FRAMEWORKINSTALLAPPSPREFIX
742743
FRAMEWORKUNIXTOOLSPREFIX
@@ -820,6 +821,7 @@ enable_universalsdk
820821
with_universal_archs
821822
with_framework_name
822823
enable_framework
824+
with_app_store_compliance
823825
with_cxx_main
824826
with_suffix
825827
enable_shared
@@ -1524,6 +1526,10 @@ Optional Packages:
15241526
specify the name for the python framework on macOS
15251527
only valid when --enable-framework is set. see
15261528
Mac/README.rst (default is 'Python')
1529+
--with-app-store-compliance=[PATCH-FILE]
1530+
Enable any patches required for compiliance with app
1531+
stores. Optional PATCH-FILE specifies the custom
1532+
patch to apply.
15271533
--with-cxx-main[=COMPILER]
15281534
compile main() and link Python executable with C++
15291535
compiler specified in COMPILER (default is $CXX)
@@ -3457,6 +3463,52 @@ cat >>confdefs.h <<_ACEOF
34573463
_ACEOF
34583464

34593465

3466+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-app-store-compliance" >&5
3467+
$as_echo_n "checking for --with-app-store-compliance... " >&6; }
3468+
3469+
# Check whether --with-app_store_compliance was given.
3470+
if test "${with_app_store_compliance+set}" = set; then :
3471+
withval=$with_app_store_compliance;
3472+
case "$withval" in
3473+
yes)
3474+
case $ac_sys_system in
3475+
Darwin|iOS)
3476+
# iOS is able to share the macOS patch
3477+
APP_STORE_COMPLIANCE_PATCH="Mac/Resources/app-store-compliance.patch"
3478+
;;
3479+
*) as_fn_error $? "no default app store compliance patch available for $ac_sys_system" "$LINENO" 5 ;;
3480+
esac
3481+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: applying default app store compliance patch" >&5
3482+
$as_echo "applying default app store compliance patch" >&6; }
3483+
;;
3484+
*)
3485+
APP_STORE_COMPLIANCE_PATCH="${withval}"
3486+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: applying custom app store compliance patch" >&5
3487+
$as_echo "applying custom app store compliance patch" >&6; }
3488+
;;
3489+
esac
3490+
3491+
else
3492+
3493+
case $ac_sys_system in
3494+
iOS)
3495+
# Always apply the compliance patch on iOS; we can use the macOS patch
3496+
APP_STORE_COMPLIANCE_PATCH="Mac/Resources/app-store-compliance.patch"
3497+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: applying default app store compliance patch" >&5
3498+
$as_echo "applying default app store compliance patch" >&6; }
3499+
;;
3500+
*)
3501+
# No default app compliance patching on any other platform
3502+
APP_STORE_COMPLIANCE_PATCH=
3503+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not patching for app store compliance" >&5
3504+
$as_echo "not patching for app store compliance" >&6; }
3505+
;;
3506+
esac
3507+
3508+
fi
3509+
3510+
3511+
34603512

34613513

34623514
# Set name for machine-dependent library files

configure.ac

+41
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,47 @@ AC_SUBST([INSTALLTARGETS])
541541

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

544+
dnl quadrigraphs "@<:@" and "@:>@" produce "[" and "]" in the output
545+
AC_MSG_CHECKING([for --with-app-store-compliance])
546+
AC_ARG_WITH(
547+
[app_store_compliance],
548+
[AS_HELP_STRING(
549+
[--with-app-store-compliance=@<:@PATCH-FILE@:>@],
550+
[Enable any patches required for compiliance with app stores.
551+
Optional PATCH-FILE specifies the custom patch to apply.]
552+
)],[
553+
case "$withval" in
554+
yes)
555+
case $ac_sys_system in
556+
Darwin|iOS)
557+
# iOS is able to share the macOS patch
558+
APP_STORE_COMPLIANCE_PATCH="Mac/Resources/app-store-compliance.patch"
559+
;;
560+
*) AC_MSG_ERROR([no default app store compliance patch available for $ac_sys_system]) ;;
561+
esac
562+
AC_MSG_RESULT([applying default app store compliance patch])
563+
;;
564+
*)
565+
APP_STORE_COMPLIANCE_PATCH="${withval}"
566+
AC_MSG_RESULT([applying custom app store compliance patch])
567+
;;
568+
esac
569+
],[
570+
case $ac_sys_system in
571+
iOS)
572+
# Always apply the compliance patch on iOS; we can use the macOS patch
573+
APP_STORE_COMPLIANCE_PATCH="Mac/Resources/app-store-compliance.patch"
574+
AC_MSG_RESULT([applying default app store compliance patch])
575+
;;
576+
*)
577+
# No default app compliance patching on any other platform
578+
APP_STORE_COMPLIANCE_PATCH=
579+
AC_MSG_RESULT([not patching for app store compliance])
580+
;;
581+
esac
582+
])
583+
AC_SUBST([APP_STORE_COMPLIANCE_PATCH])
584+
544585
AC_SUBST([_PYTHON_HOST_PLATFORM])
545586

546587
# Set name for machine-dependent library files

0 commit comments

Comments
 (0)