to be 100%, but it’s good to have enough to catch important regressions • Run the tests in both Python 2 & Python 3 ◦ tip: ignore the ones aren’t passing in Python 3 yet, try to keep passing the ones that already do • Remember the tests may be incorrect in Python 3 and needing to change too
2.6 or previous, first migrate to 2.7+ • Ignore 3.x lesser than 3.3 ◦ didn’t had good enough support (syntax & stdlib) to write code compatible with 2 ◦ vendors (distros) generally support 3.3+ • Tip for installing several distinct versions of Python: ◦ http://saghul.github.io/pythonz (CPython, PyPy, etc)
3 in the same codebase, when coming from Python 2 • Everything in one file, easy to copy and paste inside the project if needed • Helper functions, constants, shims, aliases • Vocabulary for porting • Learn it, love it! <3
might be necessary to break ◦ unicode vs bytes force you to fix some issues ◦ when it’s really a bug, it’s acceptable to break • Be ready to do some deprecation cycles ◦ emit warnings for obsolete code, telling how to fix ◦ tip: DeprecationWarning is ignored by default, create a new class MyDeprecationWarning(Warning)
to decide if: • should it be only text? (unicode in PY2, str in PY3) • should it be only binary? (str/bytes in PY2, bytes in PY3) • should it be native string? (str in PY2 & PY3) It’s simpler when you can choose either text or binary. It’s important a good coverage, and checking correctness of tests too.
the bits with less dependencies • Example: ◦ pick a module under utils ◦ review the code and the tests ◦ fix the tests, add some more ◦ port • It’s nice to document some decisions on bytes vs unicode ◦ Scrapy: started with utils, then Request/Response