Commits

cvs2svn  committed 3cfc395

This commit was manufactured by cvs2svn to create tag 'r22a3'.

  • Participants
  • Parent commits 38c12fa
  • Branches legacy-trunk
  • Tags v2.2a3

Comments (0)

Files changed (717)

File Demo/sgi/video/vcopy.py

-# Copy a video file, interactively, frame-by-frame.
-
-import sys
-import getopt
-from gl import *
-from DEVICE import *
-import VFile
-import string
-import imageop
-
-def report(time, iframe):
-	print 'Frame', iframe, ': t =', time
-
-def usage():
-	sys.stderr.write('usage: vcopy [-t type] [-m treshold] [-a] infile outfile\n')
-	sys.stderr.write('-t Convert to other type\n')
-	sys.stderr.write('-a Automatic\n')
-	sys.stderr.write('-m Convert grey to mono with treshold\n')
-	sys.stderr.write('-d Convert grey to mono with dithering\n')
-	sys.exit(2)
-
-def help():
-	print 'Command summary:'
-	print 'n   get next image from input'
-	print 'w   write current image to output'
-
-def main():
-	foreground()
-	opts, args = getopt.getopt(sys.argv[1:], 't:am:d')
-	if len(args) <> 2:
-		usage()
-	[ifile, ofile] = args
-	print 'open film ', ifile
-	ifilm = VFile.VinFile().init(ifile)
-	print 'open output ', ofile
-	ofilm = VFile.VoutFile().init(ofile)
-	
-	ofilm.setinfo(ifilm.getinfo())
-
-	use_grabber = 0
-	continuous = 0
-	tomono = 0
-	tomonodither = 0
-	for o, a in opts:
-		if o == '-t':
-			ofilm.format = a
-			use_grabber = 1
-		if o == '-a':
-			continuous = 1
-		if o == '-m':
-			if ifilm.format <> 'grey':
-				print '-m only supported for greyscale'
-				sys.exit(1)
-			tomono = 1
-			treshold = string.atoi(a)
-			ofilm.format = 'mono'
-		if o == '-d':
-			if ifilm.format <> 'grey':
-				print '-m only supported for greyscale'
-				sys.exit(1)
-			tomonodither = 1
-			ofilm.format = 'mono'
-			
-	ofilm.writeheader()
-	#
-	prefsize(ifilm.width, ifilm.height)
-	w = winopen(ifile)
-	qdevice(KEYBD)
-	qdevice(ESCKEY)
-	qdevice(WINQUIT)
-	qdevice(WINSHUT)
-	print 'qdevice calls done'
-	#
-	help()
-	#
-	time, data, cdata = ifilm.getnextframe()
-	ifilm.showframe(data, cdata)
-	iframe = 1
-	report(time, iframe)
-	#
-	while 1:
-		if continuous:
-			dev = KEYBD
-		else:
-			dev, val = qread()
-		if dev in (ESCKEY, WINQUIT, WINSHUT):
-			break
-		if dev == REDRAW:
-			reshapeviewport()
-		elif dev == KEYBD:
-			if continuous:
-				c = '0'
-			else:
-				c = chr(val)
-			#XXX Debug
-			if c == 'R':
-				c3i(255,0,0)
-				clear()
-			if c == 'G':
-				c3i(0,255,0)
-				clear()
-			if c == 'B':
-				c3i(0,0,255)
-				clear()
-			if c == 'w' or continuous:
-				if use_grabber:
-					data, cdata = ofilm.grabframe()
-				if tomono:
-					data = imageop.grey2mono(data, \
-						  ifilm.width, ifilm.height, \
-						  treshold)
-				if tomonodither:
-					data = imageop.dither2mono(data, \
-						  ifilm.width, ifilm.height)
-				ofilm.writeframe(time, data, cdata)
-				print 'Frame', iframe, 'written.'
-			if c == 'n' or continuous:
-				try:
-					time,data,cdata = ifilm.getnextframe()
-					ifilm.showframe(data, cdata)
-					iframe = iframe+1
-					report(time, iframe)
-				except EOFError:
-					print 'EOF'
-					if continuous:
-						break
-					ringbell()
-		elif dev == INPUTCHANGE:
-			pass
-		else:
-			print '(dev, val) =', (dev, val)
-	ofilm.close()
-
-main()

File Demo/sgi/video/vinfo.py

-from gl import *
-from GL import *
-from DEVICE import *
-import time
-import sys
-import getopt
-
-class Struct(): pass
-epoch = Struct()
-EndOfFile = 'End of file'
-bye = 'bye'
-
-def openvideo(filename):
-	f = open(filename, 'r')
-	line = f.readline()
-	if not line: raise EndOfFile
-	if line[:4] == 'CMIF': line = f.readline()
-	x = eval(line[:-1])
-	if len(x) == 3: w, h, pf = x
-	else: w, h = x; pf = 2
-	return f, w, h, pf
-
-def loadframe(f, w, h, pf):
-	line = f.readline()
-	if line == '':
-		raise EndOfFile
-	x = eval(line[:-1])
-	if type(x) == type(0) or type(x) == type(0.0):
-		tijd = x
-		if pf == 0:
-			size = w*h*4
-		else:
-			size = (w/pf) * (h/pf)
-	else:
-		tijd, size = x
-	f.seek(size, 1)
-	return tijd
-
-def main():
-	delta = 0
-	short = 0
-	try:
-		opts, names = getopt.getopt(sys.argv[1:], 'ds')
-	except getopt.error, msg:
-		sys.stderr.write(msg + '\n')
-		sys.stderr.write('usage: vinfo [-d] [-s] [file] ...\n')
-		sys.exit(2)
-	for opt, arg in opts:
-		if opt == '-d': delta = 1	# print delta between frames
-		elif opt == '-s': short = 1	# short: don't print times
-	if names == []:
-		names = ['film.video']
-	for name in names:
-	    try:
-		f, w, h, pf = openvideo(name)
-	    except:
-	    	sys.stderr.write(name + ': cannot open\n')
-	    	continue
-	    if pf == 0:
-	        size = w*h*4
-	    else:
-	        size = (w/pf) * (h/pf)
-	    print name, ':', w, 'x', h, '; pf =', pf, ', size =', size,
-	    if pf == 0:
-		    print '(color)',
-	    else:
-		    print '(' + `(w/pf)` + 'x' + `(h/pf)` + ')',
-		    if (w/pf)%4 <> 0: print '!!!',
-	    print
-	    num = 0
-	    try:
-	    	otijd = 0
-		while not short:
-		    try:
-			tijd = loadframe(f, w, h, pf)
-			if delta: print '\t' + `tijd-otijd`,
-			else: print '\t' + `tijd`,
-			otijd = tijd
-			num = num + 1
-			if num % 8 == 0:
-				print
-		    except EndOfFile:
-			raise bye
-	    except bye:
-		pass
-	    if num % 8 <> 0:
-		print
-	    f.close()
-
-main()

