176 lines
6.5 KiB
Plaintext
176 lines
6.5 KiB
Plaintext
|
PEP: 290
|
||
|
Title: Code Migration and Modernization
|
||
|
Version: $Revision$
|
||
|
Last-Modified: $Date$
|
||
|
Author: python@rcn.com (Raymond D. Hettinger)
|
||
|
Status: Active
|
||
|
Type: Informational
|
||
|
Created: 6-Jun-2002
|
||
|
Post-History:
|
||
|
|
||
|
|
||
|
Abstract
|
||
|
|
||
|
This PEP is a collection of procedures and ideas for updating
|
||
|
Python applications when newer versions of Python are installed.
|
||
|
|
||
|
The migration tips highlight possible areas of incompatibility and
|
||
|
make suggestions on how to find and resolve those differences. The
|
||
|
modernization procedures show how older code can be updated to
|
||
|
take advantage of new language features.
|
||
|
|
||
|
|
||
|
Rationale
|
||
|
|
||
|
This repository of procedures serves as a catalog or checklist of
|
||
|
known migration issues and procedures for addressing those issues.
|
||
|
|
||
|
Migration issues can arise for several reasons. Some obsolete
|
||
|
features are slowly deprecated according to the guidelines in PEP 4.
|
||
|
Also, some code relies on undocumented behaviors which are subject to
|
||
|
change between versions. Some code may rely on behavior which was
|
||
|
subsequently shown to be a bug and that behavior changes when the bug
|
||
|
is fixed.
|
||
|
|
||
|
Modernization options arise when new versions of Python add features
|
||
|
that allow improved clarity or higher performance than previously
|
||
|
available.
|
||
|
|
||
|
|
||
|
|
||
|
Guidelines for New Entries
|
||
|
|
||
|
Developers with commit access may update the PEP directly. Others
|
||
|
can send their ideas to a developer for possible inclusion.
|
||
|
|
||
|
While a consistent format makes the repository easier to use, feel
|
||
|
free to add or subtract sections to improve clarity.
|
||
|
|
||
|
Grep patterns may be supplied as tool to help maintainers locate
|
||
|
code for possible updates. However, fully automated search/replace
|
||
|
style regular expressions are not recommended. Instead, each code
|
||
|
fragment should be evaluated individually.
|
||
|
|
||
|
The contra-indications section is the most important part of a new
|
||
|
entry. It lists known situations where the update SHOULD NOT be
|
||
|
applied.
|
||
|
|
||
|
|
||
|
Modernization Procedures
|
||
|
|
||
|
Pattern: if d.has_key(k): --> if k in d:
|
||
|
Idea: For testing dictionary membership, use the 'in' keyword
|
||
|
instead of the 'has_key()' method.
|
||
|
Version: 2.2 or greater
|
||
|
Benefits: The result is shorter and more readable. The style becomes
|
||
|
consistent with tests for membership in lists. The result is
|
||
|
slightly faster because has_key requires an attribute search
|
||
|
and uses a relatively expensive CALL FUNCTION op code.
|
||
|
Locating: grep has_key
|
||
|
Contra-indications:
|
||
|
1. if dictlike.has_key(k) ## objects like shelve do not define
|
||
|
__contains__()
|
||
|
|
||
|
|
||
|
Pattern: for k in d.keys() --> for k in d
|
||
|
for k in d.items() --> for k in d.iteritems()
|
||
|
for k in d.values() --> for k in d.itervalues()
|
||
|
Idea: Use the new iter methods for looping over dictionaries
|
||
|
Version: 2.2 or greater
|
||
|
Benefits: The iter methods are faster because the do not have to create
|
||
|
a new list object with a complete copy of all of the keys,
|
||
|
values, or items. Selecting only keys, items, or values as
|
||
|
needed saves the time for creating throwaway object references
|
||
|
and, in the case of items, saves a second hash look-up of
|
||
|
the key.
|
||
|
Contra-indications:
|
||
|
1. def getids(): return d.keys() ## do not change the return type
|
||
|
2. for k in dictlike.keys() ## objects like shelve do not define
|
||
|
itermethods
|
||
|
3. k = d.keys(); j = k[:] ## iterators do not support slicing,
|
||
|
sorting or other operations
|
||
|
4. for k in d.keys(): del[k] ## dict iterators prohibit modifying the
|
||
|
dictionary
|
||
|
|
||
|
|
||
|
Pattern: if v == None --> if v is None:
|
||
|
if v != None --> if v is not None:
|
||
|
Idea: Since there is only one None object, equality can be tested
|
||
|
with identity.
|
||
|
Version: All
|
||
|
Benefits: Identity tests are slightly faster than equality tests. Also,
|
||
|
some object types may overload comparison to be much slower.
|
||
|
Locating: grep '== None' or grep '!= None'
|
||
|
|
||
|
|
||
|
Pattern: os.stat("foo")[stat.ST_MTIME] --> os.stat("foo").st_mtime
|
||
|
os.stat("foo")[stat.ST_MTIME] --> os.path.getmtime("foo")
|
||
|
Idea: Replace stat contants or indices with new stat methods
|
||
|
Version: 2.2 or greater
|
||
|
Benefits: The methods are not order dependent and do not require an
|
||
|
import of the stat module
|
||
|
Locating: grep os.stat
|
||
|
|
||
|
|
||
|
Pattern: import whrandom --> import random
|
||
|
Idea: Replace deprecated module
|
||
|
Version: 2.1 or greater
|
||
|
Benefits: All random methods collected in one place
|
||
|
Locating: grep whrandom
|
||
|
|
||
|
|
||
|
Pattern: import types ; type(v, types.IntType) --> isinstance(v, int)
|
||
|
type(s, types.StringTypes --> isinstance(s, basestring)
|
||
|
Idea: The types module will likely to be deprecated in the future.
|
||
|
Version: 2.2 or greater
|
||
|
Benefits: May be slightly faster, avoid a deprecated feature.
|
||
|
Locating: grep types *.py | grep import
|
||
|
|
||
|
|
||
|
Pattern: import string ; string.method(s, ...) --> s.method(...)
|
||
|
c in string.whitespace --> c.isspace()
|
||
|
Idea: The string module will likely to be deprecated in the future.
|
||
|
Version: 2.0 or greater
|
||
|
Benefits: Slightly faster, avoid a deprecated feature.
|
||
|
Locating: grep string *.py | grep import
|
||
|
|
||
|
|
||
|
Pattern: NewError = 'NewError' --> class NewError(Exception): pass
|
||
|
Idea: String exceptions are deprecated, derive from the Exception
|
||
|
base class.
|
||
|
Version: Any
|
||
|
Benefits: Unlike the obsolete string exceptions, class exceptions all
|
||
|
derive from another exception or the Exception base class.
|
||
|
This allows meaningful groupings of exceptions. It also
|
||
|
allows an "except Exception" clause to catch all exceptions.
|
||
|
Locating: Use PyChecker
|
||
|
|
||
|
Pattern: "foobar"[:3] == "foo" -> "foobar".startswith("foo")
|
||
|
"foobar"[-3:] == "bar" -> "foobar".endswith("bar")
|
||
|
Version: 2.0 or greater
|
||
|
Benefits: Faster because no slice has to be created. Less risk of
|
||
|
miscounting.
|
||
|
|
||
|
|
||
|
References
|
||
|
|
||
|
[1] PEP 4, Deprecation of Standard Modules
|
||
|
http://www.python.org/peps/pep-0004.html
|
||
|
|
||
|
|
||
|
|
||
|
Copyright
|
||
|
|
||
|
This document has been placed in the public domain.
|
||
|
|
||
|
|
||
|
|
||
|
Local Variables:
|
||
|
mode: indented-text
|
||
|
indent-tabs-mode: nil
|
||
|
sentence-end-double-space: t
|
||
|
fill-column: 70
|
||
|
End:
|
||
|
|
||
|
|