Files
dive-into-python3/porting-code-to-python-3-with-2to3.html
T
Mark Pilgrim b26e06634b various fluff
2009-01-29 01:00:23 -05:00

2050 lines
50 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Porting code to Python 3 with 2to3 - Dive into Python 3</title>
<link rel="stylesheet" type="text/css" href="dip3.css">
<style type="text/css">
h1:before{counter-increment:h1;content:"Appendix A. "}
h2:before{counter-increment:h2;content:"A." counter(h2) ". "}
h3:before{counter-increment:h3;content:"A." counter(h2) "." counter(h3) ". "}
</style>
<script type="text/javascript">
window.onload = function() {
if (!window.addEventListener) { return; }
var arTables = document.getElementsByTagName('table');
for (var i = arTables.length - 1; i >= 0; i--) {
var elmTable = arTables[i];
var olNotes = document.getElementById("skip" + elmTable.id);
if (!olNotes) { continue; }
var arNotes = olNotes.getElementsByTagName('li');
var arTableRows = elmTable.getElementsByTagName('tr');
if (arNotes.length == 0) { continue; }
//if (arNotes.length != arTableRows.length - 1) { alert(elmTable.id + "table has " + arTableRows.length + " rows but the list below it has " + arNotes.length + " items!"); }
for (var j = arTableRows.length - 1; j >= 1; j--) {
var elmTableRow = arTableRows[j];
var elmNote = arNotes[j - 1];
elmTableRow._li = elmNote;
elmNote._tr = elmTableRow;
elmTableRow.addEventListener('mouseover', function() {
this.className = 'hover';
this._li.className = 'hover';
}, true);
elmNote.addEventListener('mouseover', function() {
this.className = 'hover';
this._tr.className = 'hover';
}, true);
elmTableRow.addEventListener('mouseout', function() {
this.className = '';
this._li.className = '';
}, true);
elmNote.addEventListener('mouseout', function() {
this.className = '';
this._tr.className = '';
}, true);
}
}
}
</script>
</head>
<body>
<h1>Porting code to Python 3 with <code>2to3</code></h1>
<aside>
<blockquote class="q">
<p><span>&#x275D;</span> Life is pleasant. Death is peaceful. It's the transition that's troublesome. <span>&#x275E;</span><br>&mdash; Isaac Asimov (attributed)</p>
</blockquote>
</aside>
<ol class="toc">
<li><a href="#divingin">Diving in</a></li>
<li><a href="#print"><code>print</code> statement</a></li>
<li><a href="#ne">&lt;> comparison</a></li>
<li><a href="#has_key"><code>has_key()</code> dictionary method</a></li>
<li><a href="#dict">Dictionary methods that return lists</a></li>
<li><a href="#imports">Modules that have been renamed or reorganized</a>
<ol>
<li><a href="#http"><code>http</code> package</a></li>
<li><a href="#urllib"><code>urllib</code> package</a></li>
<li><a href="#dbm"><code>dbm</code> package</a></li>
<li><a href="#xmlrpc"><code>xmlrpc</code> package</a></li>
<li><a href="#othermodules">Other modules</a></li>
</ol>
</li>
<li><a href="#import">Relative imports within a package</a></li>
<li><a href="#filter"><code>filter()</code> global function</a></li>
<li><a href="#map"><code>map()</code> global function</a></li>
<li><a href="#reduce"><code>reduce()</code> global function (3.1+)</a></li>
<li><a href="#apply"><code>apply()</code> global function</a></li>
<li><a href="#intern"><code>intern()</code> global function</a></li>
<li><a href="#exec"><code>exec</code> statement</a></li>
<li><a href="#execfile"><code>execfile</code> statement (3.1+)</a></li>
<li><a href="#repr"><code>repr</code> literals (backticks)</a></li>
<li><a href="#except"><code>try...except</code> statement</a></li>
<li><a href="#raise"><code>raise</code> statement</a></li>
<li><a href="#throw"><code>throw</code> statement</a></li>
<li><a href="#long"><code>long</code> data type</a></li>
<li><a href="#xrange"><code>xrange()</code> global function</a></li>
<li><a href="#raw_input"><code>raw_input()</code> and <code>input()</code> global functions</a></li>
<li><a href="#funcattrs"><code>func_*</code> function attributes</a></li>
<li><a href="#xreadlines"><code>xreadlines()</code> I/O method</a></li>
<li><a href="#tuple_params"><code>lambda</code> functions with multiple parameters</a></li>
<li><a href="#methodattrs">Special method attributes</a></li>
<li><a href="#next"><code>next()</code> iterator method</a></li>
<li><a href="#nonzero"><code>__nonzero__</code> special class attribute</a></li>
<li><a href="#numliterals">Number literals</a></li>
<li><a href="#renames"><code>sys.maxint</code></a></li>
<li><a href="#unicode"><code>unicode()</code> global function</a></li>
<li><a href="#unicodeliteral">Unicode string literals</a></li>
<li><a href="#callable"><code>callable()</code> global function</a></li>
<li><a href="#zip"><code>zip()</code> global function</a></li>
<li><a href="#standarderror"><code>StandardError()</code> exception</a></li>
<li><a href="#types"><code class="filename">types</code> module constants</a></li>
<li><a href="#isinstance"><code>isinstance</code> global function (3.1+)</a></li>
<li><a href="#basestring"><code>basestring</code> datatype</a></li>
<li><a href="#itertools"><code class="filename">itertools</code> module</a></li>
<li><a href="#sys_exc"><code>sys.exc_type</code>, <code>sys.exc_value</code>, <code>sys.exc_traceback</code></a></li>
<li><a href="#paren">List comprehensions over tuples</a></li>
<li><a href="#getcwdu"><code>os.getcwdu()</code> function</a></li>
<li><a href="#metaclass">Metaclasses</a></li>
<li><a href="#set_literal"><code>set()</code> literals</a></li>
<li><a href="#buffer"><code>buffer()</code> global function</a></li>
<li><a href="#wscomma">Whitespace around commas</a></li>
<li><a href="#idioms">Common idioms</a></li>
</ol>
<section>
<h2 id="divingin">Diving in</h2>
<p class="fancy">FIXME intro</p>
<p>...</p>
</section>
<section>
<h2 id="print"><code>print</code> statement</h2>
<p>In Python 2, <code>print</code> was a statement -- whatever you wanted to print simply followed the <code>print</code> keyword. In Python 3, <code>print()</code> is a function -- whatever you want to print is passed to <code>print()</code> like any other function.</p>
<p><a class="skip" href="#skipcompareprint">skip over this table</a></p>
<table id="compareprint">
<tr>
<th class="notes">Notes</th>
<th class="python2">Python 2</th>
<th class="python3">Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>print</code></td>
<td><code>print()</code></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><code>print 1</code></td>
<td><code>print(1)</code></td>
</tr>
<tr>
<th>&#x2462;</th>
<td><code>print 1, 2</code></td>
<td><code>print(1, 2)</code></td>
</tr>
<tr>
<th>&#x2463;</th>
<td><code>print 1, 2,</code></td>
<td><code>print(1, 2, end=' ')</code></td>
</tr>
<tr>
<th>&#x2464;</th>
<td><code>print >>sys.stderr, 1, 2, 3</code></td>
<td><code>print(1, 2, 3, file=sys.stderr)</code></td>
</tr>
</table>
<ol id="skipcompareprint">
<li>To print a blank line, call <code>print()</code> without any arguments.</li>
<li>To print a single value, call <code>print()</code> with one argument</li>
<li>To print two values separated by a space, call <code>print()</code> with two arguments.</li>
<li>This one is a little tricky. In Python 2, if you ended a <code>print</code> statement with a comma, it would print the values separated by spaces, then print a trailing space, then stop without printing a carriage return. In Python 3, the way to do this is to pass <code>end=' '</code> as a keyword argument to the <code>print()</code> function. The <code>end</code> argument defaults to <code>'\n'</code> (a carriage return), so overriding it will suppress the carriage return after printing the other arguments.</li>
<li>In Python 2, you could redirect the output to a pipe -- like <code>sys.stderr</code> -- by using the <code>>>pipe_name</code> syntax. In Python 3, the way to do this is to pass the pipe in the <code>file</code> keyword argument. The <code>file</code> argument defaults to <code>sys.stdout</code> (standard out), so overriding it will output to a different pipe instead.</li>
</ol>
</section>
<section>
<h2 id="ne">&lt;> comparison</h2>
<p>Python 2 supported <code>&lt;></code> as a synonym for <code>!=</code>, the not-equals comparison operator. Python 3 supports the <code>!=</code> operator, but not <code>&lt;></code>.</p>
<p><a class="skip" href="#skipcomparene">skip over this table</a></p>
<table id="comparene">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>if x <> y:</code></td>
<td><code>if x != y:</code></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><code>if x <> y <> z:</code></td>
<td><code>if x != y != z:</code></td>
</tr>
</table>
<ol id="skipcomparene">
<li>A simple comparison.</li>
<li>A more complex comparison between three values.</li>
</ol>
</section>
<section>
<h2 id="has_key"><code>has_key()</code> dictionary method</h2>
<p>In Python 2, dictionaries had a <code>has_key()</code> method to test whether the dictionary had a certain key. In Python 3, this method no longer exists. Instead, you need to use the <code>in</code> operator.</p>
<p><a class="skip" href="#skipcomparehas_key">skip over this table</a></p>
<table id="comparehas_key">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>a_dictionary.has_key("PapayaWhip")</code></td>
<td><code>"PapayaWhip" in a_dictionary</code></td>
</tr>
<tr>
<th>&#x2461;</th >
<td><code>a_dictionary.has_key(x) or a_dictionary.has_key(y)</code></td>
<td><code>x in a_dictionary or y in a_dictionary</code></td>
</tr>
<tr>
<th>&#x2462;</th>
<td><code>a_dictionary.has_key(x or y)</code></td>
<td><code>(x or y) in a_dictionary</code></td>
</tr>
<tr>
<th>&#x2463;</th>
<td><code>a_dictionary.has_key(x + y)</code></td>
<td><code>(x + y) in a_dictionary</code></td>
</tr>
<tr>
<th>&#x2464;</th>
<td><code>x + a_dictionary.has_key(y)</code></td>
<td><code>x + (y in a_dictionary)</code></td>
</tr>
</table>
<ol id="skipcomparehas_key">
<li>The simplest form.</li>
<li>The <code>or</code> operator takes precedence over the <code>in</code> operator, so there is no need for parentheses here.</li>
<li>On the other hand, you <em>do</em> need parentheses here, for the same reason -- <code>or</code> takes precedence over <code>in</code>.</li>
<li>The <code>in</code> operator takes precedence over the <code>+</code> operator, so this form needs parentheses too.</li>
<li>Again with the parentheses, for the same reason.</li>
</ol>
</section>
<section>
<h2 id="dict">Dictionary methods that return lists</h2>
<p>In Python 2, many dictionary methods returned lists. The most frequently used methods were <code>keys()</code>, <code>items()</code>, and <code>values()</code>. In Python 3, all of these methods return dynamic views. In some contexts, this is not a problem. If the method's return value is immediately passed to another function that iterates through the entire sequence, it makes no difference whether the actual type is a list or a view. In other contexts, it matters a great deal. If you were expecting a complete list with individually addressable elements, your code will choke, because views do not support indexing.</p>
<p><a class="skip" href="#skipcomparedict">skip over this table</a></p>
<table id="comparedict">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>a_dictionary.keys()</code></td>
<td><code>list(a_dictionary.keys())</code></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><code>a_dictionary.items()</code></td>
<td><code>list(a_dictionary.items())</code></td>
</tr>
<tr>
<th>&#x2462;</th>
<td><code>a_dictionary.iterkeys()</code></td>
<td><code>iter(a_dictionary.keys())</code></td>
</tr>
<tr>
<th>&#x2463;</th>
<td><code>[i for i in a_dictionary.iterkeys()]</code></td>
<td><code>[i for i in a_dictionary.keys()]</code></td>
</tr>
<tr>
<th>&#x2464;</th>
<td><code>min(a_dictionary.keys())</code></td>
<td><i>no change</i></td>
</tr>
</table>
<ol id="skipcomparedict">
<li><code>2to3</code> errs on the side of safety, converting the return value from <code>keys()</code> to a static list with the <code>list()</code> function. This will always work, but it will be less efficient than using a view. You should examine the converted code to see if a list is absolutely necessary, or if a view would do.</li>
<li>Another view-to-list conversion, with the <code>items()</code> method. <code>2to3</code> will do the same thing with the <code>values()</code> method.</li>
<li>Python 3 does not support the <code>iterkeys()</code> method anymore. Use <code>keys()</code>, and if necessary, convert the view to an iterator with the <code>iter()</code> function.</li>
<li><code>2to3</code> recognizes when the <code>iterkeys()</code> method is used inside a list comprehension, and converts it to the <code>keys()</code> method (without wrapping it in an extra call to <code>iter()</code>). This works because views are iterable.</li>
<li><code>2to3</code> recognizes that the <code>keys()</code> method is immediately passed to a function which iterates through an entire sequence, so there is no need to convert the return value to a list first. The <code>min()</code> function will happily iterate through the view instead. This applies to <code>min()</code>, <code>max()</code>, <code>sum()</code>, <code>list()</code>, <code>tuple()</code>, <code>set()</code>, <code>sorted()</code>, <code>any()</code>, and <code>all()</code>.</li>
</ol>
</section>
<section>
<h2 id="imports">Modules that have been renamed or reorganized</h2>
<p>Several modules in the Python Standard Library have been renamed. Several other modules which are related to each other have been combined or reorganized to make their association more logical.</p>
<p>FIXME: once the rest of the book is written, these should link back to the chapters and sections that explain these modules.</p>
<section>
<h3 id="http"><code>http</code> package</h3>
In Python 3, several related HTTP modules have been combined into a single package, <code>http</code>.</p>
<p><a class="skip" href="#skipcompareimporthttp">skip over this table</a></p>
<table id="compareimporthttp">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>import httplib</code></td>
<td><code>import http.client</code></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><code>import Cookie</code></td>
<td><code>import http.cookies</code></td>
</tr>
<tr>
<th>&#x2462;</th>
<td><code>import cookielib</code></td>
<td><code>import http.cookiejar</code></td>
</tr>
<tr>
<th>&#x2463;</th>
<td><pre><code>import BaseHTTPServer
import SimpleHTTPServer
import CGIHttpServer</code></pre></td>
<td><code>import http.server</code></td>
</tr>
</table>
<ol id="skipcompareimporthttp">
<li>The <code>http.client</code> module implements a low-level library that can request HTTP resources and interpret HTTP responses.</li>
<li>The <code>http.cookies</code> module provides a Pythonic interface to "cookies" that are sent in a <code>Set-Cookie:</code> HTTP header.</li>
<li>The <code>http.cookiejar</code> module manipulates the actual files on disk that popular web browsers use to store cookies.</li>
<li>The <code>http.server</code> module provides a basic HTTP server.</li>
</ol>
</section>
<section>
<h3 id="urllib"><code>urllib</code> package</h3>
<p>Python 2 had a rat's nest of overlapping modules to parse, encode, and fetch URLs. In Python 3, these have all been refactored and combined in a single package, <code>urllib</code>.</p>
<p><a class="skip" href="#skipcompareimporturllib">skip over this table</a></p>
<table id="compareimporturllib">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>import urllib</code></td>
<td><code>import urllib.request, urllib.parse, urllib.error</code></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><code>import urllib2</code></td>
<td><code>import urllib.request, urllib.error</code></td>
</tr>
<tr>
<th>&#x2462;</th>
<td><code>import urlparse</code></td>
<td><code>import urllib.parse</code></td>
</tr>
<tr>
<th>&#x2463;</th>
<td><code>import robotparser</code></td>
<td><code>import urllib.robotparser</code></td>
</tr>
<tr>
<th>&#x2464;</th>
<td><pre><code>from urllib import FancyURLopener
from urllib import urlencode</code></pre></td>
<td><pre><code>from urllib.request import FancyURLopener
from urllib.parse import urlencode</code></pre></td>
</tr>
<tr>
<th>&#x2465;</th>
<td><pre><code>from urllib2 import Request
from urllib2 import HTTPError</code></pre></td>
<td><pre><code>from urllib.request import Request
from urllib.error import HTTPError</code></pre></td>
</tr>
</table>
<ol id="skipcompareimporturllib">
<li>The old <code>urllib</code> module in Python 2 had a variety of functions, including <code>urlopen()</code> for fetching data and <code>splittype()</code>, <code>splithost()</code>, and <code>splituser()</code> for splitting a URL into its constituent parts. These functions have been reorganized more logically within the new <code>urllib</code> package. <code>2to3</code> will also change all calls to these functions so they use the new naming scheme.</li>
<li>The old <code>urllib2</code> module in Python 2 has been folded into into the <code>urllib</code> package in Python 3. All your <code>urllib2</code> favorites -- the <code>build_opener()</code> method, <code>Request</code> objects, and <code>HTTPBasicAuthHandler</code> and friends -- are still available.</li>
<li>The <code>urllib.parse</code> module in Python 3 contains all the parsing functions from the old <code>urlparse</code> module in Python 2.</li>
<li>The <code>urllib.robotparser</code> module parses <a href="http://www.robotstxt.org/"><code>robots.txt</code> files</a>.</li>
<li>The <code>FancyURLopener</code> class, which handles HTTP redirects and other status codes, is still available in the new <code>urllib.request</code> module. The <code>urlencode</code> function has moved to <code>urllib.parse</code>.</li>
<li>The <code>Request</code> object is still available in <code>urllib.request</code>, but constants like <code>HTTPError</code> have been moved to <code>urllib.error</code>.</li>
</ol>
</section>
<section>
<h3 id="dbm"><code>dbm</code> package</h3>
<p>All the various DBM clones are now in a single package, <code>dbm</code>. If you need a specific variant like GNU DBM, you can import the appropriate module within the <code>dbm</code> package.</p>
<p><a class="skip" href="#skipcompareimportdbm">skip over this table</a></p>
<table id="compareimportdbm">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th></th>
<td><code>import dbm</code></td>
<td><code>import dbm.ndbm</code></td>
</tr>
<tr>
<th></th>
<td><code>import gdbm</code></td>
<td><code>import dbm.gnu</code></td>
</tr>
<tr>
<th></th>
<td><code>import dbhash</code></td>
<td><code>import dbm.bsd</code></td>
</tr>
<tr>
<th></th>
<td><code>import dumbdbm</code></td>
<td><code>import dbm.dumb</code></td>
</tr>
<tr>
<th></th>
<td><pre><code>import anydbm
import whichdb</code></pre></td>
<td><code>import dbm</code></td>
</tr>
</table>
<p id="skipcompareimportdbm"></p>
</section>
<section>
<h3 id="xmlrpc"><code>xmlrpc</code> package</h3>
<p>XML-RPC is a lightweight method of performing remote RPC calls over HTTP. The XML-RPC client library and several XML-RPC server implementations are now combined in a single package, <code>xmlrpc</code>.</p>
<p><a class="skip" href="#skipcompareimportxmlrpc">skip over this table</a></p>
<table id="compareimportxmlrpc">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th></th>
<td><code>import xmlrpclib</code></td>
<td><code>import xmlrpc.client</code></td>
</tr>
<tr>
<th></th>
<td><pre><code>import DocXMLRPCServer
import SimpleXMLRPCServer</code></pre></td>
<td><code>import xmlrpc.server</code></td>
</tr>
</table>
<p id="skipcompareimportxmlrpc"></p>
</section>
<section>
<h3 id="othermodules">Other modules</h3>
<p><a class="skip" href="#skipcompareimports">skip over this table</a></p>
<table id="compareimports">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><pre><code>try:
import cStringIO as StringIO
except ImportError:
import StringIO</code></pre></td>
<td><code>import io</code></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><pre><code>try:
import cPickle as pickle
except ImportError:
import pickle</code></pre></td>
<td><code>import pickle</code></td>
</tr>
<tr>
<th>&#x2462;</th>
<td><code>import __builtin__</code></td>
<td><code>import builtins</code></td>
</tr>
<tr>
<th>&#x2463;</th>
<td><code>import copy_reg</code></td>
<td><code>import copyreg</code></td>
</tr>
<tr>
<th>&#x2464;</th>
<td><code>import Queue</code></td>
<td><code>import queue</code></td>
</tr>
<tr>
<th>&#x2465;</th>
<td><code>import SocketServer</code></td>
<td><code>import socketserver</code></td>
</tr>
<tr>
<th>&#x2466;</th>
<td><code>import ConfigParser</code></td>
<td><code>import configparser</code></td>
</tr>
<tr>
<th>&#x2467;</th>
<td><code>import repr</code></td>
<td><code>import reprlib</code></td>
</tr>
<tr>
<th>&#x2468;</th>
<td><code>import commands</code></td>
<td><code>import subprocess</code></td>
</tr>
</table>
<ol id="skipcompareimports">
<li>A common idiom in Python 2 was to try to import <code>cStringIO as StringIO</code>, and if that failed, to import <code>StringIO</code> instead. Do not do this in Python 3; the <code>io</code> module does it for you. It will find the fastest implementation available and use it automatically.</li>
<li>A similar idiom was used to import the fastest pickle implementation. Do not do this in Python 3; the <code>pickle</code> module does it for you.</li>
<li>The <code>builtins</code> module contains the "global" functions, classes, and constants used throughout the Python language. Redefining a function in the <code>builtins</code> module will redefine the "global" function everywhere. That is exactly as powerful and scary as it sounds.</li>
<li>The <code>copyreg</code> module adds pickle support for custom types defined in C.</li>
<li>The <code>queue</code> module implements a multi-producer, multi-consumer queue.</li>
<li>The <code>socketserver</code> module provides generic base classes for implementing different kinds of socket servers.</li>
<li>The <code>configparser</code> module parses INI-style configuration files.</li>
<li>The <code>reprlib</code> module reimplements the built-in <code>repr()</code> function, but with limits on how many values are represented.</li>
<li>The <code>subprocess</code> module allows you to spawn processes, connect to their pipes, and obtain their return codes.</li>
</ol>
</section>
</section>
<section>
<h2 id="import">Relative imports within a package</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcompareimport">skip over this table</a></p>
<table id="compareimport">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>FIXME</code></td>
<td><code>FIXME</code></td>
</tr>
</table>
<ol id="skipcompareimport">
<li>...</li>
</ol>
</section>
<section>
<h2 id="filter"><code>filter()</code> global function</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcomparefilter">skip over this table</a></p>
<table id="comparefilter">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>filter(a_function, a_sequence)</code></td>
<td><code>list(filter(a_function, a_sequence))</code></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><code>list(filter(a_function, a_sequence))</code></td>
<td><i>no change</i></td>
</tr>
<tr>
<th>&#x2462;</th>
<td><code>filter(None, a_sequence)</code></td>
<td><code>[i for i in a_sequence if i]</code></td>
</tr>
<tr>
<th>&#x2463;</th>
<td><code>for i in filter(None, a_sequence)</code></td>
<td><i>no change</i></td>
</tr>
<tr>
<th>&#x2464;</th>
<td><code>[i for i in filter(a_function, a_sequence)]</code></td>
<td><i>no change</i></td>
</tr>
</table>
<ol id="skipcomparefilter">
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
</ol>
</section>
<section>
<h2 id="map"><code>map()</code> global function</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcomparemap">skip over this table</a></p>
<table id="comparemap">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>map(a_function, 'PapayaWhip')</code></td>
<td><code>list(map(a_function, 'PapayaWhip'))</code></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><code>map(None, 'PapayaWhip')</code></td>
<td><code>list('PapayaWhip')</code></td>
</tr>
<tr>
<th>&#x2462;</th>
<td><code>map(lambda x: x+1, range(42))</code></td>
<td><code>[x+1 for x in range(42)]</code></td>
</tr>
<tr>
<th>&#x2463;</th>
<td><code>for i in map(a_function, a_sequence):</code></td>
<td><i>unchanged</i></td>
</tr>
<tr>
<th>&#x2464;</th>
<td><code>[i for i in map(a_function, a_sequence)]</code></td>
<td><i>unchanged</i></td>
</tr>
</table>
<ol id="skipcomparemap">
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
</ol>
</section>
<section>
<h2 id="reduce"><code>reduce()</code> global function (3.1+)</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcomparereduce">skip over this table</a></p>
<table id="comparereduce">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>reduce(a, b, c)</code></td>
<td><pre><code>from functtools import reduce
reduce(a, b, c)</code></td>
</tr>
</table>
<ol id="skipcomparereduce">
<li>...</li>
</ol>
</section>
<section>
<h2 id="apply"><code>apply()</code> global function</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcompareapply">skip over this table</a></p>
<table id="compareapply">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>apply(a_function, args)</code></td>
<td><code>a_function(*args)</code></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><code>apply(a_function, args, kwds)</code></td>
<td><code>a_function(*args, **kwds)</code></td>
</tr>
<tr>
<th>&#x2462;</th>
<td><code>apply(a_function, args + z)</code></td>
<td><code>a_function(*args + z)</code></td>
</tr>
<tr>
<th>&#x2463;</th>
<td><code>apply(aModule.a_function, args)</code></td>
<td><code>aModule.a_function(*args)</code></td>
</tr>
</table>
<ol id="skipcompareapply">
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
</ol>
</section>
<section>
<h2 id="intern"><code>intern()</code> global function</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcompareintern">skip over this table</a></p>
<table id="compareintern">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>intern(aString)</code></td>
<td><code>sys.intern(aString)</code></td>
</tr>
</table>
<ol id="skipcompareintern">
<li>...</li>
</ol>
</section>
<section>
<h2 id="exec"><code>exec</code> statement</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcompareexec">skip over this table</a></p>
<table id="compareexec">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>exec codeString</code></td>
<td><code>exec(codeString)</code></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><code>exec codeString in a_global_namespace</code></td>
<td><code>exec(codeString, a_global_namespace)</code></td>
</tr>
<tr>
<th>&#x2462;</th>
<td><code>exec codeString in a_global_namespace, a_local_namespace</code></td>
<td><code>exec(codeString, a_global_namespace, a_local_namespace)</code></td>
</tr>
</table>
<ol id="skipcompareexec">
<li>...</li>
<li>...</li>
<li>...</li>
</ol>
</section>
<section>
<h2 id="execfile"><code>execfile</code> statement (3.1+)</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcompareexecfile">skip over this table</a></p>
<table id="compareexecfile">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>execfile("a_filename")</code></td>
<td><code>execfile(compile(open("a_filename").read(), "a_filename", "exec"))</code></td>
</tr>
</table>
<ol id="skipcompareexecfile">
<li>...</li>
</ol>
</section>
<section>
<h2 id="repr"><code>repr</code> literals (backticks)</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcomparerepr">skip over this table</a></p>
<table id="comparerepr">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>`x`</code></td>
<td><code>repr(x)</code></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><code>`1 + 2`</code></td>
<td><code>repr(1 + 2)</code></td>
</tr>
<tr>
<th>&#x2462;</th>
<td><code>`"PapayaWhip" + `2``</code></td>
<td><code>repr("PapayaWhip" + repr(2))</code></td>
</tr>
</table>
<ol id="skipcomparerepr">
<li>...</li>
<li>...</li>
<li>...</li>
</ol>
</section>
<section>
<h2 id="except"><code>try...except</code> statement</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcompareexcept">skip over this table</a></p>
<table id="compareexcept">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><pre><code>try:
import mymodule
except ImportError, e
pass</code></pre></td>
<td><pre><code>try:
import mymodule
except ImportError as e:
pass</code></pre></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><pre><code>try:
import mymodule
except (RuntimeError, ImportError), e
pass</code></pre></td>
<td><pre><code>try:
import mymodule
except (RuntimeError, ImportError) as e:
pass</code></pre></td>
</tr>
<tr>
<th>&#x2462;</th>
<td><pre><code>try:
import mymodule
except ImportError:
pass</code></pre></td>
<td><i>unchanged</i></td>
</tr>
<tr>
<th>&#x2463;</th>
<td><pre><code>try:
import mymodule
except:
pass</code></pre></td>
<td><i>unchanged</i></td>
</tr>
</table>
<ol id="skipcompareexcept">
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
</ol>
</section>
<section>
<h2 id="raise"><code>raise</code> statement</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcompareraise">skip over this table</a></p>
<table id="compareraise">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>raise MyException, "error message"</code></td>
<td><code>raise MyException("error message")</code></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><code>raise MyException, "error message", a_traceback</code></td>
<td><code>raise MyException("error message").with_traceback(a_traceback)</code></td>
</tr>
<tr>
<th>&#x2462;</th>
<td><code>raise "error message"</code></td>
<td><i>unsupported</i></td>
</tr>
</table>
<ol id="skipcompareraise">
<li>...</li>
<li>...</li>
<li>...</li>
</ol>
</section>
<section>
<h2 id="throw"><code>throw</code> statement</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcomparethrow">skip over this table</a></p>
<table id="comparethrow">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>aGenerator.throw(MyException)</code></td>
<td><i>unchanged</i></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><code>aGenerator.throw(MyException, "error message")</code></td>
<td><code>aGenerator.throw(MyException("error message"))</code></td>
</tr>
<tr>
<th>&#x2462;</th>
<td><code>aGenerator.throw("error message")</code></td>
<td><i>unsupported</i></td>
</tr>
</table>
<ol id="skipcomparethrow">
<li>...</li>
<li>...</li>
<li>...</li>
</ol>
</section>
<section>
<h2 id="long"><code>long</code> data type</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcomparelong">skip over this table</a></p>
<table id="comparelong">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>x = 1000000000000L</code></td>
<td><code>x = 1000000000000</code></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><code>x = 0xFFFFFFFFFFFFL</code></td>
<td><code>x = 0xFFFFFFFFFFFF</code></td>
</tr>
<tr>
<th>&#x2462;</th>
<td><code>long(x)</code></td>
<td><code>int(x)</code></td>
</tr>
<tr>
<th>&#x2463;</th>
<td><code>type(x) is long</code></td>
<td><code>type(x) is int</code></td>
</tr>
<tr>
<th>&#x2464;</th>
<td><code>isinstance(x, long)</code></td>
<td><code>isinstance(x, int)</code></td>
</tr>
</table>
<ol id="skipcomparelong">
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
</ol>
</section>
<section>
<h2 id="xrange"><code>xrange()</code> global function</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcomparexrange">skip over this table</a></p>
<table id="comparexrange">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>xrange(10)</code></td>
<td><code>range(10)</code></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><code>a_sequence = range(10)</code></td>
<td><code>a_sequence = list(range(10))</code></td>
</tr>
<tr>
<th>&#x2462;</th>
<td><code>[i for i in xrange(10)]</code></td>
<td><code>[i for i in range(10)]</code></td>
</tr>
<tr>
<th>&#x2463;</th>
<td><code>for i in range(10):</code></td>
<td><i>unchanged</i></td>
</tr>
<tr>
<th>&#x2464;</th>
<td><code>sum(range(10))</code></td>
<td><i>unchanged</i></td>
</tr>
</table>
<ol id="skipcomparexrange">
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
</ol>
</section>
<section>
<h2 id="raw_input"><code>raw_input()</code> and <code>input()</code> global functions</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcompareraw_input">skip over this table</a></p>
<table id="compareraw_input">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>raw_input()</code></td>
<td><code>input()</code></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><code>raw_input("prompt")</code></td>
<td><code>input("prompt")</code></td>
</tr>
<tr>
<th>&#x2462;</th>
<td><code>input()</code></td>
<td><code>eval(input())</code></td>
</tr>
<tr>
<th>&#x2463;</th>
<td><code>input("prompt")</code></td>
<td><code>eval(input("prompt"))</code></td>
</tr>
</table>
<ol id="skipcompareraw_input">
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
</ol>
</section>
<section>
<h2 id="funcattrs"><code>func_*</code> function attributes</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcomparefuncattrs">skip over this table</a></p>
<table id="comparefuncattrs">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>a_function.func_closure</code></td>
<td><code>a_function.__closure__</code></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><code>a_function.func_doc</code></td>
<td><code>a_function.__doc__</code></td>
</tr>
<tr>
<th>&#x2462;</th>
<td><code>a_function.func_name</code></td>
<td><code>a_function.__name__</code></td>
</tr>
<tr>
<th>&#x2463;</th>
<td><code>a_function.func_defaults</code></td>
<td><code>a_function.__defaults__</code></td>
</tr>
<tr>
<th>&#x2464;</th>
<td><code>a_function.func_code</code></td>
<td><code>a_function.__code__</code></td>
</tr>
<tr>
<th>&#x2465;</th>
<td><code>a_function.func_globals</code></td>
<td><code>a_function.__globals__</code></td>
</tr>
<tr>
<th>&#x2466;</th>
<td><code>a_function.func_dict</code></td>
<td><code>a_function.__dict__</code></td>
</tr>
</table>
<ol id="skipcomparefuncattrs">
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
</ol>
</section>
<section>
<h2 id="xreadlines"><code>xreadlines()</code> I/O method</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcomparexreadlines">skip over this table</a></p>
<table id="comparexreadlines">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>for line in a_file.xreadlines():</code></td>
<td><code>for line in a_file:</code></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><code>for line in a_file.xreadlines(5):</code></td>
<td><i>unchanged</i></td>
</tr>
</table>
<ol id="skipcomparexreadlines">
<li>...</li>
<li>...</li>
</ol>
</section>
<section>
<h2 id="tuple_params"><code>lambda</code> functions with multiple parameters</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcomparetuple_params">skip over this table</a></p>
<table id="comparetuple_params">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>lambda (x,): x + f(x)</code></td>
<td><code>lambda x1: x1[0] + f(x1[1])</code></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><code>lambda (x, y): x + f(y)</code></td>
<td><code>lambda x_y: x_y[0] + f(x_y[1])</code></td>
</tr>
<tr>
<th>&#x2462;</th>
<td><code>lambda (x, (y, z)): x + y + z</code></td>
<td><code>lambda x_y_z: x_y_z[0] + x_y_z[1][0] + x_y_z[1][1]</code></td>
</tr>
</table>
<ol id="skipcomparetuple_params">
<li>...</li>
<li>...</li>
<li>...</li>
</ol>
</section>
<section>
<h2 id="methodattrs">Special method attributes</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcomparemethodattrs">skip over this table</a></p>
<table id="comparemethodattrs">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>aClassInstance.aClassMethod.im_func</code></td>
<td><code>aClassInstance.aClassMethod.__func__</code></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><code>aClassInstance.aClassMethod.im_self</code></td>
<td><code>aClassInstance.aClassMethod.__self__</code></td>
</tr>
<tr>
<th>&#x2462;</th>
<td><code>aClassInstance.aClassMethod.im_class</code></td>
<td><code>aClassInstance.aClassMethod.self.__class__</code></td>
</tr>
</table>
<ol id="skipcomparemethodattrs">
<li>...</li>
<li>...</li>
<li>...</li>
</ol>
</section>
<section>
<h2 id="next"><code>next()</code> iterator method</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcomparenext">skip over this table</a></p>
<table id="comparenext">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>anIterator.next()</code></td>
<td><code>next(anIterator)</code></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><code>a_function_that_returns_an_iterator().next()</code></td>
<td><code>next(a_function_that_returns_an_iterator())</code></td>
</tr>
<tr>
<th>&#x2462;</th>
<td><pre><code>class A:
def next(self):
pass</code></pre></td>
<td><pre><code>class A:
def __next__(self):
pass</code></pre></td>
</tr>
<tr>
<th>&#x2463;</th>
<td><pre><code>class A:
def next(self, x, y):
pass</code></pre></td>
<td><i>unchanged</i></td>
</tr>
<tr>
<th>&#x2464;</th>
<td><pre><code>next = 42
for an_iterator in a_sequence_of_iterators:
an_iterator.next()</code></pre></td>
<td><pre><code>next = 42
for an_iterator in a_sequence_of_iterators:
an_iterator.__next__()</code></pre></td>
</tr>
</table>
<ol id="skipcomparenext">
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
</ol>
</section>
<section>
<h2 id="nonzero"><code>__nonzero__</code> special class attribute</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcomparenonzero">skip over this table</a></p>
<table id="comparenonzero">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><pre><code>class A:
def __nonzero__(self):
pass</code></pre></td>
<td><pre><code>class A:
def __bool__(self):
pass</code></pre></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><pre><code>class A:
def __nonzero__(self, x, y):
pass</code></pre></td>
<td><i>unchanged</i></td>
</tr>
</table>
<ol id="skipcomparenonzero">
<li>...</li>
<li>...</li>
</ol>
</section>
<section>
<h2 id="numliterals">Number literals</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcomparenumliterals">skip over this table</a></p>
<table id="comparenumliterals">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>x = 12L</code></td>
<td><code>x = 12</code></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><code>x = 0755</code></td>
<td><code>x = 0o755</code></td>
</tr>
</table>
<ol id="skipcomparenumliterals">
<li>...</li>
<li>...</li>
</ol>
</section>
<section>
<h2 id="renames"><code>sys.maxint</code></h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcomparerenames">skip over this table</a></p>
<table id="comparerenames">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>from sys import maxint</code></td>
<td><code>from sys import maxsize</code></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><pre><code>import sys
a_function(sys.maxint)</code></pre></td>
<td><pre><code>import sys
a_function(sys.maxsize)</code></pre></td>
</tr>
</table>
<ol id="skipcomparerenames">
<li>...</li>
<li>...</li>
</ol>
</section>
<section>
<h2 id="unicode"><code>unicode()</code> global function</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcompareunicode">skip over this table</a></p>
<table id="compareunicode">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>unicode(anything)</code></td>
<td><code>str(anything)</code></td>
</tr>
</table>
<ol id="skipcompareunicode">
<li>...</li>
</ol>
</section>
<section>
<h2 id="unicodeliteral">Unicode string literals</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcompareunicodeliteral">skip over this table</a></p>
<table id="compareunicodeliteral">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>u"PapayaWhip"</code></td>
<td><code>"PapayaWhip"</code></td>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>ur"PapayaWhip\foo"</code></td>
<td><code>r"PapayaWhip\foo"</code></td>
</tr>
</table>
<ol id="skipcompareunicodeliteral">
<li>...</li>
<li>...</li>
</ol>
</section>
<section>
<h2 id="callable"><code>callable()</code> global function</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcomparecallable">skip over this table</a></p>
<table id="comparecallable">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>callable(anything)</code></td>
<td><code>hasattr(anything, "__call__")</code></td>
</tr>
</table>
<ol id="skipcomparecallable">
<li>...</li>
</ol>
</section>
<section>
<h2 id="zip"><code>zip()</code> global function</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcomparezip">skip over this table</a></p>
<table id="comparezip">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>zip(a, b, c)</code></td>
<td><code>list(zip(a, b, c))</code></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><code>d.join(zip(a, b, c))</code></td>
<td><i>unchanged</i></td>
</tr>
</table>
<ol id="skipcomparezip">
<li>...</li>
<li>...</li>
</ol>
</section>
<section>
<h2 id="standarderror"><code>StandardError()</code> exception</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcomparestandarderror">skip over this table</a></p>
<table id="comparestandarderror">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>x = StandardError()</code></td>
<td><code>x = Exception()</code></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><code>x = StandardError(a, b, c)</code></td>
<td><code>x = Exception(a, b, c)</code></td>
</tr>
</table>
<ol id="skipcomparestandarderror">
<li>...</li>
<li>...</li>
</ol>
</section>
<section>
<h2 id="types"><code class="filename">types</code> module constants</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcomparetypes">skip over this table</a></p>
<table id="comparetypes">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>types.StringType</code></td>
<td><code>bytes</code></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><code>types.DictType</code></td>
<td><code>dict</code></td>
</tr>
<tr>
<th>&#x2462;</th>
<td><code>types.IntType</code></td>
<td><code>int</code></td>
</tr>
<tr>
<th>&#x2463;</th>
<td><code>types.LongType</code></td>
<td><code>int</code></td>
</tr>
<tr>
<th>&#x2464;</th>
<td><code>types.ListType</code></td>
<td><code>list</code></td>
</tr>
<tr>
<th>&#x2465;</th>
<td><code>types.NoneType</code></td>
<td><code>type(None)</code></td>
</tr>
</table>
<ol id="skipcomparetypes">
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
</ol>
</section>
<section>
<h2 id="isinstance"><code class="filename">isinstance</code> global function (3.1+)</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcompareisinstance">skip over this table</a></p>
<table id="compareisinstance">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>isinstance(x, (int, float, int))</code></td>
<td><code>isinstance(x, (int, float))</code></td>
</tr>
</table>
<ol id="skipcompareisinstance">
<li>...</li>
</ol>
</section>
<section>
<h2 id="basestring"><code>basestring</code> datatype</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcomparebasestring">skip over this table</a></p>
<table id="comparebasestring">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>isinstance(x, basestring)</code></td>
<td><code>isinstance(x, str)</code></td>
</tr>
</table>
<ol id="skipcomparebasestring">
<li>...</li>
</ol>
</section>
<section>
<h2 id="itertools"><code class="filename">itertools</code> module</h2>
<p>FIXME intro</p>
<table id="compareitertools">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>itertools.izip(a, b)</code></td>
<td><code>zip(a, b)</code></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><code>itertools.imap(a, b)</code></td>
<td><code>map(a, b)</code></td>
</tr>
<tr>
<th>&#x2462;</th>
<td><code>itertools.ifilter(a, b)</code></td>
<td><code>filter(a, b)</code></td>
</tr>
<tr>
<th>&#x2463;</th>
<td><code>itertools.ifilterfalse(a, b)</code></td>
<td><code>filterfalse(a, b)</code></td>
</tr>
<tr>
<th>&#x2464;</th>
<td><code>from itertools import imap, izip, foo</code></td>
<td><code>from itertools import foo</code></td>
</tr>
</table>
<ol id="skipcompareitertools">
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
</ol>
</section>
<section>
<h2 id="sys_exc"><code>sys.exc_type</code>, <code>sys.exc_value</code>, <code>sys.exc_traceback</code></h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcomparesys_exc">skip over this table</a></p>
<table id="comparesys_exc">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>sys.exc_type</code></td>
<td><code>sys.exc_info()[0]</code></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><code>sys.exc_value</code></td>
<td><code>sys.exc_info()[1]</code></td>
</tr>
<tr>
<th>&#x2462;</th>
<td><code>sys.exc_traceback</code></td>
<td><code>sys.exc_info()[2]</code></td>
</tr>
</table>
<ol id="skipcomparesys_exc">
<li>...</li>
<li>...</li>
<li>...</li>
</ol>
</section>
<section>
<h2 id="paren">List comprehensions over tuples</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcompareparen">skip over this table</a></p>
<table id="compareparen">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>[i for i in 1, 2]</code></td>
<td><code>[i for i in (1, 2)]</code></td>
</tr>
</table>
<ol id="skipcompareparen">
<li>...</li>
</ol>
</section>
<section>
<h2 id="getcwdu"><code>os.getcwdu()</code> function</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcomparegetcwdu">skip over this table</a></p>
<table id="comparegetcwdu">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>os.getcwdu()</code></td>
<td><code>os.getcwd()</code></td>
</tr>
</table>
<ol id="skipcomparegetcwdu">
<li>...</li>
</ol>
</section>
<section>
<h2 id="metaclass">Metaclasses</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcomparemetaclass">skip over this table</a></p>
<table id="comparemetaclass">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><pre><code>class Whip:
__metaclass__ = PapayaMeta</code></pre></td>
<td><pre><code>class Whip(metaclass=PapayaMeta):
pass</code></pre></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><pre><code>class Whip(Whipper):
__metaclass__ = PapayaMeta</code></pre></td>
<td><pre><code>class Whip(Whipper, metaclass=PapayaMeta):
pass</code></pre></td>
</tr>
</table>
<ol id="skipcomparemetaclass">
<li>...</li>
<li>...</li>
</ol>
</section>
<section>
<h2 id="set_literal"><code>set()</code> literals</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcompareset_literal">skip over this table</a></p>
<table id="compareset_literal">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>set([1, 2, 3])</code></td>
<td><code>{1, 2, 3}</code></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><code>set((1, 2, 3))</code></td>
<td><code>{1, 2, 3}</code></td>
</tr>
<tr>
<th>&#x2462;</th>
<td><code>set([i for i in a_sequence])</code></td>
<td><code>{i for i in a_sequence}</code></td>
</tr>
</table>
<ol id="skipcompareset_literal">
<li>...</li>
<li>...</li>
<li>...</li>
</ol>
</section>
<section>
<h2 id="buffer"><code>buffer()</code> global function</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcomparebuffer">skip over this table</a></p>
<table id="comparebuffer">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>x = buffer(y)</code></td>
<td><code>x = memoryview(y)</code></td>
</tr>
</table>
<ol id="skipcomparebuffer">
<li>...</li>
</ol>
</section>
<section>
<h2 id="wscomma">Whitespace around commas</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcomparewscomma">skip over this table</a></p>
<table id="comparewscomma">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><code>a ,b</code></td>
<td><code>a, b</code></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><code>{a :b}</code></td>
<td><code>{a: b}</code></td>
</tr>
</table>
<ol id="skipcomparewscomma">
<li>...</li>
<li>...</li>
</ol>
</section>
<section>
<h2 id="idioms">Common idioms</h2>
<p>FIXME intro</p>
<p><a class="skip" href="#skipcompareidioms">skip over this table</a></p>
<table id="compareidioms">
<tr>
<th>Notes</th>
<th>Python 2</th>
<th>Python 3</th>
</tr>
<tr>
<th>&#x2460;</th>
<td><pre><code>while 1:
do_stuff()</code></pre></td>
<td><pre><code>while True:
do_stuff()</code></pre></td>
</tr>
<tr>
<th>&#x2461;</th>
<td><code>type(x) == T</code></td>
<td><code>isinstance(x, T)</code></td>
</tr>
<tr>
<th>&#x2462;</th>
<td><code>type(x) is T</code></td>
<td><code>isinstance(x, T)</code></td>
</tr>
<tr>
<th>&#x2463;</th>
<td><pre><code>a_list = list(a_sequence)
a_list.sort()
do_stuff(a_list)</code></pre></td>
<td><pre><code>a_list = sorted(a_sequence)
do_stuff(a_list)</code></pre></td>
</tr>
</table>
<ol id="skipcompareidioms">
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
</ol>
</section>
<footer>
<p class="c">&copy; 2001-4, 2009 Mark Pilgrim, <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">CC-BY-3.0</a></p>
</footer>
</body>
</html>