summaryrefslogtreecommitdiffstats
path: root/Doc/howto/pyporting.rst
diff options
context:
space:
mode:
authorBrett Cannon <brett@python.org>2013-03-09 19:22:35 (GMT)
committerBrett Cannon <brett@python.org>2013-03-09 19:22:35 (GMT)
commitb7e6b895546ac7ae3217480b2161ed0ecbee408a (patch)
treef5f73f51f6b922a1485b1d48e581afe01ee8bf01 /Doc/howto/pyporting.rst
parentc2d90fb3ec648cb84db9ed037c734e574e3655ae (diff)
downloadcpython-b7e6b895546ac7ae3217480b2161ed0ecbee408a.zip
cpython-b7e6b895546ac7ae3217480b2161ed0ecbee408a.tar.gz
cpython-b7e6b895546ac7ae3217480b2161ed0ecbee408a.tar.bz2
Touch up the Python 2 to 3 porting guide
Diffstat (limited to 'Doc/howto/pyporting.rst')
-rw-r--r--Doc/howto/pyporting.rst61
1 files changed, 46 insertions, 15 deletions
diff --git a/Doc/howto/pyporting.rst b/Doc/howto/pyporting.rst
index a2e4173..9015372 100644
--- a/Doc/howto/pyporting.rst
+++ b/Doc/howto/pyporting.rst
@@ -21,21 +21,21 @@ Porting Python 2 Code to Python 3
Choosing a Strategy
===================
-When a project makes the decision that it's time to support both Python 2 & 3,
+When a project chooses to support both Python 2 & 3,
a decision needs to be made as to how to go about accomplishing that goal.
The chosen strategy will depend on how large the project's existing
-codebase is and how much divergence you want from your Python 2 codebase from
-your Python 3 one (e.g., starting a new version with Python 3).
-
-If your project is brand-new or does not have a large codebase, then you may
-want to consider writing/porting :ref:`all of your code for Python 3
-and use 3to2 <use_3to2>` to port your code for Python 2.
+codebase is and how much divergence you want from your current Python 2 codebase
+(e.g., changing your code to work simultaneously with Python 2 and 3).
If you would prefer to maintain a codebase which is semantically **and**
syntactically compatible with Python 2 & 3 simultaneously, you can write
:ref:`use_same_source`. While this tends to lead to somewhat non-idiomatic
code, it does mean you keep a rapid development process for you, the developer.
+If your project is brand-new or does not have a large codebase, then you may
+want to consider writing/porting :ref:`all of your code for Python 3
+and use 3to2 <use_3to2>` to port your code for Python 2.
+
Finally, you do have the option of :ref:`using 2to3 <use_2to3>` to translate
Python 2 code into Python 3 code (with some manual help). This can take the
form of branching your code and using 2to3 to start a Python 3 branch. You can
@@ -55,10 +55,10 @@ Regardless of what strategy you pick, there are a few things you should
consider.
One is make sure you have a robust test suite. You need to make sure everything
-continues to work, just like when you support a new minor version of Python.
-This means making sure your test suite is thorough and is ported properly
-between Python 2 & 3. You will also most likely want to use something like tox_
-to automate testing between both a Python 2 and Python 3 VM.
+continues to work, just like when you support a new minor/feature release of
+Python. This means making sure your test suite is thorough and is ported
+properly between Python 2 & 3. You will also most likely want to use something
+like tox_ to automate testing between both a Python 2 and Python 3 interpreter.
Two, once your project has Python 3 support, make sure to add the proper
classifier on the Cheeseshop_ (PyPI_). To have your project listed as Python 3
@@ -98,7 +98,8 @@ guard.
Four, read all the approaches. Just because some bit of advice applies to one
approach more than another doesn't mean that some advice doesn't apply to other
-strategies.
+strategies. This is especially true of whether you decide to use 2to3 or be
+source-compatible; tips for one approach almost always apply to the other.
Five, drop support for older Python versions if possible. `Python 2.5`_
introduced a lot of useful syntax and libraries which have become idiomatic
@@ -108,6 +109,14 @@ compatibility much easier if you are going from Python 2 to 3.
of Python which you believe can be your minimum support version
and work from there.
+Six, target the newest version of Python 3 that you can. Beyond just the usual
+bugfixes, compatibility has continued to improve between Python 2 and 3 as time
+has passed. This is especially true for Python 3.3 where the ``u`` prefix for
+strings is allowed, making source-compatible Python code easier.
+
+Seven, make sure to look at the `Other Resources`_ for tips from other people
+which may help you out.
+
.. _tox: http://codespeak.net/tox/
.. _Cheeseshop:
@@ -169,8 +178,8 @@ experimental translation just to see how long it takes to evaluate whether you
prefer this approach compared to using :ref:`use_same_source` or simply keeping
a separate Python 3 codebase.
-Below are the typical steps taken by a project which uses a 2to3-based approach
-to supporting Python 2 & 3.
+Below are the typical steps taken by a project which tries to support
+Python 2 & 3 while keeping the code directly executable by Python 2.
Support Python 2.7
@@ -215,7 +224,9 @@ string with a ``u`` prefix to get the same effect. But regardless of whether
you use this future statement or not, you **must** make sure you know exactly
which Python 2 strings you want to be bytes, and which are to be strings. This
means you should, **at minimum** mark all strings that are meant to be text
-strings with a ``u`` prefix if you do not use this future statement.
+strings with a ``u`` prefix if you do not use this future statement. Python 3.3
+allows strings to continue to have the ``u`` prefix (it's a no-op in that case)
+to make it easier for code to be source-compatible between Python 2 & 3.
Bytes literals
@@ -226,6 +237,15 @@ are meant to contain bytes with a ``b`` prefix help to very clearly delineate
what is and is not a Python 3 string. When you run 2to3 on code, all Python 2
strings become Python 3 strings **unless** they are prefixed with ``b``.
+This point cannot be stressed enough: make sure you know what all of your string
+literals in Python 2 are meant to become in Python 3. Any string literal that
+should be treated as bytes should have the ``b`` prefix. Any string literal
+that should be Unicode/text in Python 2 should either have the ``u`` literal
+(supported, but ignored, in Python 3.3 and later) or you should have
+``from __future__ import unicode_literals`` at the top of the file. But the key
+point is you should know how Python 3 will treat everyone one of your string
+literals and you should mark them as appropriate.
+
There are some differences between byte literals in Python 2 and those in
Python 3 thanks to the bytes type just being an alias to ``str`` in Python 2.
Probably the biggest "gotcha" is that indexing results in different values. In
@@ -264,6 +284,16 @@ other words, unless you are only supporting Python 2.7 or a version earlier
than Python 2.5, use the __future__ statement.
+Mark all Unicode strings with a ``u`` prefix
+'''''''''''''''''''''''''''''''''''''''''''''
+
+While Python 2.6 has a ``__future__`` statement to automatically cause Python 2
+to treat all string literals as Unicode, Python 2.5 does not have that shortcut.
+This means you should go through and mark all string literals with a ``u``
+prefix to turn them explicitly into Unicode strings where appropriate. That
+leaves all unmarked string literals to be considered byte literals in Python 3.
+
+
Handle Common "Gotchas"
-----------------------
@@ -708,6 +738,7 @@ thus helping provide information for this document):
* http://lucumr.pocoo.org/2011/1/22/forwards-compatible-python/
* http://lucumr.pocoo.org/2010/2/11/porting-to-python-3-a-guide/
* http://wiki.python.org/moin/PortingPythonToPy3k
+* https://wiki.ubuntu.com/Python/3
If you feel there is something missing from this document that should be added,
please email the python-porting_ mailing list.