File Demo/sgi/video/vtime.py

-#
-# Module vtime - Keep virtual time between two nodes.
-#
-# We try for synchronised clocks by sending a packet of the for
-# (1,mytime,0) to the other side, and waiting (at most) a second for
-# a reply. This reply has the form (2,mytime,histime), and we can
-# estimate the time difference by defining histime to be exactly half-way
-# between the time we sent our message and got our reply. We send a
-# final (3,mynewtime,histime) message to allow the other side to do the
-# same computations.
-#
-# Note that the protocol suffers heavily from the 2-army problem.
-# It'll have to do until I can read up on time-sync protocols, though.
-#
-from socket import *
-import time
-
-MSGSIZE = 100
-MSGTIMEOUT = 1000
-
-recv_timeout = 'receive timeout'
-bad_connect = 'Bad connection'
-
-def timeavg(a,b):
-    return int((long(a)+b)/2L)
-def tryrecv(s):
-    cnt = 0
-    while 1:
-	if s.avail():
-	    return s.recvfrom(MSGSIZE)
-	time.millisleep(100)
-	cnt = cnt + 100
-	if cnt > MSGTIMEOUT:
-	    raise recv_timeout
-
-class VTime():
-    def init(self,(client,host,port)):
-	s = socket(AF_INET, SOCK_DGRAM)
-	host = gethostbyname(host)
-	localhost = gethostbyname(gethostname())
-	raddr = (host,port)
-	s.bind((localhost,port))
-	if client:
-	    #
-	    # We loop here because we want the *second* measurement
-	    # for accuracy
-	    for loopct in (0,2):
-		curtijd = time.millitimer()
-		check = `(loopct,curtijd,0)`
-		s.sendto(check,raddr)
-		while 1:
-		    try:
-			if loopct:
-			    data, other = s.recvfrom(MSGSIZE)
-			else:
-			    data, other = tryrecv(s)
-			newtijd = time.millitimer()
-			if other <> raddr:
-			    print 'Someone else syncing to us: ', other
-			    raise bad_connect
-			data = eval(data)
-			if data[:2] == (loopct+1,curtijd):
-			    break
-			if data[0] <> 2:
-			    print 'Illegal sync reply: ', data
-			    raise bad_connect
-		    except recv_timeout:
-			curtijd = time.millitimer()
-			check = `(loopct,curtijd,0)`
-			s.sendto(check,raddr)
-	    histime = data[2]
-	    s.sendto(`(4,newtijd,histime)`,raddr)
-	    mytime = timeavg(curtijd,newtijd)
-	    #mytime = curtijd
-	    self.timediff = histime - mytime
-	else:
-	    while 1:
-		data,other = s.recvfrom(MSGSIZE)
-		if other <> raddr:
-		    print 'Someone else syncing to us: ', other, ' Wanted ', raddr
-		    raise bad_connect
-		data = eval(data)
-		if data[0] in (0,2):
-		    curtijd = time.millitimer()
-		    s.sendto(`(data[0]+1,data[1],curtijd)`,raddr)
-		elif data[0] == 4:
-		    newtijd = time.millitimer()
-		    histime = data[1]
-		    mytime = timeavg(curtijd,newtijd)
-		    #mytime = curtijd
-		    self.timediff = histime-mytime
-		    break
-		else:
-		    print 'Funny data: ', data
-		    raise bad_connect
-	return self
-	#
-    def his2mine(self,tijd):
-	return tijd - self.timediff
-    #
-    def mine2his(self, tijd):
-	return tijd + self.timediff
-
-def test(clt, host, port):
-    xx = VTime().init(clt,host,port)
-    print 'Time diff: ', xx.his2mine(0)

File Doc/whatsnew/whatsnew20.tex

