blob: ae0be2fd2b885019ffb3e09bf15dd488921951b6 [file] [log] [blame]
Fred Drake2db76802004-12-01 05:05:47 +00001\documentclass{howto}
2\usepackage{distutils}
3% $Id$
4
Fred Drake2db76802004-12-01 05:05:47 +00005
6\title{What's New in Python 2.5}
7\release{0.0}
Andrew M. Kuchling92e24952004-12-03 13:54:09 +00008\author{A.M. Kuchling}
9\authoraddress{\email{amk@amk.ca}}
Fred Drake2db76802004-12-01 05:05:47 +000010
11\begin{document}
12\maketitle
13\tableofcontents
14
15This article explains the new features in Python 2.5. No release date
Andrew M. Kuchling5eefdca2006-02-08 11:36:09 +000016for Python 2.5 has been set; it will probably be released in the
17autumn of 2006.
Fred Drake2db76802004-12-01 05:05:47 +000018
19% Compare with previous release in 2 - 3 sentences here.
20
21This article doesn't attempt to provide a complete specification of
22the new features, but instead provides a convenient overview. For
23full details, you should refer to the documentation for Python 2.5.
24% add hyperlink when the documentation becomes available online.
25If you want to understand the complete implementation and design
26rationale, refer to the PEP for a particular new feature.
27
28
29%======================================================================
Andrew M. Kuchling3e41b052005-03-01 00:53:46 +000030\section{PEP 309: Partial Function Application}
Fred Drake2db76802004-12-01 05:05:47 +000031
Andrew M. Kuchlingb1c96fd2005-03-20 21:42:04 +000032The \module{functional} module is intended to contain tools for
33functional-style programming. Currently it only contains
34\class{partial}, but new functions will probably be added in future
35versions of Python.
36
Andrew M. Kuchling4b000cd2005-04-09 15:51:44 +000037For programs written in a functional style, it can be useful to
38construct variants of existing functions that have some of the
39parameters filled in. Consider a Python function \code{f(a, b, c)};
40you could create a new function \code{g(b, c)} that was equivalent to
41\code{f(1, b, c)}. This is called ``partial function application'',
42and is provided by the \class{partial} class in the new
43\module{functional} module.
44
45The constructor for \class{partial} takes the arguments
46\code{(\var{function}, \var{arg1}, \var{arg2}, ...
47\var{kwarg1}=\var{value1}, \var{kwarg2}=\var{value2})}. The resulting
48object is callable, so you can just call it to invoke \var{function}
49with the filled-in arguments.
50
51Here's a small but realistic example:
52
53\begin{verbatim}
54import functional
55
56def log (message, subsystem):
57 "Write the contents of 'message' to the specified subsystem."
58 print '%s: %s' % (subsystem, message)
59 ...
60
61server_log = functional.partial(log, subsystem='server')
62\end{verbatim}
63
Andrew M. Kuchling6af7fe02005-08-02 17:20:36 +000064Here's another example, from a program that uses PyGTk. Here a
65context-sensitive pop-up menu is being constructed dynamically. The
66callback provided for the menu option is a partially applied version
67of the \method{open_item()} method, where the first argument has been
68provided.
Andrew M. Kuchling4b000cd2005-04-09 15:51:44 +000069
Andrew M. Kuchling6af7fe02005-08-02 17:20:36 +000070\begin{verbatim}
71...
72class Application:
73 def open_item(self, path):
74 ...
75 def init (self):
76 open_func = functional.partial(self.open_item, item_path)
77 popup_menu.append( ("Open", open_func, 1) )
78\end{verbatim}
Andrew M. Kuchlingb1c96fd2005-03-20 21:42:04 +000079
80
81\begin{seealso}
82
83\seepep{309}{Partial Function Application}{PEP proposed and written by
84Peter Harris; implemented by Hye-Shik Chang, with adaptations by
85Raymond Hettinger.}
86
87\end{seealso}
Fred Drake2db76802004-12-01 05:05:47 +000088
89
90%======================================================================
Fred Drakedb7b0022005-03-20 22:19:47 +000091\section{PEP 314: Metadata for Python Software Packages v1.1}
92
Andrew M. Kuchlingd8d732e2005-04-09 23:59:41 +000093Some simple dependency support was added to Distutils. The
94\function{setup()} function now has \code{requires},\code{provides},
95and \code{obsoletes}. When you build a source distribution using the
96\code{sdist} command, the dependency information will be recorded in
97the \file{PKG-INFO} file.
98
99Another new keyword is \code{download_url}, which should be set to a
100URL for the package's source code. This means it's now possible to
101look up an entry in the package index, determine the dependencies for
102a package, and download the required packages.
103
104% XXX put example here
105
106\begin{seealso}
107
108\seepep{314}{Metadata for Python Software Packages v1.1}{PEP proposed
109and written by A.M. Kuchling, Richard Jones, and Fred Drake;
110implemented by Richard Jones and Fred Drake.}
111
112\end{seealso}
Fred Drakedb7b0022005-03-20 22:19:47 +0000113
114
115%======================================================================
Andrew M. Kuchlinga2e21cb2005-08-02 17:13:21 +0000116\section{PEP 342: New Generator Features}
117
Andrew M. Kuchling150e3492005-08-23 00:56:06 +0000118As introduced in Python 2.3, generators only produce output; once a
119generator's code was invoked to create an iterator, there's no way to
120pass new parameters into the function when its execution is resumed.
Andrew M. Kuchling07382062005-08-27 18:45:47 +0000121Hackish solutions to this include making the generator's code look at
122a global variable and then changing the global variable's value, or
123passing in some mutable object that callers then modify. Python
1242.5 adds the ability to pass values \emph{into} a generator.
Andrew M. Kuchling150e3492005-08-23 00:56:06 +0000125
126To refresh your memory of basic generators, here's a simple example:
127
128\begin{verbatim}
129def counter (maximum):
130 i = 0
131 while i < maximum:
132 yield i
133 i += 1
134\end{verbatim}
135
Andrew M. Kuchling07382062005-08-27 18:45:47 +0000136When you call \code{counter(10)}, the result is an iterator that
137returns the values from 0 up to 9. On encountering the
138\keyword{yield} statement, the iterator returns the provided value and
139suspends the function's execution, preserving the local variables.
140Execution resumes on the following call to the iterator's
141\method{next()} method, picking up after the \keyword{yield}.
Andrew M. Kuchling150e3492005-08-23 00:56:06 +0000142
Andrew M. Kuchling07382062005-08-27 18:45:47 +0000143In Python 2.3, \keyword{yield} was a statement; it didn't return any
144value. In 2.5, \keyword{yield} is now an expression, returning a
145value that can be assigned to a variable or otherwise operated on:
Andrew M. Kuchlinga2e21cb2005-08-02 17:13:21 +0000146
Andrew M. Kuchling07382062005-08-27 18:45:47 +0000147\begin{verbatim}
148val = (yield i)
149\end{verbatim}
150
151I recommend that you always put parentheses around a \keyword{yield}
152expression when you're doing something with the returned value, as in
153the above example. The parentheses aren't always necessary, but it's
154easier to always add them instead of having to remember when they're
155needed. The exact rules are that a \keyword{yield}-expression must
156always be parenthesized except when it occurs at the top-level
157expression on the right-hand side of an assignment, meaning
158you can to write \code{val = yield i} but \code{val = (yield i) + 12}.
159
160Values are sent into a generator by calling its
161\method{send(\var{value})} method. The generator's code is then
162resumed and the \keyword{yield} expression produces \var{value}.
163If the regular \method{next()} method is called, the \keyword{yield}
164returns \constant{None}.
165
166Here's the previous example, modified to allow changing the value of
167the internal counter.
168
169\begin{verbatim}
170def counter (maximum):
171 i = 0
172 while i < maximum:
173 val = (yield i)
174 # If value provided, change counter
175 if val is not None:
176 i = val
177 else:
178 i += 1
179\end{verbatim}
180
181And here's an example of changing the counter:
182
183\begin{verbatim}
184>>> it = counter(10)
185>>> print it.next()
1860
187>>> print it.next()
1881
189>>> print it.send(8)
1908
191>>> print it.next()
1929
193>>> print it.next()
194Traceback (most recent call last):
195 File ``t.py'', line 15, in ?
196 print it.next()
197StopIteration
Andrew M. Kuchlingc2033702005-08-29 13:30:12 +0000198\end{verbatim}
Andrew M. Kuchling07382062005-08-27 18:45:47 +0000199
200Because \keyword{yield} will often be returning \constant{None},
201you shouldn't just use its value in expressions unless you're sure
202that only the \method{send()} method will be used.
203
204There are two other new methods on generators in addition to
205\method{send()}:
206
207\begin{itemize}
208
209 \item \method{throw(\var{type}, \var{value}=None,
210 \var{traceback}=None)} is used to raise an exception inside the
211 generator; the exception is raised by the \keyword{yield} expression
212 where the generator's execution is paused.
213
214 \item \method{close()} raises a new \exception{GeneratorExit}
215 exception inside the generator to terminate the iteration.
216 On receiving this
217 exception, the generator's code must either raise
218 \exception{GeneratorExit} or \exception{StopIteration}; catching the
219 exception and doing anything else is illegal and will trigger
220 a \exception{RuntimeError}. \method{close()} will also be called by
221 Python's garbage collection when the generator is garbage-collected.
222
223 If you need to run cleanup code in case of a \exception{GeneratorExit},
224 I suggest using a \code{try: ... finally:} suite instead of
225 catching \exception{GeneratorExit}.
226
227\end{itemize}
228
229The cumulative effect of these changes is to turn generators from
230one-way producers of information into both producers and consumers.
231Generators also become \emph{coroutines}, a more generalized form of
232subroutines; subroutines are entered at one point and exited at
233another point (the top of the function, and a \keyword{return
234statement}), but coroutines can be entered, exited, and resumed at
235many different points (the \keyword{yield} statements).science term
236
237
Andrew M. Kuchlinga2e21cb2005-08-02 17:13:21 +0000238\begin{seealso}
239
240\seepep{342}{Coroutines via Enhanced Generators}{PEP written by
241Guido van Rossum and Phillip J. Eby;
Andrew M. Kuchling07382062005-08-27 18:45:47 +0000242implemented by Phillip J. Eby. Includes examples of
243some fancier uses of generators as coroutines.}
244
245\seeurl{http://en.wikipedia.org/wiki/Coroutine}{The Wikipedia entry for
246coroutines.}
247
248\seeurl{http://www.sidhe.org/~dan/blog/archives/000178.html}{An
249explanation of coroutines from a Perl point of view, written by Dan
250Sugalski.}
Andrew M. Kuchlinga2e21cb2005-08-02 17:13:21 +0000251
252\end{seealso}
253
254
255%======================================================================
Fred Drake2db76802004-12-01 05:05:47 +0000256\section{Other Language Changes}
257
258Here are all of the changes that Python 2.5 makes to the core Python
259language.
260
261\begin{itemize}
Andrew M. Kuchling1cae3f52004-12-03 14:57:21 +0000262
263\item The \function{min()} and \function{max()} built-in functions
264gained a \code{key} keyword argument analogous to the \code{key}
Andrew M. Kuchlinge9b1bf42005-03-20 19:26:30 +0000265argument for \method{sort()}. This argument supplies a function
Andrew M. Kuchling1cae3f52004-12-03 14:57:21 +0000266that takes a single argument and is called for every value in the list;
267\function{min()}/\function{max()} will return the element with the
268smallest/largest return value from this function.
269For example, to find the longest string in a list, you can do:
270
271\begin{verbatim}
272L = ['medium', 'longest', 'short']
273# Prints 'longest'
274print max(L, key=len)
275# Prints 'short', because lexicographically 'short' has the largest value
276print max(L)
277\end{verbatim}
278
279(Contributed by Steven Bethard and Raymond Hettinger.)
Fred Drake2db76802004-12-01 05:05:47 +0000280
Andrew M. Kuchling150e3492005-08-23 00:56:06 +0000281\item Two new built-in functions, \function{any()} and
282\function{all()}, evaluate whether an iterator contains any true or
283false values. \function{any()} returns \constant{True} if any value
284returned by the iterator is true; otherwise it will return
285\constant{False}. \function{all()} returns \constant{True} only if
286all of the values returned by the iterator evaluate as being true.
287
288% XXX who added?
289
290
Andrew M. Kuchlinge9b1bf42005-03-20 19:26:30 +0000291\item The list of base classes in a class definition can now be empty.
292As an example, this is now legal:
293
294\begin{verbatim}
295class C():
296 pass
297\end{verbatim}
298(Implemented by Brett Cannon.)
299
Fred Drake2db76802004-12-01 05:05:47 +0000300\end{itemize}
301
302
303%======================================================================
304\subsection{Optimizations}
305
306\begin{itemize}
307
Andrew M. Kuchling150e3492005-08-23 00:56:06 +0000308\item When they were introduced
309in Python 2.4, the built-in \class{set} and \class{frozenset} types
310were built on top of Python's dictionary type.
311In 2.5 the internal data structure has been customized for implementing sets,
312and as a result sets will use a third less memory and are somewhat faster.
313(Implemented by Raymond Hettinger.)
Fred Drake2db76802004-12-01 05:05:47 +0000314
315\end{itemize}
316
317The net result of the 2.5 optimizations is that Python 2.5 runs the
Andrew M. Kuchling92e24952004-12-03 13:54:09 +0000318pystone benchmark around XX\% faster than Python 2.4.
Fred Drake2db76802004-12-01 05:05:47 +0000319
320
321%======================================================================
322\section{New, Improved, and Deprecated Modules}
323
324As usual, Python's standard library received a number of enhancements and
325bug fixes. Here's a partial list of the most notable changes, sorted
326alphabetically by module name. Consult the
327\file{Misc/NEWS} file in the source tree for a more
328complete list of changes, or look through the CVS logs for all the
329details.
330
331\begin{itemize}
332
Andrew M. Kuchling150e3492005-08-23 00:56:06 +0000333% collections.deque now has .remove()
334
Andrew M. Kuchling3e41b052005-03-01 00:53:46 +0000335% the cPickle module no longer accepts the deprecated None option in the
336% args tuple returned by __reduce__().
337
338% csv module improvements
339
340% datetime.datetime() now has a strptime class method which can be used to
341% create datetime object using a string and format.
342
Andrew M. Kuchling150e3492005-08-23 00:56:06 +0000343\item A new \module{hashlib} module has been added to replace the
344\module{md5} and \module{sha} modules. \module{hashlib} adds support
345for additional secure hashes (SHA-224, SHA-256, SHA-384, and SHA-512).
346When available, the module uses OpenSSL for fast platform optimized
347implementations of algorithms. The old \module{md5} and \module{sha}
348modules still exist as wrappers around hashlib to preserve backwards
349compatibility. (Contributed by Gregory P. Smith.)
350
Andrew M. Kuchlinge9b1bf42005-03-20 19:26:30 +0000351\item The \function{nsmallest()} and
352\function{nlargest()} functions in the \module{heapq} module
353now support a \code{key} keyword argument similar to the one
354provided by the \function{min()}/\function{max()} functions
355and the \method{sort()} methods. For example:
356Example:
357
358\begin{verbatim}
359>>> import heapq
360>>> L = ["short", 'medium', 'longest', 'longer still']
361>>> heapq.nsmallest(2, L) # Return two lowest elements, lexicographically
362['longer still', 'longest']
363>>> heapq.nsmallest(2, L, key=len) # Return two shortest elements
364['short', 'medium']
365\end{verbatim}
366
367(Contributed by Raymond Hettinger.)
368
Andrew M. Kuchling511a3a82005-03-20 19:52:18 +0000369\item The \function{itertools.islice()} function now accepts
370\code{None} for the start and step arguments. This makes it more
371compatible with the attributes of slice objects, so that you can now write
372the following:
373
374\begin{verbatim}
375s = slice(5) # Create slice object
376itertools.islice(iterable, s.start, s.stop, s.step)
377\end{verbatim}
378
379(Contributed by Raymond Hettinger.)
Andrew M. Kuchling3e41b052005-03-01 00:53:46 +0000380
Andrew M. Kuchling150e3492005-08-23 00:56:06 +0000381\item The \module{operator} module's \function{itemgetter()}
382and \function{attrgetter()} functions now support multiple fields.
383A call such as \code{operator.attrgetter('a', 'b')}
384will return a function
385that retrieves the \member{a} and \member{b} attributes. Combining
386this new feature with the \method{sort()} method's \code{key} parameter
387lets you easily sort lists using multiple fields.
388
389% XXX who added?
390
Andrew M. Kuchling3e41b052005-03-01 00:53:46 +0000391
Andrew M. Kuchlinge9b1bf42005-03-20 19:26:30 +0000392\item The \module{os} module underwent a number of changes. The
393\member{stat_float_times} variable now defaults to true, meaning that
394\function{os.stat()} will now return time values as floats. (This
395doesn't necessarily mean that \function{os.stat()} will return times
396that are precise to fractions of a second; not all systems support
397such precision.)
Andrew M. Kuchling3e41b052005-03-01 00:53:46 +0000398
Andrew M. Kuchling150e3492005-08-23 00:56:06 +0000399Constants named \member{os.SEEK_SET}, \member{os.SEEK_CUR}, and
Andrew M. Kuchlinge9b1bf42005-03-20 19:26:30 +0000400\member{os.SEEK_END} have been added; these are the parameters to the
Andrew M. Kuchling150e3492005-08-23 00:56:06 +0000401\function{os.lseek()} function. Two new constants for locking are
402\member{os.O_SHLOCK} and \member{os.O_EXLOCK}.
403
404On FreeBSD, the \function{os.stat()} function now returns
405times with nanosecond resolution, and the returned object
406now has \member{st_gen} and \member{st_birthtime}.
407The \member{st_flags} member is also available, if the platform supports it.
408% XXX patch 1180695, 1212117
409
Andrew M. Kuchling4678dc82006-01-15 16:11:28 +0000410\item The \module{socket} module now supports \constant{AF_NETLINK}
411sockets on Linux, thanks to a patch from Philippe Biondi.
412Netlink sockets are a Linux-specific mechanism for communications
413between a user-space process and kernel code; an introductory
414article about them is at \url{http://www.linuxjournal.com/article/7356}.
415In Python code, netlink addresses are represented as a tuple of 2 integers,
416\code{(\var{pid}, \var{group_mask})}.
417
Andrew M. Kuchling150e3492005-08-23 00:56:06 +0000418\item New module: \module{spwd} provides functions for accessing the
419shadow password database on systems that support it.
420% XXX give example
Fred Drake2db76802004-12-01 05:05:47 +0000421
Andrew M. Kuchlinge9b1bf42005-03-20 19:26:30 +0000422\item The \class{TarFile} class in the \module{tarfile} module now has
Georg Brandl08c02db2005-07-22 18:39:19 +0000423an \method{extractall()} method that extracts all members from the
Andrew M. Kuchlinge9b1bf42005-03-20 19:26:30 +0000424archive into the current working directory. It's also possible to set
425a different directory as the extraction target, and to unpack only a
Andrew M. Kuchling150e3492005-08-23 00:56:06 +0000426subset of the archive's members.
Andrew M. Kuchlinge9b1bf42005-03-20 19:26:30 +0000427
Andrew M. Kuchling150e3492005-08-23 00:56:06 +0000428A tarfile's compression can be autodetected by
429using the mode \code{'r|*'}.
430% patch 918101
431(Contributed by Lars Gust\"abel.)
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000432
Fredrik Lundh7e0aef02005-12-12 18:54:55 +0000433\item A new package \module{xml.etree} has been added, which contains
434a subset of the ElementTree XML library. Available modules are
435\module{ElementTree}, \module{ElementPath}, and
436\module{ElementInclude}, from ElementTree 1.2.6. (Contributed by
437Fredrik Lundh.)
438
Andrew M. Kuchling150e3492005-08-23 00:56:06 +0000439\item The \module{xmlrpclib} module now supports returning
440 \class{datetime} objects for the XML-RPC date type. Supply
441 \code{use_datetime=True} to the \function{loads()} function
442 or the \class{Unmarshaller} class to enable this feature.
443% XXX patch 1120353
444
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000445
Fred Drake114b8ca2005-03-21 05:47:11 +0000446\end{itemize}
Andrew M. Kuchlinge9b1bf42005-03-20 19:26:30 +0000447
Fred Drake2db76802004-12-01 05:05:47 +0000448
449
450%======================================================================
451% whole new modules get described in \subsections here
452
Andrew M. Kuchling150e3492005-08-23 00:56:06 +0000453% XXX new distutils features: upload
454
Fredrik Lundh7e0aef02005-12-12 18:54:55 +0000455% XXX should hashlib perhaps be described here instead?
456% XXX should xml.etree perhaps be described here instead?
Andrew M. Kuchling150e3492005-08-23 00:56:06 +0000457
458
Fred Drake2db76802004-12-01 05:05:47 +0000459
460% ======================================================================
461\section{Build and C API Changes}
462
463Changes to Python's build process and to the C API include:
464
465\begin{itemize}
466
Andrew M. Kuchlingdb85ed52005-10-23 21:52:59 +0000467\item The design of the bytecode compiler has changed a great deal, no
468longer generating bytecode by traversing the parse tree. Instead
469the parse tree is converted to an abstract syntax tree (or AST), and it is
470the abstract syntax tree that's traversed to produce the bytecode.
471
472No documentation has been written for the AST code yet. To start
473learning about it, read the definition of the various AST nodes in
474\file{Parser/Python.asdl}. A Python script reads this file and
475generates a set of C structure definitions in
476\file{Include/Python-ast.h}. The \cfunction{PyParser_ASTFromString()}
477and \cfunction{PyParser_ASTFromFile()}, defined in
478\file{Include/pythonrun.h}, take Python source as input and return the
479root of an AST representing the contents. This AST can then be turned
480into a code object by \cfunction{PyAST_Compile()}. For more
481information, read the source code, and then ask questions on
482python-dev.
483
484% List of names taken from Jeremy's python-dev post at
485% http://mail.python.org/pipermail/python-dev/2005-October/057500.html
486The AST code was developed under Jeremy Hylton's management, and
487implemented by (in alphabetical order) Brett Cannon, Nick Coghlan,
488Grant Edwards, John Ehresman, Kurt Kaiser, Neal Norwitz, Tim Peters,
489Armin Rigo, and Neil Schemenauer, plus the participants in a number of
490AST sprints at conferences such as PyCon.
491
Andrew M. Kuchling150e3492005-08-23 00:56:06 +0000492\item The built-in set types now have an official C API. Call
493\cfunction{PySet_New()} and \cfunction{PyFrozenSet_New()} to create a
494new set, \cfunction{PySet_Add()} and \cfunction{PySet_Discard()} to
495add and remove elements, and \cfunction{PySet_Contains} and
496\cfunction{PySet_Size} to examine the set's state.
497
498\item The \cfunction{PyRange_New()} function was removed. It was
499never documented, never used in the core code, and had dangerously lax
500error checking.
Fred Drake2db76802004-12-01 05:05:47 +0000501
502\end{itemize}
503
504
505%======================================================================
506\subsection{Port-Specific Changes}
507
508Platform-specific changes go here.
509
510
511%======================================================================
512\section{Other Changes and Fixes \label{section-other}}
513
514As usual, there were a bunch of other improvements and bugfixes
515scattered throughout the source tree. A search through the CVS change
516logs finds there were XXX patches applied and YYY bugs fixed between
Andrew M. Kuchling92e24952004-12-03 13:54:09 +0000517Python 2.4 and 2.5. Both figures are likely to be underestimates.
Fred Drake2db76802004-12-01 05:05:47 +0000518
519Some of the more notable changes are:
520
521\begin{itemize}
522
523\item Details go here.
524
525\end{itemize}
526
527
528%======================================================================
529\section{Porting to Python 2.5}
530
531This section lists previously described changes that may require
532changes to your code:
533
534\begin{itemize}
535
Andrew M. Kuchling3e41b052005-03-01 00:53:46 +0000536\item Some old deprecated modules (\module{statcache}, \module{tzparse},
537 \module{whrandom}) have been moved to \file{Lib/lib-old}.
Andrew M. Kuchling0c35db92005-03-20 20:06:49 +0000538You can get access to these modules again by adding the directory
539to your \code{sys.path}:
540
541\begin{verbatim}
542import os
543from distutils import sysconfig
544
545lib_dir = sysconfig.get_python_lib(standard_lib=True)
546old_dir = os.path.join(lib_dir, 'lib-old')
547sys.path.append(old_dir)
548\end{verbatim}
549
550Doing so is discouraged, however; it's better to update any code that
551still uses these modules.
Andrew M. Kuchling3e41b052005-03-01 00:53:46 +0000552
553% the pickle module no longer uses the deprecated bin parameter.
Fred Drake2db76802004-12-01 05:05:47 +0000554
555\end{itemize}
556
557
558%======================================================================
559\section{Acknowledgements \label{acks}}
560
561The author would like to thank the following people for offering
562suggestions, corrections and assistance with various drafts of this
563article: .
564
565\end{document}