From 06afedd27f1c8a8cae23860ac178dcd5cc329b98 Mon Sep 17 00:00:00 2001 From: Mark Pilgrim Date: Sat, 16 May 2009 01:06:48 -0400 Subject: [PATCH] various fixes in porting chapter [thanks G.P.] --- porting-code-to-python-3-with-2to3.html | 19 +++++++++++-------- table-of-contents.html | 2 +- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/porting-code-to-python-3-with-2to3.html b/porting-code-to-python-3-with-2to3.html index 7d64e62..ae0750c 100644 --- a/porting-code-to-python-3-with-2to3.html +++ b/porting-code-to-python-3-with-2to3.html @@ -219,7 +219,7 @@ import CGIHttpServer
  • The http.server module provides a basic HTTP server.

    urllib

    -

    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, urllib. +

    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, urllib.
    Notes Python 2 @@ -249,10 +249,10 @@ from urllib.error import HTTPError

    1. The old urllib module in Python 2 had a variety of functions, including urlopen() for fetching data and splittype(), splithost(), and splituser() for splitting a URL into its constituent parts. These functions have been reorganized more logically within the new urllib package. 2to3 will also change all calls to these functions so they use the new naming scheme. -
    2. The old urllib2 module in Python 2 has been folded into into the urllib package in Python 3. All your urllib2 favorites — the build_opener() method, Request objects, and HTTPBasicAuthHandler and friends — are still available. +
    3. The old urllib2 module in Python 2 has been folded into the urllib package in Python 3. All your urllib2 favorites — the build_opener() method, Request objects, and HTTPBasicAuthHandler and friends — are still available.
    4. The urllib.parse module in Python 3 contains all the parsing functions from the old urlparse module in Python 2.
    5. The urllib.robotparser module parses robots.txt files. -
    6. The FancyURLopener class, which handles HTTP redirects and other status codes, is still available in the new urllib.request module. The urlencode function has moved to urllib.parse. +
    7. The FancyURLopener class, which handles HTTP redirects and other status codes, is still available in the new urllib.request module. The urlencode() function has moved to urllib.parse.
    8. The Request object is still available in urllib.request, but constants like HTTPError have been moved to urllib.error.

    dbm

    @@ -407,7 +407,7 @@ for an_iterator in a_sequence_of_iterators:
  • If you have a function that returns an iterator, call the function and pass the result to the next() function. (The 2to3 script is smart enough to convert this properly.)
  • If you define your own class and mean to use it as an iterator, define the __next__() special method.
  • If you define your own class and just happen to have a method named next() that takes one or more arguments, 2to3 will not touch it. This class can not be used as an iterator, because its next() method takes arguments. -
  • This one is a bit tricky. If you have a local variable named next, then it takes precedence over the new global next() function. In this case, you need to call the iterator’s special __next()__ method to get the next item in the sequence. (Alternatively, you could also refactor the code so the local variable wasn’t named next, but 2to3 will not do that for you automatically.) +
  • This one is a bit tricky. If you have a local variable named next, then it takes precedence over the new global next() function. In this case, you need to call the iterator’s special __next__() method to get the next item in the sequence. (Alternatively, you could also refactor the code so the local variable wasn’t named next, but 2to3 will not do that for you automatically.)

    filter() global function

    In Python 2, the filter() function returned a list, the result of filtering a sequence through a function that returned True or False for each item in the sequence. In Python 3, the filter() function returns an iterator, not a list. @@ -478,7 +478,7 @@ for an_iterator in a_sequence_of_iterators:

    from functtools import reduce
     reduce(a, b, c)
    -
    +

    The version of 2to3 that shipped with Python 3.0 would not fix the reduce() function automatically. The fix first appeared in the 2to3 script that shipped with Python 3.1.

    apply() global function

    @@ -547,7 +547,7 @@ reduce(a, b, c) execfile("a_filename") exec(compile(open("a_filename").read(), "a_filename", "exec")) -
    +

    The version of 2to3 that shipped with Python 3.0 would not fix the execfile statement automatically. The fix first appeared in the 2to3 script that shipped with Python 3.1.

    repr literals (backticks)

    @@ -805,7 +805,7 @@ except: aClassInstance.aClassMethod.im_class aClassInstance.aClassMethod.self.__class__ -

    __nonzero__ special class attribute

    +

    __nonzero__ special method

    In Python 2, you could build your own classes that could be used in a boolean context. For example, you could instantiate the class and then use the instance in an if statement. To do this, you defined a special __nonzero__() method which returned True or False, and it was called whenever the instance was used in a boolean context. In Python 3, you can still do this, but the name of the method has changed to __bool__().
    Notes @@ -920,6 +920,9 @@ except: types.NoneType type(None)
    +

    +

    types.StringType gets mapped to bytes instead of str because a Python 2 “string” (not a Unicode string, just a regular string) is really just a sequence of bytes in a particular character encoding. +

    isinstance() global function (3.1+)

    The isinstance() function checks whether an object is an instance of a particular class or type. In Python 2, you could pass a tuple of types, and isinstance() would return True if the object was any of those types. In Python 3, you can still do this, but passing the same type twice is deprecated. @@ -930,7 +933,7 @@ except:
    isinstance(x, (int, float, int)) isinstance(x, (int, float))
    -

    +

    The version of 2to3 that shipped with Python 3.0 would not fix these cases of isinstance() automatically. The fix first appeared in the 2to3 script that shipped with Python 3.1.

    basestring datatype

    diff --git a/table-of-contents.html b/table-of-contents.html index 016747a..0a31f44 100644 --- a/table-of-contents.html +++ b/table-of-contents.html @@ -339,7 +339,7 @@ ul li ol{margin:0;padding:0 0 0 2.5em}
  • xreadlines() I/O method
  • lambda functions that take a tuple instead of multiple parameters
  • Special method attributes -
  • __nonzero__ special class attribute +
  • __nonzero__ special method
  • Octal literals
  • sys.maxint
  • callable() global function