[Imported from Trac: page Python3, version 1]
parent
3fcfc5d636
commit
8748628139
56
Python3.md
Normal file
56
Python3.md
Normal file
|
@ -0,0 +1,56 @@
|
|||
# Porting to Python 3
|
||||
|
||||
This is still a proposal at this stage.
|
||||
|
||||
## Motivation
|
||||
|
||||
* Make code behave the same on Python 2 and Python 3, insofar as one can, so e.g. `map()` is the same on Python 2 and Python 3 (i.e. lazy).
|
||||
* Reduce errors by relying on Python 2 behavior and tests as well as manual review.
|
||||
* Try to reduce grunt work.
|
||||
|
||||
## How to choose a module to port
|
||||
|
||||
TBD, something involving core abstractions first, then dependency graph topological traversal.
|
||||
|
||||
Assume for now we've picked a module.
|
||||
|
||||
## The porting process, big picture
|
||||
|
||||
For a module M, there is also a corresponding module T, the unittests for M.
|
||||
If the tests for M are embedded into a module that tests multiple modules, step one is to split off the tests so there's T that only tests M.
|
||||
|
||||
Then:
|
||||
|
||||
1. Update T to run on both 2+3 (see below for what that looks like).
|
||||
2. Run T's tests on Python 2. They should still pass! If they don’t, something broke.
|
||||
3. Port the code module M.
|
||||
4. Now run T's tests on Python 3.
|
||||
5. Fix any problems caught by the tests.
|
||||
6. Add both M and T to `allmydata/util/_python3.py`.
|
||||
7. Submit for code review.
|
||||
|
||||
|
||||
### Porting a specific Python file
|
||||
|
||||
**First**, add explicit byte or unicode annotations for strings where needed.
|
||||
|
||||
**Second**, run `futurize --write --both-stages --all-imports path/to/file.py`.
|
||||
|
||||
**Third**, replace the `from builtins import *` variant, if any, with:
|
||||
|
||||
```#!python
|
||||
from future.utils import PY2
|
||||
if PY2:
|
||||
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
|
||||
```
|
||||
|
||||
This adds builtins that match Python 3's semantics. The `#noqa: F401` keeps flake8/pyflakes from complaining about unused imports. We do unused imports so that people changing code later don't have to manually check if `map()` is old style or new style.
|
||||
|
||||
**Fourth**, manually review the code. Futureize is nice, but it very definitely doesn't catch everything, or it makes wrong decisions.
|
||||
|
||||
In particular:
|
||||
|
||||
* `map()`, `filter()`, etc. are now lazy.
|
||||
* `dict.keys()` and friends now return a view of the underlying data, rather than a list with a copy.
|
||||
|
||||
**Fifth**, add a note to the module docstring saying it was ported to Python 3.
|
Loading…
Reference in a new issue