[mach] Add support for Python 3
Categories
(Firefox Build System :: General, enhancement)
Tracking
(Not tracked)
People
(Reporter: davehunt, Assigned: ahal)
References
Details
User Story
To work on this bug you will need to install and configure Mercurial, which will enable you to download the Firefox source code. It will also be used to commit your changes locally and prepare a patch for review. See the installation guide at https://mozilla-version-control-tools.readthedocs.io/en/latest/hgmozilla/installing.html for help getting Mercurial on your system. Once installed, there are some extensions we recommend installing, details of these can be found here: https://mozilla-version-control-tools.readthedocs.io/en/latest/hgmozilla/extensions.html To clone the Firefox source code we recommend using the unified repository. Details of this and how to create a bookmark for your work can be found here: https://mozilla-version-control-tools.readthedocs.io/en/latest/hgmozilla/unifiedrepo.html As this bug relates to Python 3, you will need to have this installed on your system. Our continuous integration is currently using Python 3.5, so for best results we recommend using the same version locally. There are a number of ways to install Python, and they vary depending on your environment. We suggest reading over the guides at http://docs.python-guide.org/en/latest/starting/installation/#python-3-installation-guides to find the best method for you. Note that we also need to maintain support for Python 2, so you'll also need to have Python 2.7 installed. Whilst we're moving towards adding support for Python 3, we've disabled any tests that fail against this version. This means that in order to work on this bug you will need to enable the tests. This can be done by removing "skip-if = python == 3" from the manifest file in `python/mach/mach/test/python.ini` To run the tests against Python 3, execute the following command: ``` mach python-test --python=3.5 python/mach ``` Work through the test failures, and update the tests and source code for the package to simultaneously support Python 2.7 and Python 3.5. You can always check that your changes have not inadvertently broken support for Python 2 by using `--python=2.7` on the command line. If you're new to Python 3, the guide at https://docs.python.org/3/howto/pyporting.html may help you to get started with understanding the differences. To assist with supporting both Python 2 and 3, we have vendored the "six" package. You can read more about this and how to use it at https://pythonhosted.org/six/ Once the package supports Python 3 and the tests pass, bump the version number in `python/mach/setup.py` to "1.0.0", and update the classifiers so they reflect the versions of Python that we now support. When your patch(es) are ready, you will need to push them for review. We are use MozReview for this, and instructions for how to prepare your machine and how to structure your commit messages can be found in our guide: https://mozilla-version-control-tools.readthedocs.io/en/latest/mozreview-user.html There may be some review issues to address, but once your contribution has been approved and subsequently landed, we will release the new version of the package!
Attachments
(17 files, 5 obsolete files)
47 bytes,
text/x-phabricator-request
|
Details | Review | |
47 bytes,
text/x-phabricator-request
|
Details | Review | |
47 bytes,
text/x-phabricator-request
|
Details | Review | |
47 bytes,
text/x-phabricator-request
|
Details | Review | |
47 bytes,
text/x-phabricator-request
|
Details | Review | |
47 bytes,
text/x-phabricator-request
|
Details | Review | |
47 bytes,
text/x-phabricator-request
|
Details | Review | |
47 bytes,
text/x-phabricator-request
|
Details | Review | |
47 bytes,
text/x-phabricator-request
|
Details | Review | |
47 bytes,
text/x-phabricator-request
|
Details | Review | |
47 bytes,
text/x-phabricator-request
|
Details | Review | |
47 bytes,
text/x-phabricator-request
|
Details | Review | |
47 bytes,
text/x-phabricator-request
|
Details | Review | |
47 bytes,
text/x-phabricator-request
|
Details | Review | |
47 bytes,
text/x-phabricator-request
|
Details | Review | |
Bug 1473498 - [mozbuild.base] Fix Python 3 incompatibilities in mozconfig error handling, r?glandium
47 bytes,
text/x-phabricator-request
|
Details | Review | |
47 bytes,
text/x-phabricator-request
|
Details | Review |
Reporter | ||
Updated•6 years ago
|
Comment 1•6 years ago
|
||
Assignee | ||
Comment 2•6 years ago
|
||
The code base is too large to convert all at once, so we need to do it piece by piece. Mach is a library that almost all Python in-tree depends on, so it will need to support both until the migration has finished.
Assignee | ||
Comment 3•5 years ago
|
||
Assignee | ||
Comment 4•5 years ago
|
||
This test is working with minimal effort. Let's get it running to prevent
future regressions.
Depends on D36097
Assignee | ||
Comment 5•5 years ago
|
||
Depends on D36098
Assignee | ||
Comment 6•5 years ago
|
||
Depends on D36100
Assignee | ||
Comment 7•5 years ago
|
||
Depends on D36101
Assignee | ||
Comment 8•5 years ago
|
||
Depends on D36102
Assignee | ||
Comment 9•5 years ago
|
||
Depends on D36103
Assignee | ||
Comment 10•5 years ago
|
||
I'll assign to myself for now (at least to get most of the above landed), but please reach out if anyone wants to help push on this.. we can coordinate.
Assignee | ||
Comment 11•5 years ago
|
||
I've run into some walls.. since mach_commands.py depend on MachCommandBase which uses a bunch of other stuff in mozbuild, I'm now hitting bytes vs str errors in init.configure. This is quickly getting into territory I'm not comfortable with and might need a build peer to either fix or figure out how we can not depend on it.
I'll still try to get the attached patches landed though (except the last two).
Assignee | ||
Updated•5 years ago
|
Comment 12•5 years ago
|
||
Comment 13•5 years ago
|
||
bugherder |
Comment 14•5 years ago
|
||
Assignee | ||
Comment 15•5 years ago
|
||
Comment 16•5 years ago
|
||
Comment on attachment 9075823 [details]
Bug 1473498 - Vendor backports.shutil_which
Revision D36838 was moved to bug 1563797. Setting attachment 9075823 [details] to obsolete.
Assignee | ||
Comment 17•5 years ago
|
||
Assignee | ||
Comment 18•5 years ago
|
||
Depends on D37762
Assignee | ||
Comment 19•5 years ago
|
||
Depends on D37763
Updated•5 years ago
|
Assignee | ||
Comment 20•5 years ago
|
||
Depends on D36104
Comment 21•5 years ago
|
||
Updated•5 years ago
|
Updated•5 years ago
|
Assignee | ||
Comment 22•5 years ago
|
||
On Windows in Python 2, the subprocess module requires the use of bytes with
the 'env' argument. For that reason, we would sometimes use byte strings with
'os.environ' like so:
os.environ[b"FOO"] = b"bar"
However, this is a failure with Python 3 as 'os.environ' must only be used with
the text type. This patch removes the usage of byte literals in 'os.environ'
and instead encodes 'env' to byte strings at the subprocess call site.
Comment 23•5 years ago
|
||
bugherder |
Comment 24•5 years ago
|
||
Comment 25•5 years ago
|
||
bugherder |
Assignee | ||
Comment 26•5 years ago
|
||
Updated•5 years ago
|
Comment 27•5 years ago
|
||
Comment 28•5 years ago
|
||
bugherder |
Comment 29•5 years ago
|
||
This patch makes BuildEnvironmentNotFoundException a subclass of AttributeError as well, because hasattr in
python3 no longer catches all tracebacks but only AttributeError, and we use both hasattr and
BuildEnvironmentNotFoundException to guard against a handful of buildconfig variables in a few places
where it is OK to not have a buildenvironment.
We also use universal_newlines in real_host in init.configure (since I found
that fix while working on the AttributeError one) so that we get the right string type back from the process call
Lastly this patch also uses BytesIO for calling into a ReducedConfigureSandbox as its stdout and stderr pipes,
This ensures that related code handling the sandbox doesn't complain about getbuffer() missing in StringIO in py3.
Assignee | ||
Comment 30•5 years ago
|
||
Comment 31•5 years ago
|
||
Comment 32•5 years ago
|
||
bugherder |
Updated•5 years ago
|
Updated•5 years ago
|
Assignee | ||
Comment 34•5 years ago
|
||
Ok, I've confused myself a bunch of times and have too many revisions going.. so commenting here to clarify the current state of affairs.
First, fixing this comment in D40504 causes errors in configure (see comment below that one). So there are three options here:
- Leave that
encode
at the end there despite not encodingconfig.status
, i.e ignore this issue (sounds like this might be a no-go.. but figured I'd list it). - Fix the underlying build problems. This is probably the most correct approach, but I don't feel qualified to tackle it (nor do I have that much time). This will likely delay the migration by weeks or even months. Maybe a build peer would be able to solve these more quickly than I think.
- Keep enforcing
bytes
inconfig.status
and fix the encoding issues on the other side (e.g inconfigenvironment.py
and whatever mach commands use it).
If we decide to do option #3, then we have two further options:
3A. Assume anytime we interface with a value from config.status
, it's going to be bytes and update our code accordingly. D36912 started going down this route, but I started hitting issues in mach_commands.py
files themselves. I'm not sure how deep the error stack goes, maybe it won't be too bad. Long term I think this approach will end up being annoying, but it might also be the cleanest for now.
3B. Recursively decode everything that comes out of config.status
in configenvironment.py
right away. This is basically what my initial patch did way back when.
Mike, which path would you like to take here?
Assignee | ||
Comment 35•5 years ago
|
||
Looks like 3A
also breaks configure:
0:03.57 File "/home/ahal/dev/mozilla-central/python/mozbuild/mozbuild/frontend/reader.py", line 1057, in read_mozbuild
0:03.57 raise bre
0:03.57 mozbuild.frontend.reader.BuildReaderError:
0:03.57 ==============================
0:03.57 FATAL ERROR PROCESSING MOZBUILD FILE
0:03.57 ==============================
0:03.57
0:03.57 The error occurred while processing the following file:
0:03.57
0:03.57 /home/ahal/dev/mozilla-central/build/templates.mozbuild
0:03.57
0:03.57 This file was included as part of processing:
0:03.57
0:03.57 /home/ahal/dev/mozilla-central/ipc/app/moz.build
0:03.57
0:03.57 The error was triggered on line 20 of this file:
0:03.57
0:03.57 PROGRAM = name
0:03.57
0:03.57 The underlying problem is an attempt to write an illegal value to a special variable.
0:03.57
0:03.57 The variable whose value was rejected is:
0:03.57
0:03.58 PROGRAM
0:03.58 The value being written to it was of the following type:
0:03.58
0:03.58 str
0:03.58
0:03.58 This variable expects the following type(s):
0:03.58
0:03.58 unicode
0:03.58
0:03.58 Change the file to write a value of the appropriate type and try again.
0:03.58
0:03.63 *** Fix above errors and then restart with\
0:03.63 "./mach build"
0:03.63 gmake: *** [client.mk:115: configure] Error 1
Comment 36•5 years ago
|
||
(In reply to Andrew Halberstadt [:ahal] from comment #34)
- Leave that
encode
at the end there despite not encodingconfig.status
, i.e ignore this issue (sounds like this might be a no-go.. but figured I'd list it).
config.status does a subset of what configure does, avoiding to rerun all tests when you only need to adapt to e.g. changes to moz.build files. That means config.status and configure are meant to do the exact same thing. So that's not a option.
- Fix the underlying build problems. This is probably the most correct approach, but I don't feel qualified to tackle it (nor do I have that much time). This will likely delay the migration by weeks or even months. Maybe a build peer would be able to solve these more quickly than I think.
Not sure what you mean by "underlying build problems". If you mean the fact that some things are bytes before ending up in config.status, that sounds sensible.
- Keep enforcing
bytes
inconfig.status
and fix the encoding issues on the other side (e.g inconfigenvironment.py
and whatever mach commands use it).
That sounds awful. As in, this implies multiple places to get things subtly wrong.
Assignee | ||
Comment 37•5 years ago
|
||
(In reply to Mike Hommey [:glandium] from comment #36)
Not sure what you mean by "underlying build problems". If you mean the fact that some things are bytes before ending up in config.status, that sounds sensible.
Yes, this is the ideal solution. By underlying problems I mostly mean this error:
https://phabricator.services.mozilla.com/D40504#1246752
I tried to debug that but have no idea what's going on. I'm pretty sure when that gets fixed we'll hit more errors, see this comment:
https://searchfox.org/mozilla-central/source/configure.py#126
That sounds awful. As in, this implies multiple places to get things subtly wrong.
Actually, this might not be quite as bad as I initially thought.. might have something that works well enough for non-build related commands to get unblocked. Will post back if it ends up being successful.
Assignee | ||
Comment 38•5 years ago
|
||
Without the output, this exception wasn't being very helpful.
Updated•5 years ago
|
Updated•5 years ago
|
Assignee | ||
Comment 39•5 years ago
|
||
Depends on D36843
Updated•5 years ago
|
Updated•5 years ago
|
Assignee | ||
Comment 40•5 years ago
|
||
Use of 'BaseException.message` was deprecated in Python 2.6 (and removed in
Python 3). We should rely on the exception's 'str' instead.
We also need to ensure the mozconfig subprocess' output is text when formatting
it into the message with Py3.
Updated•5 years ago
|
Assignee | ||
Comment 41•5 years ago
|
||
This also fixes an import error in Python 3 (builtins.unicode).
Updated•5 years ago
|
Assignee | ||
Comment 42•5 years ago
|
||
Updated•5 years ago
|
Comment 43•5 years ago
|
||
Comment 44•5 years ago
|
||
bugherder |
Assignee | ||
Updated•5 years ago
|
Description
•