Size: 4186
Comment: copy edit
|
Size: 4787
Comment: Consistent usage of heading and admonition
|
Deletions are marked like this. | Additions are marked like this. |
Line 8: | Line 8: |
= Write Tests = | = Unit Tests = |
Line 11: | Line 11: |
'''Write unit tests for all new or refactored code''' |
|
Line 59: | Line 61: |
= Let all exception classes inherit from Exception = | = Exception class inheritance = |
Line 71: | Line 73: |
= Use parentheses for Exception argument = | = Arguments for raise statement = |
Line 73: | Line 75: |
The syntax | The {{{raise}}} statement currently accepts different syntaxes. This will be consolidated so that only one argument is allowed for {{{raise}}}: the exception object, created like any other object. Other syntaxes will be deprecated. '''Write the {{{raise}}} statement with the exception object as the only argument''' Don't write: |
Line 77: | Line 83: |
will be deprecated. Use | Instead, write: |
Line 81: | Line 88: |
instead. | |
Line 83: | Line 89: |
= Don't compare incompatible objects = | = Comparison of incompatible types = |
Line 87: | Line 93: |
= Don't use <> = | '''Don't compare objects of different types with undefined comparison behaviour''' = Deprecation of little-used alternative operators = |
Line 91: | Line 99: |
= Don't use `` (backticks) = | '''Use only {{{!=}}} for inequality comparison''' |
Line 93: | Line 101: |
The `backticks` for repr() will not exist in Python 3.0. Almost all code currently uses repr(foo) for this purpose, and many don't even know of `foo`. It is also harder to read. | The syntax {{{`foo`}}} for repr() will not exist in Python 3.0. Almost all code currently uses {{{repr(foo)}}} for this purpose, and the backtick syntax is little-known and less readable. |
Line 95: | Line 103: |
= Don't assign to names that will become keywords = | '''Use only {{{repr(foo)}}} for the representation of an object''' = New keywords = |
Line 98: | Line 108: |
'''Don't assign to names that will become keywords''' |
Python is a mature language, but it hasn't stopped evolving, and there are some issues to consider when coding Python, if you want your code to work with the latest version of Python in five five years from now... See http://www.python.org/peps/pep-3000.html for more information.
Unit Tests
Automated testing is generally better than debugging, and is your safety-net for any kind of refactoring, not only when migrating to a newer Python. Use PyUnit (unittest), DocTest or any alternative (see UnitTests) to help you.
Write unit tests for all new or refactored code
True Division
Since the beginning, Python has yielded an integer result when two integers are divided, e.g. 3/2 => 1. While correct if we assume that dividing integers means integer division (the remainder is accessible through the modulo operator %) it's not always obvious to beginners. This behaviour will change in a future Python version, so that a/b will yield a float as a result even if both a and b are integers, and a new floor division operator // will perform integer division. See See http://www.python.org/peps/pep-0238.html
Use true and floor division in new code
from __future__ import division # Enable the new behaviour f = 3/2 # 1.5 i = 3//2 # 1
New style classes
Currently, there are two kinds of classes in Python. The 'classic' or old style classes, and the new style classes. Old style classes will go away in some future version, and while most code will still work when the default switches from old style to new style, there are some differences in semantics, and the new style classes have some extra features. See http://www.python.org/doc/newstyle.html
Use new style classes in new code
Don't write
class X: pass
Write
class X(object): pass
Exception class inheritance
Starting from Python 3.0, all exceptions must be derived from BaseException, which will be the base class for KeyboardInterrupt, SystemExit and Exception from Python 2.5. See http://www.python.org/peps/pep-0352.html
When defining new exception classes, always inherit (directly or indirectly) from Exception
class MyException(Exception): pass
Arguments for raise statement
The raise statement currently accepts different syntaxes. This will be consolidated so that only one argument is allowed for raise: the exception object, created like any other object. Other syntaxes will be deprecated.
Write the raise statement with the exception object as the only argument
Don't write:
raise MyException "A nasty error"
Instead, write:
raise MyException("A nasty error")
Comparison of incompatible types
In the future, x < y and friends (>, <=, >=) will raise an exception instead of an arbitrary result, if type(x) != type(y) unless the types explicitly define the behaviour for these comparisions.
Don't compare objects of different types with undefined comparison behaviour
Deprecation of little-used alternative operators
One obvious way to test for inequality already exists: the '!=' operator. The rarely-used '<>' will go away.
Use only != for inequality comparison
The syntax `foo` for repr() will not exist in Python 3.0. Almost all code currently uses repr(foo) for this purpose, and the backtick syntax is little-known and less readable.
Use only repr(foo) for the representation of an object
New keywords
All of the names with, as, nonlocal, True and False are becoming keywords. Code that attempts to assign to those names will generate an exception in Python 3.0.
Don't assign to names that will become keywords
See more
Here are some more tips on writing Python code to be future proof with Python 3.0.
Collin Winter have some tips in: [http://oakwinter.com/code/porting-setuptools-to-py3k/]
More changes in the future?
The following little code might be useful to run when you upgrade to a new Python version. It shows how some new features in Python is getting gradually enabled. (This example is from Python 2.3.)
>>> import __future__ >>> for x in __future__.all_feature_names: ... print x, eval('__future__.'+x) ... nested_scopes _Feature((2, 1, 0, 'beta', 1), (2, 2, 0, 'alpha', 0), 16) generators _Feature((2, 2, 0, 'alpha', 1), (2, 3, 0, 'final', 0), 4096) division _Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192)
The second tuple (e.g. (3, 0, 0, 'alpha', 0) for division) shows when a new feature will become the default.