blob: de47c3da24556f10746394e8e1d1ae13836b6b3a [file] [log] [blame] [view]
Dirk Prankecc232342021-05-13 22:20:121# Migrating Chromium to Python3
2
3This page describes the current status and how to migrate code.
4
5[crbug.com/941669](https://crbug.com/941669) tracks the overall migration.
6
7*It is now safe to write new code using Python3 as long as it isn't called
8from other Python2 files. See the
9[Python style guide](../styleguide/python/python.md) for the latest on this.*
10
11## Status
12
Takuto Ikuta189a4b742021-07-20 02:42:3013As of the time of writing (2021-07-19), we're in the following state:
Dirk Prankecc232342021-05-13 22:20:1214
15* depot_tools is fully Python3-compatible.
16* [gclient hooks](#gclient_hooks) are being migrated to use Python3
17 ([crbug.com/1208028](https://crbug.com/1208028)).
18* GN is fully Python3-compatible, meaning that all the scripts invoked
19 through exec_script() are using Python3.
Takuto Ikuta189a4b742021-07-20 02:42:3020* The [build](#gn_ninja-actions) (scripts invoked by Ninja) uses Python3.
Dirk Prankecc232342021-05-13 22:20:1221* We are updating the various test harnesses and frameworks to use
22 Python3, but most still use Python2. It is possible to use
23 Python3 for tests if you're ready to do so.
24* [PRESUBMIT checks](#presubmit_checks) are being migrated to use Python3
25 ([crbug.com/1207012](https://crbug.com/1207012)).
26* Python3-compatible pylint checks are available but not yet fully
27 integrated into the presubmit checks
28 ([crbug.com/1157676](https://crbug.com/1157676)).
29
30
31## Migrating Python code from 2 to 3
32
33This document will not attempt to replicate the general information in
34the [Python.org Porting HOWTO](https://docs.python.org/3/howto/pyporting.html)
35or the many, many other guides on the Internet.
36
37However, here are a few notes that may be helpful in a Chromium context:
38
39* Most of our Python code is pretty straightforward and moves easily
40 from Python2 to Python3, so don't stress out about this!
41
42* When migrating code, please make the Right Changes, rather than the
43 minimum needed to get things to work. For example, make sure your code
44 is clear about whether something should be a byte string or a unicode
45 string, rather than trying to handle both "to be compatible".
46 (If you really do need the code to handle both, though, that can be okay.)
47
48* Do not assume you can use [vpython] regardless of context! vpython has
49 performance issues in some situations and so we don't want to use it yet for
50 things invoked by gclient, PRESUBMITs, or Ninja. However, all tests are run
51 under vpython and so you can assume it there.
52
53* Some people find the `2to3` tool to be useful to partially or
54 completely automate the migration of existing files, and the
55 `six` module to shim compatibility across the two. The `six` module
56 is available in vpython and in `//third_party/six/src/six.py`.
57
58* shebang lines mostly don't matter. A "shebang line" is the line at the
59 beginning of many unix scripts, like `#!/usr/bin/env python`. They are
60 not that important for us because most of our python invocations come
61 from tools like Ninja or Swarming and invoke python directly. So, while
62 you should keep them accurate where they are useful, we can't rely
63 on them to tell which code has been migrated and which hasn't.
64
65* The major gotchas for us tend to have to do with processing output
66 from a subprocess (e.g., `subprocess.check_output()`). By default
67 output is returned as a binary string, so get in the habit of calling
68 `.check_output().decode('utf-8')` instead. This is compatible across
69 2 and 3. 'utf-8' is the default in Python3 (ASCII was the default in
70 Python2), but being explicitly is probably a good idea until we have
71 migrated everything.
72
73* Be aware that `filter` and `map` return generators in Python3, which
74 are one-shot objects. If you reference them inside another loop, e.g.,
75
76 foo = [ ... ]
77 bar = filter(some_function, [ ...])
78 for x in foo:
79 for y in bar:
80 do_something(x, y)
81
82 this won't work right, because on the second and subsequent iterations,
83 bar will be an empty list.
84
85 Best practice is to use a list comprehension instead of `map` or `filter`,
86 but you can also explicitly cast the results of map or filter to a list
87 if the list comprehension is too awkward.
88
89* Some modules (like `urllib2`) were renamed and/or moved around in Python 3.
90 A Google search will usually quickly tell you the new location.
91
92* Watch out for places where you reference `basestring` or `unicode` directly.
93 `six` provides some compatibility types to help here.
94
95## Testing your migrations
96
97Generally speaking, test your changes the same way we do everything else:
98make a change locally, and rely on the CQ and CI bots to catch problems.
99
100However, here are some specific guidelines for the different contexts
101where we use Python:
102
103### gclient hooks
104
105To switch a gclient hook from Python2 to Python3, simply change `python`
106to `python3` in the DEPS file, and make sure things still run :).
107
108### GN/Ninja actions
109
Takuto Ikuta189a4b742021-07-20 02:42:30110All targets in the build use Python3 now, and anything declared via an
Dirk Prankecc232342021-05-13 22:20:12111`action()` rule in GN will use Python3.
112
Dirk Prankecc232342021-05-13 22:20:12113### Tests
114
115Test targets that run by invoking python scripts (like telemetry_unittests
116or blink_web_tests) should eventually migrate to using the [script_test]
117GN templates. Once you do that, they will use Python3 by default. However,
118some tests may specify `run_under_python2 = true` as a template variable
119to use Python2, so when you're ready to test Python3, just delete that line.
120
121Some tests still need to be migrated to `script_test()`
122([crbug.com/1208648](https://crbug.com/1208648)). The process for
123doing that is not yet well documented, so ask on python@chromium.org (or
124ask dpranke@ directly).
125
126There is no general mechanism for migrating tests that are C++ executables
127that launch python via subprocesses, so you're on your own for dealing with
128that.
129
130### Presubmit checks
131
132Presubmit checks are run using Python 2 by default. To run them using
133Python3, add the line `USE_PYTHON3 = True` to the PRESUBMIT.py file in
134question (effectively creating a global variable).
135
Dirk Prankecc232342021-05-13 22:20:12136[script_test]: https://source.chromium.org/?q=script_test%20file:testing%2Ftest.gni&ss=chromium
137[vpython]: https://chromium.googlesource.com/infra/infra/+/refs/heads/main/doc/users/vpython.md