Bug 1673700 - Don't use double quotes around strings in definition of `fork_interpose` r=firefox-build-system-reviewers,glandium

The definition of `patch_main()` has behavior that kicks in only on Windows and for Python 2. Unfortunately, not all of our `mach` commands have been migrated to Python 3, so this still matters.

Bug 1654103 replaced the single-quoted strings in this function with double-quoted strings. This should be fine, except that we call into `multiprocessing.forking.main()` with some monkey-patching that is meant to fix a Windows-specific bug (see bug 1316140). We don't do any clever serialization or anything here and we end up just passing that source to `multiprocessing.forking.main()` which aggregates that source code [dumbly](https://github.com/python/cpython/blob/2.7/Lib/multiprocessing/forking.py#L259), wrapping everything in double-quotes again and passing it to `_subprocess.CreateProcess()`, which ends up failing if the source contains strings formatted with double quotes.

We could revert bug 1654103 and exempt this file from linting, but that is overkill given that this file otherwise contains useful stuff. Instead we move everything to another file, exempt that file from linting, and update `util.py` accordingly.

Differential Revision: https://phabricator.services.mozilla.com/D94909
This commit is contained in:
Ricky Stewart 2020-10-29 15:47:14 +00:00
Родитель df27f3685c
Коммит fbe2b42f80
5 изменённых файлов: 51 добавлений и 42 удалений

Просмотреть файл

@ -19,7 +19,7 @@ exclude =
netwerk/protocol/http/make_incoming_tables.py,
python/devtools/migrate-l10n/migrate/main.py,
python/l10n/fluent_migrations,
python/mozbuild/dumbmake,
python/mozbuild/mozbuild/fork_interpose.py,
security/manager/ssl/tests/unit,
servo/components/style,
testing/condprofile/condprof/android.py,

Просмотреть файл

@ -0,0 +1,42 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
# This source code is indirectly used in python/mozbuild/mozbuild/util.py and
# is not meant to be imported. This file can be entirely deleted when the
# transition to Python 3 is complete.
import imp
import os
import sys
orig_find_module = imp.find_module
def my_find_module(name, dirs):
if name == main_module_name:
path = os.path.join(dirs[0], main_file_name)
f = open(path)
return (f, path, ('', 'r', imp.PY_SOURCE))
return orig_find_module(name, dirs)
# Don't allow writing bytecode file for the main module.
orig_load_module = imp.load_module
def my_load_module(name, file, path, description):
# multiprocess.forking invokes imp.load_module manually and
# hard-codes the name __parents_main__ as the module name.
if name == '__parents_main__':
old_bytecode = sys.dont_write_bytecode
sys.dont_write_bytecode = True
try:
return orig_load_module(name, file, path, description)
finally:
sys.dont_write_bytecode = old_bytecode
return orig_load_module(name, file, path, description)
imp.find_module = my_find_module
imp.load_module = my_load_module
from multiprocessing.forking import main
main()

Просмотреть файл

@ -1426,7 +1426,6 @@ def patch_main():
# not, but at least some basic mach commands appear to work without it. So
# skip it in 3.4+ until we determine it's still needed.
if sys.platform == "win32" and sys.version_info < (3, 4):
import inspect
import os
from multiprocessing import forking
@ -1445,50 +1444,16 @@ def patch_main():
# If main is a .py file, everything ought to work as expected.
return
def fork_interpose():
import imp
import os
import sys
orig_find_module = imp.find_module
def my_find_module(name, dirs):
if name == main_module_name:
path = os.path.join(dirs[0], main_file_name)
f = open(path)
return (f, path, ("", "r", imp.PY_SOURCE))
return orig_find_module(name, dirs)
# Don't allow writing bytecode file for the main module.
orig_load_module = imp.load_module
def my_load_module(name, file, path, description):
# multiprocess.forking invokes imp.load_module manually and
# hard-codes the name __parents_main__ as the module name.
if name == "__parents_main__":
old_bytecode = sys.dont_write_bytecode
sys.dont_write_bytecode = True
try:
return orig_load_module(name, file, path, description)
finally:
sys.dont_write_bytecode = old_bytecode
return orig_load_module(name, file, path, description)
imp.find_module = my_find_module
imp.load_module = my_load_module
from multiprocessing.forking import main
main()
def my_get_command_line():
fork_code, lineno = inspect.getsourcelines(fork_interpose)
# Remove the first line (for 'def fork_interpose():') and the three
# levels of indentation (12 spaces), add our relevant globals.
with open(
os.path.join(os.path.dirname(__file__), "fork_interpose.py"), "rU"
) as fork_file:
fork_code = fork_file.read()
# Add our relevant globals.
fork_string = (
"main_file_name = '%s'\n" % main_file_name
+ "main_module_name = '%s'\n" % main_module_name
+ "".join(x[12:] for x in fork_code[1:])
+ fork_code
)
cmdline = orig_command_line()
# We don't catch errors if "-c" is not found because it's not clear

Просмотреть файл

@ -4,6 +4,7 @@ black:
exclude:
- gfx/harfbuzz/src/meson.build
- layout/style/ServoCSSPropList.mako.py
- python/mozbuild/mozbuild/fork_interpose.py
- python/mozbuild/mozbuild/test/frontend/data/reader-error-syntax/moz.build
- testing/mozharness/configs/test/test_malformed.py
- testing/web-platform/tests

Просмотреть файл

@ -15,6 +15,7 @@ py2:
- netwerk
- nsprpub
- other-licenses
- python/mozbuild/mozbuild/fork_interpose.py
- security
- servo
- taskcluster/docker/funsize-update-generator