-\documentclass{howto}
-
-% $Id$
-
-\title{What's New in Python 2.0}
-\release{1.01}
-\author{A.M. Kuchling and Moshe Zadka}
-\authoraddress{\email{amk1@bigfoot.com}, \email{moshez@math.huji.ac.il} }
-\begin{document}
-\maketitle\tableofcontents
-
-\section{Introduction}
-
-A new release of Python, version 2.0, will be released some time this
-autumn.  Beta versions are already available from
-\url{http://www.pythonlabs.com/products/python2.0/}.  This article
-covers the exciting new features in 2.0, highlights some other useful
-changes, and points out a few incompatible changes that may require
-rewriting code.
-
-Python's development never completely stops between releases, and a
-steady flow of bug fixes and improvements are always being submitted.
-A host of minor fixes, a few optimizations, additional docstrings, and
-better error messages went into 2.0; to list them all would be
-impossible, but they're certainly significant.  Consult the
-publicly-available CVS logs if you want to see the full list.  This
-progress is due to the five developers working for 
-PythonLabs are now getting paid to spend their days fixing bugs,
-and also due to the improved communication resulting 
-from moving to SourceForge.
-
-% ======================================================================
-\section{What About Python 1.6?}
-
-Python 1.6 can be thought of as the Contractual Obligations Python
-release.  After the core development team left CNRI in May 2000, CNRI
-requested that a 1.6 release be created, containing all the work on
-Python that had been performed at CNRI.  Python 1.6 therefore
-represents the state of the CVS tree as of May 2000, with the most
-significant new feature being Unicode support.  Development continued
-after May, of course, so the 1.6 tree received a few fixes to ensure
-that it's forward-compatible with Python 2.0.  1.6 is therefore part
-of Python's evolution, and not a side branch.
-
-So, should you take much interest in Python 1.6?  Probably not.  The
-1.6final and 2.0beta1 releases were made on the same day (September 5,
-2000), the plan being to finalize Python 2.0 within a month or so.  If
-you have applications to maintain, there seems little point in
-breaking things by moving to 1.6, fixing them, and then having another
-round of breakage within a month by moving to 2.0; you're better off
-just going straight to 2.0.  Most of the really interesting features
-described in this document are only in 2.0, because a lot of work was
-done between May and September.  
-
-% ======================================================================
-\section{New Development Process}
-
-The most important change in Python 2.0 may not be to the code at all,
-but to how Python is developed: in May 2000 the Python developers
-began using the tools made available by SourceForge for storing 
-source code, tracking bug reports, and managing the queue of patch
-submissions.  To report bugs or submit patches for Python 2.0, use the
-bug tracking and patch manager tools available from Python's project
-page, located at \url{http://sourceforge.net/projects/python/}.
-
-The most important of the services now hosted at SourceForge is the
-Python CVS tree, the version-controlled repository containing the
-source code for Python.  Previously, there were roughly 7 or so people
-who had write access to the CVS tree, and all patches had to be
-inspected and checked in by one of the people on this short list.
-Obviously, this wasn't very scalable.  By moving the CVS tree to
-SourceForge, it became possible to grant write access to more people;
-as of September 2000 there were 27 people able to check in changes, a
-fourfold increase.  This makes possible large-scale changes that
-wouldn't be attempted if they'd have to be filtered through the small
-group of core developers.  For example, one day Peter Schneider-Kamp
-took it into his head to drop K\&R C compatibility and convert the C
-source for Python to ANSI C. After getting approval on the python-dev
-mailing list, he launched into a flurry of checkins that lasted about
-a week, other developers joined in to help, and the job was done.  If
-there were only 5 people with write access, probably that task would
-have been viewed as ``nice, but not worth the time and effort needed''
-and it would never have gotten done.
-
-The shift to using SourceForge's services has resulted in a remarkable
-increase in the speed of development.  Patches now get submitted,
-commented on, revised by people other than the original submitter, and
-bounced back and forth between people until the patch is deemed worth
-checking in.  Bugs are tracked in one central location and can be
-assigned to a specific person for fixing, and we can count the number
-of open bugs to measure progress.  This didn't come without a cost:
-developers now have more e-mail to deal with, more mailing lists to
-follow, and special tools had to be written for the new environment.
-For example, SourceForge sends default patch and bug notification
-e-mail messages that are completely unhelpful, so Ka-Ping Yee wrote an
-HTML screen-scraper that sends more useful messages.
-
-The ease of adding code caused a few initial growing pains, such as
-code was checked in before it was ready or without getting clear
-agreement from the developer group.  The approval process that has
-emerged is somewhat similar to that used by the Apache group.
-Developers can vote +1, +0, -0, or -1 on a patch; +1 and -1 denote
-acceptance or rejection, while +0 and -0 mean the developer is mostly
-indifferent to the change, though with a slight positive or negative
-slant.  The most significant change from the Apache model is that the
-voting is essentially advisory, letting Guido van Rossum, who has
-Benevolent Dictator For Life status, know what the general opinion is.
-He can still ignore the result of a vote, and approve or
-reject a change even if the community disagrees with him.
-
-Producing an actual patch is the last step in adding a new feature,
-and is usually easy compared to the earlier task of coming up with a
-good design.  Discussions of new features can often explode into
-lengthy mailing list threads, making the discussion hard to follow,
-and no one can read every posting to python-dev.  Therefore, a
-relatively formal process has been set up to write Python Enhancement
-Proposals (PEPs), modelled on the Internet RFC process.  PEPs are
-draft documents that describe a proposed new feature, and are
-continually revised until the community reaches a consensus, either
-accepting or rejecting the proposal.  Quoting from the introduction to
-PEP 1, ``PEP Purpose and Guidelines'':
-
-\begin{quotation}
-    PEP stands for Python Enhancement Proposal.  A PEP is a design
-    document providing information to the Python community, or
-    describing a new feature for Python.  The PEP should provide a
-    concise technical specification of the feature and a rationale for
-    the feature.
-
-    We intend PEPs to be the primary mechanisms for proposing new
-    features, for collecting community input on an issue, and for
-    documenting the design decisions that have gone into Python.  The
-    PEP author is responsible for building consensus within the
-    community and documenting dissenting opinions.
-\end{quotation}
-
-Read the rest of PEP 1 for the details of the PEP editorial process,
-style, and format.  PEPs are kept in the Python CVS tree on
-SourceForge, though they're not part of the Python 2.0 distribution,
-and are also available in HTML form from
-\url{http://python.sourceforge.net/peps/}.  As of September 2000,
-there are 25 PEPS, ranging from PEP 201, ``Lockstep Iteration'', to
-PEP 225, ``Elementwise/Objectwise Operators''.
-
-% ======================================================================
-\section{Unicode}
-
-The largest new feature in Python 2.0 is a new fundamental data type:
-Unicode strings.  Unicode uses 16-bit numbers to represent characters
-instead of the 8-bit number used by ASCII, meaning that 65,536
-distinct characters can be supported.
-
-The final interface for Unicode support was arrived at through
-countless often-stormy discussions on the python-dev mailing list, and
-mostly implemented by Marc-Andr\'e Lemburg, based on a Unicode string
-type implementation by Fredrik Lundh.  A detailed explanation of the
-interface is in the file \file{Misc/unicode.txt} in the Python source
-distribution; it's also available on the Web at
-\url{http://starship.python.net/crew/lemburg/unicode-proposal.txt}.
-This article will simply cover the most significant points about the Unicode 
-interfaces.
-
-In Python source code, Unicode strings are written as
-\code{u"string"}.  Arbitrary Unicode characters can be written using a
-new escape sequence, \code{\e u\var{HHHH}}, where \var{HHHH} is a
-4-digit hexadecimal number from 0000 to FFFF.  The existing
-\code{\e x\var{HHHH}} escape sequence can also be used, and octal
-escapes can be used for characters up to U+01FF, which is represented
-by \code{\e 777}.
-
-Unicode strings, just like regular strings, are an immutable sequence
-type.  They can be indexed and sliced, but not modified in place.
-Unicode strings have an \method{encode( \optional{encoding} )} method
-that returns an 8-bit string in the desired encoding.  Encodings are
-named by strings, such as \code{'ascii'}, \code{'utf-8'},
-\code{'iso-8859-1'}, or whatever.  A codec API is defined for
-implementing and registering new encodings that are then available
-throughout a Python program.  If an encoding isn't specified, the
-default encoding is usually 7-bit ASCII, though it can be changed for
-your Python installation by calling the
-\function{sys.setdefaultencoding(\var{encoding})} function in a
-customised version of \file{site.py}.
-
-Combining 8-bit and Unicode strings always coerces to Unicode, using
-the default ASCII encoding; the result of \code{'a' + u'bc'} is
-\code{u'abc'}.
-
-New built-in functions have been added, and existing built-ins
-modified to support Unicode:
-
-\begin{itemize}
-\item \code{unichr(\var{ch})} returns a Unicode string 1 character
-long, containing the character \var{ch}.
-
-\item \code{ord(\var{u})}, where \var{u} is a 1-character regular or Unicode string, returns the number of the character as an integer.
-
-\item \code{unicode(\var{string} \optional{, \var{encoding}} 
-\optional{, \var{errors}} ) } creates a Unicode string from an 8-bit
-string.  \code{encoding} is a string naming the encoding to use.
-The \code{errors} parameter specifies the treatment of characters that
-are invalid for the current encoding; passing \code{'strict'} as the
-value causes an exception to be raised on any encoding error, while
-\code{'ignore'} causes errors to be silently ignored and
-\code{'replace'} uses U+FFFD, the official replacement character, in
-case of any problems.
-
-\item The \keyword{exec} statement, and various built-ins such as
-\code{eval()}, \code{getattr()}, and \code{setattr()} will also
-accept Unicode strings as well as regular strings.  (It's possible
-that the process of fixing this missed some built-ins; if you find a
-built-in function that accepts strings but doesn't accept Unicode
-strings at all, please report it as a bug.)
-
-\end{itemize}
-
-A new module, \module{unicodedata}, provides an interface to Unicode
-character properties.  For example, \code{unicodedata.category(u'A')}
-returns the 2-character string 'Lu', the 'L' denoting it's a letter,
-and 'u' meaning that it's uppercase.
-\code{u.bidirectional(u'\e x0660')} returns 'AN', meaning that U+0660 is
-an Arabic number.
-
-The \module{codecs} module contains functions to look up existing encodings
-and register new ones.  Unless you want to implement a
-new encoding, you'll most often use the
-\function{codecs.lookup(\var{encoding})} function, which returns a
-4-element tuple: \code{(\var{encode_func},
-\var{decode_func}, \var{stream_reader}, \var{stream_writer})}.
-
-\begin{itemize}
-\item \var{encode_func} is a function that takes a Unicode string, and
-returns a 2-tuple \code{(\var{string}, \var{length})}.  \var{string}
-is an 8-bit string containing a portion (perhaps all) of the Unicode
-string converted into the given encoding, and \var{length} tells you
-how much of the Unicode string was converted.
-
-\item \var{decode_func} is the opposite of \var{encode_func}, taking
-an 8-bit string and returning a 2-tuple \code{(\var{ustring},
-\var{length})}, consisting of the resulting Unicode string
-\var{ustring} and the integer \var{length} telling how much of the
-8-bit string was consumed.
-
-\item \var{stream_reader} is a class that supports decoding input from
-a stream.  \var{stream_reader(\var{file_obj})} returns an object that
-supports the \method{read()}, \method{readline()}, and
-\method{readlines()} methods.  These methods will all translate from
-the given encoding and return Unicode strings.
-
-\item \var{stream_writer}, similarly, is a class that supports
-encoding output to a stream.  \var{stream_writer(\var{file_obj})}
-returns an object that supports the \method{write()} and
-\method{writelines()} methods.  These methods expect Unicode strings,
-translating them to the given encoding on output.
-\end{itemize}
-
-For example, the following code writes a Unicode string into a file, 
-encoding it as UTF-8:
-
-\begin{verbatim}
-import codecs
-
-unistr = u'\u0660\u2000ab ...'
-
-(UTF8_encode, UTF8_decode,
- UTF8_streamreader, UTF8_streamwriter) = codecs.lookup('UTF-8')
-
-output = UTF8_streamwriter( open( '/tmp/output', 'wb') )
-output.write( unistr )
-output.close()
-\end{verbatim}
-
-The following code would then read UTF-8 input from the file:
-
-\begin{verbatim}
-input = UTF8_streamreader( open( '/tmp/output', 'rb') )
-print repr(input.read())
-input.close()
-\end{verbatim}
-
-Unicode-aware regular expressions are available through the
-\module{re} module, which has a new underlying implementation called
-SRE written by Fredrik Lundh of Secret Labs AB. 
-
-A \code{-U} command line option was added which causes the Python
-compiler to interpret all string literals as Unicode string literals.
-This is intended to be used in testing and future-proofing your Python
-code, since some future version of Python may drop support for 8-bit
-strings and provide only Unicode strings.
-
-% ======================================================================
-\section{List Comprehensions}
-
-Lists are a workhorse data type in Python, and many programs
-manipulate a list at some point.  Two common operations on lists are
-to loop over them, and either pick out the elements that meet a
-certain criterion, or apply some function to each element.  For
-example, given a list of strings, you might want to pull out all the
-strings containing a given substring, or strip off trailing whitespace
-from each line.  
-
-The existing \function{map()} and \function{filter()} functions can be
-used for this purpose, but they require a function as one of their
-arguments.  This is fine if there's an existing built-in function that
-can be passed directly, but if there isn't, you have to create a
-little function to do the required work, and Python's scoping rules
-make the result ugly if the little function needs additional
-information.  Take the first example in the previous paragraph,
-finding all the strings in the list containing a given substring.  You
-could write the following to do it:
-
-\begin{verbatim}
-# Given the list L, make a list of all strings 
-# containing the substring S.
-sublist = filter( lambda s, substring=S: 
-                     string.find(s, substring) != -1,
-	          L)
-\end{verbatim}
-
-Because of Python's scoping rules, a default argument is used so that
-the anonymous function created by the \keyword{lambda} statement knows
-what substring is being searched for.  List comprehensions make this
-cleaner:
-
-\begin{verbatim}
-sublist = [ s for s in L if string.find(s, S) != -1 ]
-\end{verbatim}
-
-List comprehensions have the form:
-
-\begin{verbatim}
-[ expression for expr in sequence1 
-             for expr2 in sequence2 ...
-	     for exprN in sequenceN
-             if condition
-\end{verbatim}
-
-The \keyword{for}...\keyword{in} clauses contain the sequences to be
-iterated over.  The sequences do not have to be the same length,
-because they are \emph{not} iterated over in parallel, but
-from left to right; this is explained more clearly in the following
-paragraphs.  The elements of the generated list will be the successive
-values of \var{expression}.  The final \keyword{if} clause is
-optional; if present, \var{expression} is only evaluated and added to
-the result if \var{condition} is true.
-
-To make the semantics very clear, a list comprehension is equivalent
-to the following Python code:
-
-\begin{verbatim}
-for expr1 in sequence1:
-    for expr2 in sequence2:
-    ...
-        for exprN in sequenceN:
-             if (condition):
-                  # Append the value of 
-                  # the expression to the 
-                  # resulting list.
-\end{verbatim}
-
-This means that when there are \keyword{for}...\keyword{in} clauses,
-the resulting list will be equal to the product of the lengths of all
-the sequences.  If you have two lists of length 3, the output list is
-9 elements long:
-
-\begin{verbatim}
-seq1 = 'abc'
-seq2 = (1,2,3)
->>> [ (x,y) for x in seq1 for y in seq2]
-[('a', 1), ('a', 2), ('a', 3), ('b', 1), ('b', 2), ('b', 3), ('c', 1),
-('c', 2), ('c', 3)]
-\end{verbatim}
-
-To avoid introducing an ambiguity into Python's grammar, if
-\var{expression} is creating a tuple, it must be surrounded with
-parentheses.  The first list comprehension below is a syntax error,
-while the second one is correct:
-
-\begin{verbatim}
-# Syntax error
-[ x,y for x in seq1 for y in seq2]
-# Correct
-[ (x,y) for x in seq1 for y in seq2]
-\end{verbatim}
-
-The idea of list comprehensions originally comes from the functional
-programming language Haskell (\url{http://www.haskell.org}).  Greg
-Ewing argued most effectively for adding them to Python and wrote the
-initial list comprehension patch, which was then discussed for a
-seemingly endless time on the python-dev mailing list and kept
-up-to-date by Skip Montanaro.
-
-% ======================================================================
-\section{Augmented Assignment}
-
-Augmented assignment operators, another long-requested feature, have
-been added to Python 2.0.  Augmented assignment operators include
-\code{+=}, \code{-=}, \code{*=}, and so forth.  For example, the
-statement \code{a += 2} increments the value of the variable 
-\code{a} by 2, equivalent to the slightly lengthier \code{a = a + 2}.
-
-The full list of supported assignment operators is \code{+=},
-\code{-=}, \code{*=}, \code{/=}, \code{\%=}, \code{**=}, \code{\&=},
-\code{|=}, \verb|^=|, \code{>>=}, and \code{<<=}.  Python classes can
-override the augmented assignment operators by defining methods named
-\method{__iadd__}, \method{__isub__}, etc.  For example, the following
-\class{Number} class stores a number and supports using += to create a
-new instance with an incremented value.
-
-\begin{verbatim}
-class Number:
-    def __init__(self, value):
-        self.value = value
-    def __iadd__(self, increment):
-	return Number( self.value + increment)
-
-n = Number(5)
-n += 3
-print n.value
-\end{verbatim}
-
-The \method{__iadd__} special method is called with the value of the
-increment, and should return a new instance with an appropriately
-modified value; this return value is bound as the new value of the
-variable on the left-hand side. 
-
-Augmented assignment operators were first introduced in the C
-programming language, and most C-derived languages, such as
-\program{awk}, C++, Java, Perl, and PHP also support them.  The augmented
-assignment patch was implemented by Thomas Wouters.
-
-% ======================================================================
-\section{String Methods}
-
-Until now string-manipulation functionality was in the \module{string}
-module, which was usually a front-end for the \module{strop}
-module written in C.  The addition of Unicode posed a difficulty for
-the \module{strop} module, because the functions would all need to be
-rewritten in order to accept either 8-bit or Unicode strings.  For
-functions such as \function{string.replace()}, which takes 3 string
-arguments, that means eight possible permutations, and correspondingly
-complicated code.
-
-Instead, Python 2.0 pushes the problem onto the string type, making
-string manipulation functionality available through methods on both
-8-bit strings and Unicode strings.  
-
-\begin{verbatim}
->>> 'andrew'.capitalize()
-'Andrew'
->>> 'hostname'.replace('os', 'linux')
-'hlinuxtname'
->>> 'moshe'.find('sh')
-2
-\end{verbatim}
-
-One thing that hasn't changed, a noteworthy April Fools' joke
-notwithstanding, is that Python strings are immutable. Thus, the
-string methods return new strings, and do not modify the string on
-which they operate.
-
-The old \module{string} module is still around for backwards
-compatibility, but it mostly acts as a front-end to the new string
-methods.
-
-Two methods which have no parallel in pre-2.0 versions, although they
-did exist in JPython for quite some time, are \method{startswith()}
-and \method{endswith}.  \code{s.startswith(t)} is equivalent to \code{s[:len(t)]
-== t}, while \code{s.endswith(t)} is equivalent to \code{s[-len(t):] == t}.
-
-One other method which deserves special mention is \method{join}.  The
-\method{join} method of a string receives one parameter, a sequence of
-strings, and is equivalent to the \function{string.join} function from
-the old \module{string} module, with the arguments reversed. In other
-words, \code{s.join(seq)} is equivalent to the old
-\code{string.join(seq, s)}.
-
-% ======================================================================
-\section{Garbage Collection of Cycles}
-
-The C implementation of Python uses reference counting to implement
-garbage collection.  Every Python object maintains a count of the
-number of references pointing to itself, and adjusts the count as
-references are created or destroyed.  Once the reference count reaches
-zero, the object is no longer accessible, since you need to have a
-reference to an object to access it, and if the count is zero, no
-references exist any longer.  
-
-Reference counting has some pleasant properties: it's easy to
-understand and implement, and the resulting implementation is
-portable, fairly fast, and reacts well with other libraries that
-implement their own memory handling schemes.  The major problem with
-reference counting is that it sometimes doesn't realise that objects
-are no longer accessible, resulting in a memory leak.  This happens
-when there are cycles of references.
-
-Consider the simplest possible cycle, 
-a class instance which has a reference to itself:
-
-\begin{verbatim}
-instance = SomeClass()
-instance.myself = instance
-\end{verbatim}
-
-After the above two lines of code have been executed, the reference
-count of \code{instance} is 2; one reference is from the variable
-named \samp{'instance'}, and the other is from the \samp{myself}
-attribute of the instance.  
-
-If the next line of code is \code{del instance}, what happens?  The
-reference count of \code{instance} is decreased by 1, so it has a
-reference count of 1; the reference in the \samp{myself} attribute
-still exists.  Yet the instance is no longer accessible through Python
-code, and it could be deleted.  Several objects can participate in a
-cycle if they have references to each other, causing all of the
-objects to be leaked.
-
-Python 2.0 fixes this problem by periodically executing a cycle
-detection algorithm which looks for inaccessible cycles and deletes
-the objects involved.  A new \module{gc} module provides functions to
-perform a garbage collection, obtain debugging statistics, and tuning
-the collector's parameters.
-
-Running the cycle detection algorithm takes some time, and therefore
-will result in some additional overhead.  It is hoped that after we've
-gotten experience with the cycle collection from using 2.0, Python 2.1
-will be able to minimize the overhead with careful tuning.  It's not
-yet obvious how much performance is lost, because benchmarking this is
-tricky and depends crucially on how often the program creates and
-destroys objects.  The detection of cycles can be disabled when Python
-is compiled, if you can't afford even a tiny speed penalty or suspect
-that the cycle collection is buggy, by specifying the
-\samp{--without-cycle-gc} switch when running the \file{configure}
-script.
-
-Several people tackled this problem and contributed to a solution.  An
-early implementation of the cycle detection approach was written by
-Toby Kelsey.  The current algorithm was suggested by Eric Tiedemann
-during a visit to CNRI, and Guido van Rossum and Neil Schemenauer
-wrote two different implementations, which were later integrated by
-Neil.  Lots of other people offered suggestions along the way; the
-March 2000 archives of the python-dev mailing list contain most of the
-relevant discussion, especially in the threads titled ``Reference
-cycle collection for Python'' and ``Finalization again''.
-
-% ======================================================================
-\section{Other Core Changes}
-
-Various minor changes have been made to Python's syntax and built-in
-functions.  None of the changes are very far-reaching, but they're
-handy conveniences.
-
-\subsection{Minor Language Changes}
-
-A new syntax makes it more convenient to call a given function
-with a tuple of arguments and/or a dictionary of keyword arguments.
-In Python 1.5 and earlier, you'd use the \function{apply()}
-built-in function: \code{apply(f, \var{args}, \var{kw})} calls the
-function \function{f()} with the argument tuple \var{args} and the
-keyword arguments in the dictionary \var{kw}.  \function{apply()} 
-is the same in 2.0, but thanks to a patch from
-Greg Ewing, \code{f(*\var{args}, **\var{kw})} as a shorter
-and clearer way to achieve the same effect.  This syntax is
-symmetrical with the syntax for defining functions:
-
-\begin{verbatim}
-def f(*args, **kw):
-    # args is a tuple of positional args,
-    # kw is a dictionary of keyword args
-    ...
-\end{verbatim}
-
-The \keyword{print} statement can now have its output directed to a
-file-like object by following the \keyword{print} with 
-\verb|>> file|, similar to the redirection operator in Unix shells.
-Previously you'd either have to use the \method{write()} method of the
-file-like object, which lacks the convenience and simplicity of
-\keyword{print}, or you could assign a new value to 
-\code{sys.stdout} and then restore the old value.  For sending output to standard error,
-it's much easier to write this:
-
-\begin{verbatim}
-print >> sys.stderr, "Warning: action field not supplied"
-\end{verbatim}
-
-Modules can now be renamed on importing them, using the syntax
-\code{import \var{module} as \var{name}} or \code{from \var{module}
-import \var{name} as \var{othername}}.  The patch was submitted by
-Thomas Wouters.
-
-A new format style is available when using the \code{\%} operator;
-'\%r' will insert the \function{repr()} of its argument.  This was
-also added from symmetry considerations, this time for symmetry with
-the existing '\%s' format style, which inserts the \function{str()} of
-its argument.  For example, \code{'\%r \%s' \% ('abc', 'abc')} returns a
-string containing \verb|'abc' abc|.
-
-Previously there was no way to implement a class that overrode
-Python's built-in \keyword{in} operator and implemented a custom
-version.  \code{\var{obj} in \var{seq}} returns true if \var{obj} is
-present in the sequence \var{seq}; Python computes this by simply
-trying every index of the sequence until either \var{obj} is found or
-an \exception{IndexError} is encountered.  Moshe Zadka contributed a
-patch which adds a \method{__contains__} magic method for providing a
-custom implementation for \keyword{in}. Additionally, new built-in
-objects written in C can define what \keyword{in} means for them via a
-new slot in the sequence protocol.
-
-Earlier versions of Python used a recursive algorithm for deleting
-objects.  Deeply nested data structures could cause the interpreter to
-fill up the C stack and crash; Christian Tismer rewrote the deletion
-logic to fix this problem.  On a related note, comparing recursive
-objects recursed infinitely and crashed; Jeremy Hylton rewrote the
-code to no longer crash, producing a useful result instead.  For
-example, after this code:
-
-\begin{verbatim}
-a = []
-b = []
-a.append(a)
-b.append(b)
-\end{verbatim}
-
-The comparison \code{a==b} returns true, because the two recursive
-data structures are isomorphic. See the thread ``trashcan
-and PR\#7'' in the April 2000 archives of the python-dev mailing list
-for the discussion leading up to this implementation, and some useful
-relevant links.  
-% Starting URL:
-% http://www.python.org/pipermail/python-dev/2000-April/004834.html
-
-Note that comparisons can now also raise exceptions. In earlier
-versions of Python, a comparison operation such as \code{cmp(a,b)}
-would always produce an answer, even if a user-defined
-\method{__cmp__} method encountered an error, since the resulting
-exception would simply be silently swallowed.
-
-Work has been done on porting Python to 64-bit Windows on the Itanium
-processor, mostly by Trent Mick of ActiveState.  (Confusingly,
-\code{sys.platform} is still \code{'win32'} on Win64 because it seems
-that for ease of porting, MS Visual C++ treats code as 32 bit on Itanium.)
-PythonWin also supports Windows CE; see the Python CE page at
-\url{http://starship.python.net/crew/mhammond/ce/} for more
-information.
-
-Another new platform is Darwin/MacOS X; inital support for it is in
-Python 2.0.  Dynamic loading works, if you specify ``configure
---with-dyld --with-suffix=.x''.  Consult the README in the Python
-source distribution for more instructions.
-
-An attempt has been made to alleviate one of Python's warts, the
-often-confusing \exception{NameError} exception when code refers to a
-local variable before the variable has been assigned a value.  For
-example, the following code raises an exception on the \keyword{print}
-statement in both 1.5.2 and 2.0; in 1.5.2 a \exception{NameError}
-exception is raised, while 2.0 raises a new
-\exception{UnboundLocalError} exception.
-\exception{UnboundLocalError} is a subclass of \exception{NameError},
-so any existing code that expects \exception{NameError} to be raised
-should still work.
-
-\begin{verbatim}
-def f():
-    print "i=",i
-    i = i + 1 
-f()
-\end{verbatim}
-
-Two new exceptions, \exception{TabError} and
-\exception{IndentationError}, have been introduced.  They're both
-subclasses of \exception{SyntaxError}, and are raised when Python code
-is found to be improperly indented.
-
-\subsection{Changes to Built-in Functions}
-
-A new built-in, \function{zip(\var{seq1}, \var{seq2}, ...)}, has been
-added.  \function{zip()} returns a list of tuples where each tuple
-contains the i-th element from each of the argument sequences.  The
-difference between \function{zip()} and \code{map(None, \var{seq1},
-\var{seq2})} is that \function{map()} pads the sequences with
-\code{None} if the sequences aren't all of the same length, while
-\function{zip()} truncates the returned list to the length of the
-shortest argument sequence.
-
-The \function{int()} and \function{long()} functions now accept an
-optional ``base'' parameter when the first argument is a string.
-\code{int('123', 10)} returns 123, while \code{int('123', 16)} returns
-291.  \code{int(123, 16)} raises a \exception{TypeError} exception
-with the message ``can't convert non-string with explicit base''.
-
-A new variable holding more detailed version information has been
-added to the \module{sys} module.  \code{sys.version_info} is a tuple
-\code{(\var{major}, \var{minor}, \var{micro}, \var{level},
-\var{serial})} For example, in a hypothetical 2.0.1beta1,
-\code{sys.version_info} would be \code{(2, 0, 1, 'beta', 1)}.
-\var{level} is a string such as \code{"alpha"}, \code{"beta"}, or
-\code{"final"} for a final release.
-
-Dictionaries have an odd new method, \method{setdefault(\var{key},
-\var{default})}, which behaves similarly to the existing
-\method{get()} method.  However, if the key is missing,
-\method{setdefault()} both returns the value of \var{default} as
-\method{get()} would do, and also inserts it into the dictionary as
-the value for \var{key}.  Thus, the following lines of code:
-
-\begin{verbatim}
-if dict.has_key( key ): return dict[key]
-else: 
-    dict[key] = []
-    return dict[key]
-\end{verbatim}
-
-can be reduced to a single \code{return dict.setdefault(key, [])} statement.
-
-The interpreter sets a maximum recursion depth in order to catch
-runaway recursion before filling the C stack and causing a core dump
-or GPF..  Previously this limit was fixed when you compiled Python,
-but in 2.0 the maximum recursion depth can be read and modified using
-\function{sys.getrecursionlimit} and \function{sys.setrecursionlimit}.
-The default value is 1000, and a rough maximum value for a given
-platform can be found by running a new script,
-\file{Misc/find_recursionlimit.py}.
-
-% ======================================================================
-\section{Porting to 2.0}
-
-New Python releases try hard to be compatible with previous releases,
-and the record has been pretty good.  However, some changes are
-considered useful enough, usually because they fix initial design decisions that
-turned out to be actively mistaken, that breaking backward compatibility
-can't always be avoided.  This section lists the changes in Python 2.0
-that may cause old Python code to break.
-
-The change which will probably break the most code is tightening up
-the arguments accepted by some methods.  Some methods would take
-multiple arguments and treat them as a tuple, particularly various
-list methods such as \method{.append()} and \method{.insert()}.
-In earlier versions of Python, if \code{L} is a list, \code{L.append(
-1,2 )} appends the tuple \code{(1,2)} to the list.  In Python 2.0 this
-causes a \exception{TypeError} exception to be raised, with the
-message: 'append requires exactly 1 argument; 2 given'.  The fix is to
-simply add an extra set of parentheses to pass both values as a tuple: 
-\code{L.append( (1,2) )}.
-
-The earlier versions of these methods were more forgiving because they
-used an old function in Python's C interface to parse their arguments;
-2.0 modernizes them to use \function{PyArg_ParseTuple}, the current
-argument parsing function, which provides more helpful error messages
-and treats multi-argument calls as errors.  If you absolutely must use
-2.0 but can't fix your code, you can edit \file{Objects/listobject.c}
-and define the preprocessor symbol \code{NO_STRICT_LIST_APPEND} to
-preserve the old behaviour; this isn't recommended.
-
-Some of the functions in the \module{socket} module are still
-forgiving in this way.  For example, \function{socket.connect(
-('hostname', 25) )} is the correct form, passing a tuple representing
-an IP address, but \function{socket.connect( 'hostname', 25 )} also
-works. \function{socket.connect_ex()} and \function{socket.bind()} are
-similarly easy-going.  2.0alpha1 tightened these functions up, but
-because the documentation actually used the erroneous multiple
-argument form, many people wrote code which would break with the
-stricter checking.  GvR backed out the changes in the face of public
-reaction, so for the \module{socket} module, the documentation was
-fixed and the multiple argument form is simply marked as deprecated;
-it \emph{will} be tightened up again in a future Python version.
-
-The \code{\e x} escape in string literals now takes exactly 2 hex
-digits.  Previously it would consume all the hex digits following the
-'x' and take the lowest 8 bits of the result, so \code{\e x123456} was
-equivalent to \code{\e x56}.
-
-The \exception{AttributeError} exception has a more friendly error message,
-whose text will be something like \code{'Spam' instance has no attribute 'eggs'}.
-Previously the error message was just the missing attribute name \code{eggs}, and 
-code written to take advantage of this fact will break in 2.0.
-
-Some work has been done to make integers and long integers a bit more
-interchangeable.  In 1.5.2, large-file support was added for Solaris,
-to allow reading files larger than 2Gb; this made the \method{tell()}
-method of file objects return a long integer instead of a regular
-integer.  Some code would subtract two file offsets and attempt to use
-the result to multiply a sequence or slice a string, but this raised a
-\exception{TypeError}.  In 2.0, long integers can be used to multiply
-or slice a sequence, and it'll behave as you'd intuitively expect it
-to; \code{3L * 'abc'} produces 'abcabcabc', and \code{
-(0,1,2,3)[2L:4L]} produces (2,3). Long integers can also be used in
-various contexts where previously only integers were accepted, such
-as in the \method{seek()} method of file objects, and in the formats
-supported by the \verb|%| operator (\verb|%d|, \verb|%i|, \verb|%x|,
-etc.).  For example, \code{"\%d" \% 2L**64} will produce the string
-\samp{18446744073709551616}.
-
-The subtlest long integer change of all is that the \function{str()}
-of a long integer no longer has a trailing 'L' character, though
-\function{repr()} still includes it.  The 'L' annoyed many people who
-wanted to print long integers that looked just like regular integers,
-since they had to go out of their way to chop off the character.  This
-is no longer a problem in 2.0, but code which does \code{str(longval)[:-1]} and assumes the 'L' is there, will now lose
-the final digit.
-
-Taking the \function{repr()} of a float now uses a different
-formatting precision than \function{str()}.  \function{repr()} uses
-\code{\%.17g} format string for C's \function{sprintf()}, while
-\function{str()} uses \code{\%.12g} as before.  The effect is that 
-\function{repr()} may occasionally show more decimal places than 
-\function{str()}, for certain numbers. 
-For example, the number 8.1 can't be represented exactly in binary, so
-\code{repr(8.1)} is \code{'8.0999999999999996'}, while str(8.1) is
-\code{'8.1'}.
-