mirror of https://github.com/python/cpython
use 3-space indents.
This commit is contained in:
parent
8045d97819
commit
4b0c24a3ae
|
@ -8,14 +8,14 @@ Porting Python 2 Code to Python 3
|
||||||
|
|
||||||
.. topic:: Abstract
|
.. topic:: Abstract
|
||||||
|
|
||||||
With Python 3 being the future of Python while Python 2 is still in active
|
With Python 3 being the future of Python while Python 2 is still in active
|
||||||
use, it is good to have your project available for both major releases of
|
use, it is good to have your project available for both major releases of
|
||||||
Python. This guide is meant to help you choose which strategy works best
|
Python. This guide is meant to help you choose which strategy works best
|
||||||
for your project to support both Python 2 & 3 along with how to execute
|
for your project to support both Python 2 & 3 along with how to execute
|
||||||
that strategy.
|
that strategy.
|
||||||
|
|
||||||
If you are looking to port an extension module instead of pure Python code,
|
If you are looking to port an extension module instead of pure Python code,
|
||||||
please see http://docs.python.org/py3k/howto/cporting.html .
|
please see http://docs.python.org/py3k/howto/cporting.html .
|
||||||
|
|
||||||
|
|
||||||
Choosing a Strategy
|
Choosing a Strategy
|
||||||
|
@ -70,20 +70,20 @@ compatible it must have the
|
||||||
(from
|
(from
|
||||||
http://techspot.zzzeek.org/2011/01/24/zzzeek-s-guide-to-python-3-porting/)::
|
http://techspot.zzzeek.org/2011/01/24/zzzeek-s-guide-to-python-3-porting/)::
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='Your Library',
|
name='Your Library',
|
||||||
version='1.0',
|
version='1.0',
|
||||||
classifiers=[
|
classifiers=[
|
||||||
# make sure to use :: Python *and* :: Python :: 3 so
|
# make sure to use :: Python *and* :: Python :: 3 so
|
||||||
# that pypi can list the package on the python 3 page
|
# that pypi can list the package on the python 3 page
|
||||||
'Programming Language :: Python',
|
'Programming Language :: Python',
|
||||||
'Programming Language :: Python :: 3'
|
'Programming Language :: Python :: 3'
|
||||||
],
|
],
|
||||||
packages=['yourlibrary'],
|
packages=['yourlibrary'],
|
||||||
# make sure to add custom_fixers to the MANIFEST.in
|
# make sure to add custom_fixers to the MANIFEST.in
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
# ...
|
# ...
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
Doing so will cause your project to show up in the
|
Doing so will cause your project to show up in the
|
||||||
|
@ -340,25 +340,25 @@ The other option is to use a mixin class. This allows you to only define a
|
||||||
``__str__()`` for you (code from
|
``__str__()`` for you (code from
|
||||||
http://lucumr.pocoo.org/2011/1/22/forwards-compatible-python/)::
|
http://lucumr.pocoo.org/2011/1/22/forwards-compatible-python/)::
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
class UnicodeMixin(object):
|
class UnicodeMixin(object):
|
||||||
|
|
||||||
"""Mixin class to handle defining the proper __str__/__unicode__
|
"""Mixin class to handle defining the proper __str__/__unicode__
|
||||||
methods in Python 2 or 3."""
|
methods in Python 2 or 3."""
|
||||||
|
|
||||||
if sys.version_info[0] >= 3: # Python 3
|
if sys.version_info[0] >= 3: # Python 3
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.__unicode__()
|
return self.__unicode__()
|
||||||
else: # Python 2
|
else: # Python 2
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.__unicode__().encode('utf8')
|
return self.__unicode__().encode('utf8')
|
||||||
|
|
||||||
|
|
||||||
class Spam(UnicodeMixin):
|
class Spam(UnicodeMixin):
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u'spam-spam-bacon-spam' # 2to3 will remove the 'u' prefix
|
return u'spam-spam-bacon-spam' # 2to3 will remove the 'u' prefix
|
||||||
|
|
||||||
|
|
||||||
Specify when opening a file as binary
|
Specify when opening a file as binary
|
||||||
|
@ -380,11 +380,11 @@ Don't Index on Exceptions
|
||||||
'''''''''''''''''''''''''
|
'''''''''''''''''''''''''
|
||||||
In Python 2, the following worked::
|
In Python 2, the following worked::
|
||||||
|
|
||||||
>>> exc = Exception(1, 2, 3)
|
>>> exc = Exception(1, 2, 3)
|
||||||
>>> exc.args[1]
|
>>> exc.args[1]
|
||||||
2
|
2
|
||||||
>>> exc[1] # Python 2 only!
|
>>> exc[1] # Python 2 only!
|
||||||
2
|
2
|
||||||
|
|
||||||
But in Python 3, indexing directly off of an exception is an error. You need to
|
But in Python 3, indexing directly off of an exception is an error. You need to
|
||||||
make sure to only index on :attr:`BaseException.args` attribute which is a
|
make sure to only index on :attr:`BaseException.args` attribute which is a
|
||||||
|
@ -426,13 +426,13 @@ Manually
|
||||||
To manually convert source code using 2to3_, you use the ``2to3`` script that
|
To manually convert source code using 2to3_, you use the ``2to3`` script that
|
||||||
is installed with Python 2.6 and later.::
|
is installed with Python 2.6 and later.::
|
||||||
|
|
||||||
2to3 <directory or file to convert>
|
2to3 <directory or file to convert>
|
||||||
|
|
||||||
This will cause 2to3 to write out a diff with all of the fixers applied for the
|
This will cause 2to3 to write out a diff with all of the fixers applied for the
|
||||||
converted source code. If you would like 2to3 to go ahead and apply the changes
|
converted source code. If you would like 2to3 to go ahead and apply the changes
|
||||||
you can pass it the ``-w`` flag::
|
you can pass it the ``-w`` flag::
|
||||||
|
|
||||||
2to3 -w <stuff to convert>
|
2to3 -w <stuff to convert>
|
||||||
|
|
||||||
There are other flags available to control exactly which fixers are applied,
|
There are other flags available to control exactly which fixers are applied,
|
||||||
etc.
|
etc.
|
||||||
|
@ -444,20 +444,20 @@ When a user installs your project for Python 3, you can have either
|
||||||
:mod:`distutils` or Distribute_ run 2to3_ on your behalf.
|
:mod:`distutils` or Distribute_ run 2to3_ on your behalf.
|
||||||
For distutils, use the following idiom::
|
For distutils, use the following idiom::
|
||||||
|
|
||||||
try: # Python 3
|
try: # Python 3
|
||||||
from distutils.command.build_py import build_py_2to3 as build_py
|
from distutils.command.build_py import build_py_2to3 as build_py
|
||||||
except ImportError: # Python 2
|
except ImportError: # Python 2
|
||||||
from distutils.command.build_py import build_py
|
from distutils.command.build_py import build_py
|
||||||
|
|
||||||
setup(cmdclass = {'build_py':build_py},
|
setup(cmdclass = {'build_py':build_py},
|
||||||
# ...
|
# ...
|
||||||
)
|
)
|
||||||
|
|
||||||
For Distribute::
|
For Distribute::
|
||||||
|
|
||||||
setup(use_2to3=True,
|
setup(use_2to3=True,
|
||||||
# ...
|
# ...
|
||||||
)
|
)
|
||||||
|
|
||||||
This will allow you to not have to distribute a separate Python 3 version of
|
This will allow you to not have to distribute a separate Python 3 version of
|
||||||
your project. It does require, though, that when you perform development that
|
your project. It does require, though, that when you perform development that
|
||||||
|
@ -526,30 +526,30 @@ One change between Python 2 and 3 that will require changing how you code is
|
||||||
accessing the currently raised exception. In Python 2 the syntax to access the
|
accessing the currently raised exception. In Python 2 the syntax to access the
|
||||||
current exception is::
|
current exception is::
|
||||||
|
|
||||||
try:
|
try:
|
||||||
raise Exception()
|
raise Exception()
|
||||||
except Exception, exc:
|
except Exception, exc:
|
||||||
# Current exception is 'exc'
|
# Current exception is 'exc'
|
||||||
pass
|
pass
|
||||||
|
|
||||||
This syntax changed in Python 3 to::
|
This syntax changed in Python 3 to::
|
||||||
|
|
||||||
try:
|
try:
|
||||||
raise Exception()
|
raise Exception()
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
# Current exception is 'exc'
|
# Current exception is 'exc'
|
||||||
pass
|
pass
|
||||||
|
|
||||||
Because of this syntax change you must change to capturing the current
|
Because of this syntax change you must change to capturing the current
|
||||||
exception to::
|
exception to::
|
||||||
|
|
||||||
try:
|
try:
|
||||||
raise Exception()
|
raise Exception()
|
||||||
except Exception:
|
except Exception:
|
||||||
import sys
|
import sys
|
||||||
exc = sys.exc_info()[1]
|
exc = sys.exc_info()[1]
|
||||||
# Current exception is 'exc'
|
# Current exception is 'exc'
|
||||||
pass
|
pass
|
||||||
|
|
||||||
You can get more information about the raised exception from
|
You can get more information about the raised exception from
|
||||||
:func:`sys.exc_info` than simply the current exception instance, but you most
|
:func:`sys.exc_info` than simply the current exception instance, but you most
|
||||||
|
|
Loading…
Reference in New Issue