Commit b5a755e4 authored by Guido van Rossum's avatar Guido van Rossum

Merged revisions 56301-56442 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/branches/p3yk

................
  r56322 | kurt.kaiser | 2007-07-12 11:35:03 -0700 (Thu, 12 Jul 2007) | 2 lines

  Replace obscure code which was failing in py3k.
................
  r56323 | kurt.kaiser | 2007-07-12 11:44:12 -0700 (Thu, 12 Jul 2007) | 3 lines

  1. Remove new division option
  2. Update IDLE version to 3.0x
................
  r56327 | kurt.kaiser | 2007-07-12 12:20:20 -0700 (Thu, 12 Jul 2007) | 5 lines

  Fix another instance of this defect in Tkinter, and one in IDLE.

  Patch 1724999 by Ali Gholami Rudi -- avoid complaints about dict size
  change during iter in destroy call.
................
  r56339 | georg.brandl | 2007-07-13 03:07:25 -0700 (Fri, 13 Jul 2007) | 2 lines

  Fix #1753310: regrtest -x doesn't work anymore
................
  r56361 | kurt.kaiser | 2007-07-13 18:25:24 -0700 (Fri, 13 Jul 2007) | 2 lines

  convert a map() iterator to a list to get this working.
................
  r56362 | kurt.kaiser | 2007-07-13 18:53:45 -0700 (Fri, 13 Jul 2007) | 2 lines

  Was modifying dict during iteration.
................
  r56376 | collin.winter | 2007-07-14 11:56:19 -0700 (Sat, 14 Jul 2007) | 1 line

  Add an example of class decorators to test_grammar.
................
  r56377 | collin.winter | 2007-07-14 12:00:17 -0700 (Sat, 14 Jul 2007) | 1 line

  Add a basic example of dictcomps to test_grammar.
................
  r56413 | neal.norwitz | 2007-07-17 00:21:18 -0700 (Tue, 17 Jul 2007) | 149 lines

  Merged revisions 56202-56412 via svnmerge from
  svn+ssh://pythondev@svn.python.org/python/trunk

  ........
    r56204 | ronald.oussoren | 2007-07-08 23:02:21 -0700 (Sun, 08 Jul 2007) | 2 lines

    Patch 1693258: Fix for duplicate "preferences" menu-OS X
  ........
    r56207 | ronald.oussoren | 2007-07-09 01:41:15 -0700 (Mon, 09 Jul 2007) | 4 lines

    Patch 1673122: be explicit about which libtool to use, to avoid name clashes
    when a users install GNU libtool early in his PATH
  ........
    r56280 | georg.brandl | 2007-07-11 12:41:49 -0700 (Wed, 11 Jul 2007) | 2 lines

    Fix #1752132: wrong comment in opcode description.
  ........
    r56293 | georg.brandl | 2007-07-12 01:05:45 -0700 (Thu, 12 Jul 2007) | 3 lines

    Patch #1752270, #1750931: complain if urllib2 add_handler called
    without handler.
  ........
    r56296 | georg.brandl | 2007-07-12 01:11:29 -0700 (Thu, 12 Jul 2007) | 2 lines

    Patch #1739696: use code.co_code only if really necessary
  ........
    r56298 | georg.brandl | 2007-07-12 01:38:00 -0700 (Thu, 12 Jul 2007) | 3 lines

    Patch #1673759: add a missing overflow check when formatting floats
    with %G.
  ........
    r56302 | georg.brandl | 2007-07-12 02:06:41 -0700 (Thu, 12 Jul 2007) | 2 lines

    Patch #1731659: improve time.strptime docs.
  ........
    r56304 | georg.brandl | 2007-07-12 02:24:04 -0700 (Thu, 12 Jul 2007) | 2 lines

    Patch #1731169: clean up expected skips list.
  ........
    r56306 | georg.brandl | 2007-07-12 02:37:49 -0700 (Thu, 12 Jul 2007) | 3 lines

    Bug #1637365: add subsection about "__name__ == __main__" to the
    Python tutorial.
  ........
    r56308 | georg.brandl | 2007-07-12 02:59:22 -0700 (Thu, 12 Jul 2007) | 5 lines

    Patch #1675424: Added tests for uncovered code in the zipfile module.
      The KeyError raised by Zipfile.getinfo for nonexistent names now has
      a descriptive message.
  ........
    r56340 | facundo.batista | 2007-07-13 03:43:44 -0700 (Fri, 13 Jul 2007) | 6 lines


    Added tests for basic behavior of DateTime, Binary, and Fault classes
    and the escape function. Check that marshalling recursive sequences &
    dicts raises TypeError. Check that marshalling out-of-range ints
    raises OverflowError [Alan McIntyre - GSoC]
  ........
    r56345 | raymond.hettinger | 2007-07-13 05:09:41 -0700 (Fri, 13 Jul 2007) | 1 line

    Correct the docs for takewhile().  Improve the recipe for nth().  Should be backported
  ........
    r56348 | thomas.heller | 2007-07-13 06:59:39 -0700 (Fri, 13 Jul 2007) | 4 lines

    Repair COMError.  Since exceptions are new style classes now, setting
    the methods and docstring after the type creation does not work, they
    must be in the dictionary before creating the type.
  ........
    r56349 | thomas.heller | 2007-07-13 07:18:06 -0700 (Fri, 13 Jul 2007) | 1 line

    Add tests for _ctypes.COMError.
  ........
    r56350 | thomas.heller | 2007-07-13 09:50:43 -0700 (Fri, 13 Jul 2007) | 4 lines

    Do not try to load the GLUT library in the ctypes tests.  This test
    adds little value, but has a large problem on OS X, as explained in
    SF# 1581906.
  ........
    r56352 | thomas.heller | 2007-07-13 10:12:23 -0700 (Fri, 13 Jul 2007) | 3 lines

    Fix for SF# 1701409: segfault in c_char_p of ctypes.  The repr output
    of c_char_p and c_wchar_p has changed as a sideeffect.
  ........
    r56355 | thomas.heller | 2007-07-13 10:46:54 -0700 (Fri, 13 Jul 2007) | 3 lines

    Fix for SF# 1649098: avoid zero-sized array declaration in structure.
  ........
    r56357 | thomas.heller | 2007-07-13 12:51:55 -0700 (Fri, 13 Jul 2007) | 3 lines

    PyType_stgdict() returns a borrowed reference which must not be
    Py_DECREF'd.
  ........
    r56360 | barry.warsaw | 2007-07-13 15:12:58 -0700 (Fri, 13 Jul 2007) | 10 lines

    In response to this SF bug:

    [ 1752723 ] email.message_from_string: initial line gets discarded

    I added a test to assert that when the first line of text passed to
    message_from_string() contains a leading space, the message ends up with the
    appropriate FirstHeaderLineIsContinuationDefect on its defects list.

    The bug is invalid.
  ........
    r56364 | georg.brandl | 2007-07-14 10:12:23 -0700 (Sat, 14 Jul 2007) | 2 lines

    Bug #1753406: missing \versionadded for subprocess.check_call.
  ........
    r56366 | georg.brandl | 2007-07-14 10:32:41 -0700 (Sat, 14 Jul 2007) | 2 lines

    Clarify webbrowser.open description.
  ........
    r56380 | andrew.kuchling | 2007-07-14 13:58:21 -0700 (Sat, 14 Jul 2007) | 1 line

    Typo fix
  ........
    r56382 | andrew.kuchling | 2007-07-14 14:56:19 -0700 (Sat, 14 Jul 2007) | 7 lines

    Avoid exception if there's a stray directory inside a Maildir folder.

    The Maildir specification doesn't seem to say anything about this
    situation, and it can happen if you're keeping a Maildir mailbox in
    Subversion (.svn directories) or some similar system.  The patch just
    ignores directories in the cur/, new/, tmp/ folders.
  ........
    r56392 | facundo.batista | 2007-07-14 15:41:45 -0700 (Sat, 14 Jul 2007) | 6 lines


    First version.  Includes tests for helper functions: read, write,
    _exception, readwrite, closeall, compact_traceback; and for classes
    dispatcher, dispatcher_with_send, and file_wrapper.
    [Alan McIntyre - GSoC]
  ........
    r56399 | facundo.batista | 2007-07-15 13:30:39 -0700 (Sun, 15 Jul 2007) | 5 lines


    Changed the used port and commented out some tests that uses
    a non documented function that appers to uses resources
    not present in Windows.
  ........
    r56412 | facundo.batista | 2007-07-16 19:19:39 -0700 (Mon, 16 Jul 2007) | 6 lines


    Prevent asyncore.dispatcher tests from hanging by adding loop counters
    to server & client, and by adding asyncore.close_all calls in
    tearDown. Also choose correct expected logging results based on the
    value of __debug__  [Alan McIntyre - GSoC]
  ........
................
  r56442 | guido.van.rossum | 2007-07-18 10:26:38 -0700 (Wed, 18 Jul 2007) | 14 lines

  Merged revisions 56413-56441 via svnmerge from
  svn+ssh://pythondev@svn.python.org/python/trunk

  ........
    r56439 | georg.brandl | 2007-07-17 23:37:55 -0700 (Tue, 17 Jul 2007) | 2 lines

    Use "Unix" as platform name, not "UNIX".
  ........
    r56441 | guido.van.rossum | 2007-07-18 10:19:14 -0700 (Wed, 18 Jul 2007) | 3 lines

    SF patch# 1755885 by Kurt Kaiser: show location of Unicode escape errors.
    (Slightly tweaked for style and refcounts.)
  ........
................
parent 5ed317d7
...@@ -94,7 +94,7 @@ package, a section on differences and porting is provided. ...@@ -94,7 +94,7 @@ package, a section on differences and porting is provided.
This table describes the release history of the email package, corresponding This table describes the release history of the email package, corresponding
to the version of Python that the package was released with. For purposes of to the version of Python that the package was released with. For purposes of
this document, when you see a note about change or added versions, these refer this document, when you see a note about change or added versions, these refer
to the Python version the change was made it, \emph{not} the email package to the Python version the change was made in, \emph{not} the email package
version. This table also describes the Python compatibility of each version version. This table also describes the Python compatibility of each version
of the package. of the package.
......
...@@ -117,7 +117,7 @@ by functions or loops that truncate the stream. ...@@ -117,7 +117,7 @@ by functions or loops that truncate the stream.
Make an iterator that drops elements from the iterable as long as Make an iterator that drops elements from the iterable as long as
the predicate is true; afterwards, returns every element. Note, the predicate is true; afterwards, returns every element. Note,
the iterator does not produce \emph{any} output until the predicate the iterator does not produce \emph{any} output until the predicate
is true, so it may have a lengthy start-up time. Equivalent to: first becomes false, so it may have a lengthy start-up time. Equivalent to:
\begin{verbatim} \begin{verbatim}
def dropwhile(predicate, iterable): def dropwhile(predicate, iterable):
...@@ -509,8 +509,8 @@ def iteritems(mapping): ...@@ -509,8 +509,8 @@ def iteritems(mapping):
return izip(mapping.iterkeys(), mapping.itervalues()) return izip(mapping.iterkeys(), mapping.itervalues())
def nth(iterable, n): def nth(iterable, n):
"Returns the nth item or raise IndexError" "Returns the nth item or raise StopIteration"
return list(islice(iterable, n, n+1))[0] return islice(iterable, n, None).next()
def all(seq, pred=None): def all(seq, pred=None):
"Returns True if pred(x) is true for every element in the iterable" "Returns True if pred(x) is true for every element in the iterable"
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
Interface to Sun's NIS (Yellow Pages)} Interface to Sun's NIS (Yellow Pages)}
\declaremodule{extension}{nis} \declaremodule{extension}{nis}
\platform{UNIX} \platform{Unix}
\moduleauthor{Fred Gansevles}{Fred.Gansevles@cs.utwente.nl} \moduleauthor{Fred Gansevles}{Fred.Gansevles@cs.utwente.nl}
\sectionauthor{Moshe Zadka}{moshez@zadka.site.co.il} \sectionauthor{Moshe Zadka}{moshez@zadka.site.co.il}
\modulesynopsis{Interface to Sun's NIS (Yellow Pages) library.} \modulesynopsis{Interface to Sun's NIS (Yellow Pages) library.}
......
...@@ -145,6 +145,8 @@ The arguments are the same as for the Popen constructor. Example: ...@@ -145,6 +145,8 @@ The arguments are the same as for the Popen constructor. Example:
\begin{verbatim} \begin{verbatim}
check_call(["ls", "-l"]) check_call(["ls", "-l"])
\end{verbatim} \end{verbatim}
\versionadded{2.5}
\end{funcdesc} \end{funcdesc}
\subsubsection{Exceptions} \subsubsection{Exceptions}
......
...@@ -309,15 +309,23 @@ The field width is normally 2 except for \code{\%j} where it is 3. ...@@ -309,15 +309,23 @@ The field width is normally 2 except for \code{\%j} where it is 3.
\begin{funcdesc}{strptime}{string\optional{, format}} \begin{funcdesc}{strptime}{string\optional{, format}}
Parse a string representing a time according to a format. The return Parse a string representing a time according to a format. The return
value is a \class{struct_time} as returned by \function{gmtime()} or value is a \class{struct_time} as returned by \function{gmtime()} or
\function{localtime()}. The \var{format} parameter uses the same \function{localtime()}.
directives as those used by \function{strftime()}; it defaults to
\code{"\%a \%b \%d \%H:\%M:\%S \%Y"} which matches the formatting The \var{format} parameter uses the same directives as those used by
returned by \function{ctime()}. If \var{string} cannot be parsed \function{strftime()}; it defaults to \code{"\%a \%b \%d \%H:\%M:\%S
according to \var{format}, \exception{ValueError} is raised. If the \%Y"} which matches the formatting returned by \function{ctime()}.
string to be parsed has excess data after parsing, If \var{string} cannot be parsed according to \var{format}, or if it
\exception{ValueError} is raised. The default values used to fill in has excess data after parsing, \exception{ValueError} is raised. The
any missing data when more accurate values cannot be inferred are default values used to fill in any missing data when more accurate
\code{(1900, 1, 1, 0, 0, 0, 0, 1, -1)} . values cannot be inferred are \code{(1900, 1, 1, 0, 0, 0, 0, 1, -1)}.
For example:
\begin{verbatim}
>>> import time
>>> time.strptime("30 Nov 00", "%d %b %y")
(2000, 11, 30, 0, 0, 0, 3, 335, -1)
\end{verbatim}
Support for the \code{\%Z} directive is based on the values contained in Support for the \code{\%Z} directive is based on the values contained in
\code{tzname} and whether \code{daylight} is true. Because of this, \code{tzname} and whether \code{daylight} is true. Because of this,
......
...@@ -47,7 +47,7 @@ The following functions are defined: ...@@ -47,7 +47,7 @@ The following functions are defined:
\begin{funcdesc}{open}{url\optional{, new=0\optional{, autoraise=1}}} \begin{funcdesc}{open}{url\optional{, new=0\optional{, autoraise=1}}}
Display \var{url} using the default browser. If \var{new} is 0, the Display \var{url} using the default browser. If \var{new} is 0, the
\var{url} is opened in the same browser window. If \var{new} is 1, \var{url} is opened in the same browser window if possible. If \var{new} is 1,
a new browser window is opened if possible. If \var{new} is 2, a new browser window is opened if possible. If \var{new} is 2,
a new browser page ("tab") is opened if possible. If \var{autoraise} is a new browser page ("tab") is opened if possible. If \var{autoraise} is
true, the window is raised if possible (note that under many window true, the window is raised if possible (note that under many window
......
...@@ -24,8 +24,8 @@ it cannot currently create an encrypted file. ...@@ -24,8 +24,8 @@ it cannot currently create an encrypted file.
The available attributes of this module are: The available attributes of this module are:
\begin{excdesc}{error} \begin{excdesc}{BadZipfile}
The error raised for bad ZIP files. The error raised for bad ZIP files (old name: \code{zipfile.error}).
\end{excdesc} \end{excdesc}
\begin{excdesc}{LargeZipFile} \begin{excdesc}{LargeZipFile}
...@@ -90,7 +90,7 @@ The available attributes of this module are: ...@@ -90,7 +90,7 @@ The available attributes of this module are:
(a string) or a file-like object. The \var{mode} parameter (a string) or a file-like object. The \var{mode} parameter
should be \code{'r'} to read an existing file, \code{'w'} to should be \code{'r'} to read an existing file, \code{'w'} to
truncate and write a new file, or \code{'a'} to append to an truncate and write a new file, or \code{'a'} to append to an
existing file. For \var{mode} is \code{'a'} and \var{file} existing file. If \var{mode} is \code{'a'} and \var{file}
refers to an existing ZIP file, then additional files are added to refers to an existing ZIP file, then additional files are added to
it. If \var{file} does not refer to a ZIP file, then a new ZIP it. If \var{file} does not refer to a ZIP file, then a new ZIP
archive is appended to the file. This is meant for adding a ZIP archive is appended to the file. This is meant for adding a ZIP
...@@ -128,7 +128,8 @@ cat myzip.zip >> python.exe ...@@ -128,7 +128,8 @@ cat myzip.zip >> python.exe
\begin{methoddesc}{getinfo}{name} \begin{methoddesc}{getinfo}{name}
Return a \class{ZipInfo} object with information about the archive Return a \class{ZipInfo} object with information about the archive
member \var{name}. member \var{name}. Calling \method{getinfo()} for a name not currently
contained in the archive will raise a \exception{KeyError}.
\end{methoddesc} \end{methoddesc}
\begin{methoddesc}{infolist}{} \begin{methoddesc}{infolist}{}
...@@ -147,7 +148,9 @@ cat myzip.zip >> python.exe ...@@ -147,7 +148,9 @@ cat myzip.zip >> python.exe
parameter, if included, must be one of the following: \code{'r'} (the parameter, if included, must be one of the following: \code{'r'} (the
default), \code{'U'}, or \code{'rU'}. Choosing \code{'U'} or default), \code{'U'}, or \code{'rU'}. Choosing \code{'U'} or
\code{'rU'} will enable universal newline support in the read-only \code{'rU'} will enable universal newline support in the read-only
object. \var{pwd} is the password used for encrypted files. object. \var{pwd} is the password used for encrypted files. Calling
\method{open()} on a closed ZipFile will raise a
\exception{RuntimeError}.
\begin{notice} \begin{notice}
The file-like object is read-only and provides the following methods: The file-like object is read-only and provides the following methods:
\method{read()}, \method{readline()}, \method{readlines()}, \method{read()}, \method{readline()}, \method{readlines()},
...@@ -182,7 +185,8 @@ cat myzip.zip >> python.exe ...@@ -182,7 +185,8 @@ cat myzip.zip >> python.exe
Return the bytes of the file in the archive. The archive must be Return the bytes of the file in the archive. The archive must be
open for read or append. \var{pwd} is the password used for encrypted open for read or append. \var{pwd} is the password used for encrypted
files and, if specified, it will override the default password set with files and, if specified, it will override the default password set with
\method{setpassword()}. \method{setpassword()}. Calling \method{read()} on a closed ZipFile
will raise a \exception{RuntimeError}.
\versionchanged[\var{pwd} was added]{2.6} \versionchanged[\var{pwd} was added]{2.6}
\end{methoddesc} \end{methoddesc}
...@@ -190,6 +194,8 @@ cat myzip.zip >> python.exe ...@@ -190,6 +194,8 @@ cat myzip.zip >> python.exe
\begin{methoddesc}{testzip}{} \begin{methoddesc}{testzip}{}
Read all the files in the archive and check their CRC's and file Read all the files in the archive and check their CRC's and file
headers. Return the name of the first bad file, or else return \code{None}. headers. Return the name of the first bad file, or else return \code{None}.
Calling \method{testzip()} on a closed ZipFile will raise a
\exception{RuntimeError}.
\end{methoddesc} \end{methoddesc}
\begin{methoddesc}{write}{filename\optional{, arcname\optional{, \begin{methoddesc}{write}{filename\optional{, arcname\optional{,
...@@ -200,7 +206,10 @@ cat myzip.zip >> python.exe ...@@ -200,7 +206,10 @@ cat myzip.zip >> python.exe
separators removed). If given, \var{compress_type} overrides the separators removed). If given, \var{compress_type} overrides the
value given for the \var{compression} parameter to the constructor value given for the \var{compression} parameter to the constructor
for the new entry. The archive must be open with mode \code{'w'} for the new entry. The archive must be open with mode \code{'w'}
or \code{'a'}. or \code{'a'} -- calling \method{write()} on a ZipFile created with
mode \code{'r'} will raise a \exception{RuntimeError}. Calling
\method{write()} on a closed ZipFile will raise a
\exception{RuntimeError}.
\note{There is no official file name encoding for ZIP files. \note{There is no official file name encoding for ZIP files.
If you have unicode file names, please convert them to byte strings If you have unicode file names, please convert them to byte strings
...@@ -210,6 +219,11 @@ cat myzip.zip >> python.exe ...@@ -210,6 +219,11 @@ cat myzip.zip >> python.exe
\note{Archive names should be relative to the archive root, that is, \note{Archive names should be relative to the archive root, that is,
they should not start with a path separator.} they should not start with a path separator.}
\note{If \code{arcname} (or \code{filename}, if \code{arcname} is
not given) contains a null byte, the name of the file in the archive will
be truncated at the null byte.}
\end{methoddesc} \end{methoddesc}
\begin{methoddesc}{writestr}{zinfo_or_arcname, bytes} \begin{methoddesc}{writestr}{zinfo_or_arcname, bytes}
...@@ -218,7 +232,10 @@ cat myzip.zip >> python.exe ...@@ -218,7 +232,10 @@ cat myzip.zip >> python.exe
\class{ZipInfo} instance. If it's an instance, at least the \class{ZipInfo} instance. If it's an instance, at least the
filename, date, and time must be given. If it's a name, the date filename, date, and time must be given. If it's a name, the date
and time is set to the current date and time. The archive must be and time is set to the current date and time. The archive must be
opened with mode \code{'w'} or \code{'a'}. opened with mode \code{'w'} or \code{'a'} -- calling
\method{writestr()} on a ZipFile created with mode \code{'r'}
will raise a \exception{RuntimeError}. Calling \method{writestr()}
on a closed ZipFile will raise a \exception{RuntimeError}.
\end{methoddesc} \end{methoddesc}
...@@ -243,12 +260,13 @@ those of \class{ZipFile} objects. ...@@ -243,12 +260,13 @@ those of \class{ZipFile} objects.
available, else a \file{*.pyc} file, compiling if necessary. If the available, else a \file{*.pyc} file, compiling if necessary. If the
pathname is a file, the filename must end with \file{.py}, and just pathname is a file, the filename must end with \file{.py}, and just
the (corresponding \file{*.py[co]}) file is added at the top level the (corresponding \file{*.py[co]}) file is added at the top level
(no path information). If it is a directory, and the directory is (no path information). If the pathname is a file that does not end with
not a package directory, then all the files \file{*.py[co]} are \file{.py}, a \exception{RuntimeError} will be raised. If it is a
added at the top level. If the directory is a package directory, directory, and the directory is not a package directory, then all the
then all \file{*.py[oc]} are added under the package name as a file files \file{*.py[co]} are added at the top level. If the directory is
path, and if any subdirectories are package directories, all of a package directory, then all \file{*.py[co]} are added under the package
these are added recursively. \var{basename} is intended for name as a file path, and if any subdirectories are package directories, all
of these are added recursively. \var{basename} is intended for
internal use only. The \method{writepy()} method makes archives internal use only. The \method{writepy()} method makes archives
with file names like this: with file names like this:
......
...@@ -2498,6 +2498,44 @@ There is even a variant to import all names that a module defines: ...@@ -2498,6 +2498,44 @@ There is even a variant to import all names that a module defines:
This imports all names except those beginning with an underscore This imports all names except those beginning with an underscore
(\code{_}). (\code{_}).
\subsection{Executing modules as scripts \label{modulesAsScripts}}
When you run a Python module with
\begin{verbatim}
python fibo.py <arguments>
\end{verbatim}
the code in the module will be executed, just as if you imported it, but
with the \code{__name__} set to \code{"__main__"}. That means that by
adding this code at the end of your module:
\begin{verbatim}
if __name__ == "__main__":
import sys
fib(int(sys.argv[1]))
\end{verbatim}
you can make the file usable as a script as well as an importable module,
because the code that parses the command line only runs if the module is
executed as the ``main'' file:
\begin{verbatim}
$ python fibo.py 50
1 1 2 3 5 8 13 21 34
\end{verbatim}
If the module is imported, the code is not run:
\begin{verbatim}
>>> import fibo
>>>
\end{verbatim}
This is often used either to provide a convenient user interface to a
module, or for testing purposes (running the module as a script executes
a test suite).
\subsection{The Module Search Path \label{searchPath}} \subsection{The Module Search Path \label{searchPath}}
......
...@@ -112,7 +112,7 @@ extern "C" { ...@@ -112,7 +112,7 @@ extern "C" {
#define LOAD_GLOBAL 116 /* Index in name list */ #define LOAD_GLOBAL 116 /* Index in name list */
#define CONTINUE_LOOP 119 /* Start of loop (absolute) */ #define CONTINUE_LOOP 119 /* Start of loop (absolute) */
#define SETUP_LOOP 120 /* Target address (absolute) */ #define SETUP_LOOP 120 /* Target address (relative) */
#define SETUP_EXCEPT 121 /* "" */ #define SETUP_EXCEPT 121 /* "" */
#define SETUP_FINALLY 122 /* "" */ #define SETUP_FINALLY 122 /* "" */
......
...@@ -223,6 +223,14 @@ _check_size(c_char) ...@@ -223,6 +223,14 @@ _check_size(c_char)
class c_char_p(_SimpleCData): class c_char_p(_SimpleCData):
_type_ = "z" _type_ = "z"
if _os.name == "nt":
def __repr__(self):
if not windll.kernel32.IsBadStringPtrA(self, -1):
return "%s(%r)" % (self.__class__.__name__, self.value)
return "%s(%s)" % (self.__class__.__name__, cast(self, c_void_p).value)
else:
def __repr__(self):
return "%s(%s)" % (self.__class__.__name__, cast(self, c_void_p).value)
_check_size(c_char_p, "P") _check_size(c_char_p, "P")
class c_void_p(_SimpleCData): class c_void_p(_SimpleCData):
......
...@@ -7,25 +7,21 @@ from ctypes.test import is_resource_enabled ...@@ -7,25 +7,21 @@ from ctypes.test import is_resource_enabled
if sys.platform == "win32": if sys.platform == "win32":
lib_gl = find_library("OpenGL32") lib_gl = find_library("OpenGL32")
lib_glu = find_library("Glu32") lib_glu = find_library("Glu32")
lib_glut = find_library("glut32")
lib_gle = None lib_gle = None
elif sys.platform == "darwin": elif sys.platform == "darwin":
lib_gl = lib_glu = find_library("OpenGL") lib_gl = lib_glu = find_library("OpenGL")
lib_glut = find_library("GLUT")
lib_gle = None lib_gle = None
else: else:
lib_gl = find_library("GL") lib_gl = find_library("GL")
lib_glu = find_library("GLU") lib_glu = find_library("GLU")
lib_glut = find_library("glut")
lib_gle = find_library("gle") lib_gle = find_library("gle")
## print, for debugging ## print, for debugging
if is_resource_enabled("printing"): if is_resource_enabled("printing"):
if lib_gl or lib_glu or lib_glut or lib_gle: if lib_gl or lib_glu or lib_gle:
print("OpenGL libraries:") print("OpenGL libraries:")
for item in (("GL", lib_gl), for item in (("GL", lib_gl),
("GLU", lib_glu), ("GLU", lib_glu),
("glut", lib_glut),
("gle", lib_gle)): ("gle", lib_gle)):
print("\t", item) print("\t", item)
...@@ -33,24 +29,11 @@ if is_resource_enabled("printing"): ...@@ -33,24 +29,11 @@ if is_resource_enabled("printing"):
# On some systems, loading the OpenGL libraries needs the RTLD_GLOBAL mode. # On some systems, loading the OpenGL libraries needs the RTLD_GLOBAL mode.
class Test_OpenGL_libs(unittest.TestCase): class Test_OpenGL_libs(unittest.TestCase):
def setUp(self): def setUp(self):
self.gl = self.glu = self.gle = self.glut = None self.gl = self.glu = self.gle = None
if lib_gl: if lib_gl:
self.gl = CDLL(lib_gl, mode=RTLD_GLOBAL) self.gl = CDLL(lib_gl, mode=RTLD_GLOBAL)
if lib_glu: if lib_glu:
self.glu = CDLL(lib_glu, RTLD_GLOBAL) self.glu = CDLL(lib_glu, RTLD_GLOBAL)
if lib_glut:
# On some systems, additional libraries seem to be
# required, loading glut fails with
# "OSError: /usr/lib/libglut.so.3: undefined symbol: XGetExtensionVersion"
# I cannot figure out how to repair the test on these
# systems (red hat), so we ignore it when the glut or gle
# libraries cannot be loaded. See also:
# https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1478253&group_id=5470
# http://mail.python.org/pipermail/python-dev/2006-May/064789.html
try:
self.glut = CDLL(lib_glut)
except OSError:
pass
if lib_gle: if lib_gle:
try: try:
self.gle = CDLL(lib_gle) self.gle = CDLL(lib_gle)
...@@ -67,11 +50,6 @@ class Test_OpenGL_libs(unittest.TestCase): ...@@ -67,11 +50,6 @@ class Test_OpenGL_libs(unittest.TestCase):
if self.glu: if self.glu:
self.glu.gluBeginCurve self.glu.gluBeginCurve
if lib_glut:
def test_glut(self):
if self.glut:
self.glut.glutWireTetrahedron
if lib_gle: if lib_gle:
def test_gle(self): def test_gle(self):
if self.gle: if self.gle:
......
...@@ -58,6 +58,15 @@ if sys.platform == "win32": ...@@ -58,6 +58,15 @@ if sys.platform == "win32":
self.failUnlessEqual(sizeof(wintypes.LPARAM), self.failUnlessEqual(sizeof(wintypes.LPARAM),
sizeof(c_void_p)) sizeof(c_void_p))
def test_COMError(self):
from _ctypes import COMError
self.assertEqual(COMError.__doc__, "Raised when a COM method call failed.")
ex = COMError(-1, "text", ("details",))
self.assertEqual(ex.hresult, -1)
self.assertEqual(ex.text, "text")
self.assertEqual(ex.details, ("details",))
class Structures(unittest.TestCase): class Structures(unittest.TestCase):
def test_struct_by_value(self): def test_struct_by_value(self):
......
...@@ -1491,6 +1491,18 @@ counter to RFC 2822, there's no separating newline here ...@@ -1491,6 +1491,18 @@ counter to RFC 2822, there's no separating newline here
self.failUnless(isinstance(bad.defects[0], self.failUnless(isinstance(bad.defects[0],
Errors.StartBoundaryNotFoundDefect)) Errors.StartBoundaryNotFoundDefect))
def test_first_line_is_continuation_header(self):
eq = self.assertEqual
m = ' Line 1\nLine 2\nLine 3'
msg = email.message_from_string(m)
eq(msg.keys(), [])
eq(msg.get_payload(), 'Line 2\nLine 3')
eq(len(msg.defects), 1)
self.failUnless(isinstance(msg.defects[0],
Errors.FirstHeaderLineIsContinuationDefect))
eq(msg.defects[0].line, ' Line 1\n')
# Test RFC 2047 header encoding and decoding # Test RFC 2047 header encoding and decoding
......
...@@ -1489,6 +1489,17 @@ counter to RFC 2822, there's no separating newline here ...@@ -1489,6 +1489,17 @@ counter to RFC 2822, there's no separating newline here
self.failUnless(isinstance(bad.defects[0], self.failUnless(isinstance(bad.defects[0],
errors.StartBoundaryNotFoundDefect)) errors.StartBoundaryNotFoundDefect))
def test_first_line_is_continuation_header(self):
eq = self.assertEqual
m = ' Line 1\nLine 2\nLine 3'
msg = email.message_from_string(m)
eq(msg.keys(), [])
eq(msg.get_payload(), 'Line 2\nLine 3')
eq(len(msg.defects), 1)
self.failUnless(isinstance(msg.defects[0],
errors.FirstHeaderLineIsContinuationDefect))
eq(msg.defects[0].line, ' Line 1\n')
# Test RFC 2047 header encoding and decoding # Test RFC 2047 header encoding and decoding
......
...@@ -44,7 +44,7 @@ class FileList: ...@@ -44,7 +44,7 @@ class FileList:
return self.EditorWindow(self, filename) return self.EditorWindow(self, filename)
def close_all_callback(self, event): def close_all_callback(self, event):
for edit in self.inversedict.keys(): for edit in list(self.inversedict):
reply = edit.close() reply = edit.close()
if reply == "cancel": if reply == "cancel":
break break
......
...@@ -105,18 +105,32 @@ class _SimpleBinder: ...@@ -105,18 +105,32 @@ class _SimpleBinder:
# _state_subsets gives for each combination of modifiers, or *state*, # _state_subsets gives for each combination of modifiers, or *state*,
# a list of the states which are a subset of it. This list is ordered by the # a list of the states which are a subset of it. This list is ordered by the
# number of modifiers is the state - the most specific state comes first. # number of modifiers is the state - the most specific state comes first.
# XXX rewrite without overusing functional primitives :-)
_states = range(1 << len(_modifiers)) _states = range(1 << len(_modifiers))
_state_names = [''.join(m[0]+'-' _state_names = [''.join(m[0]+'-'
for i, m in enumerate(_modifiers) for i, m in enumerate(_modifiers)
if (1 << i) & s) if (1 << i) & s)
for s in _states] for s in _states]
_state_subsets = map(lambda i: filter(lambda j: not (j & (~i)), _states),
_states) def expand_substates(states):
for l in _state_subsets: '''For each item of states return a list containing all combinations of
l.sort(lambda a, b, nummod = lambda x: len(filter(lambda i: (1<<i) & x, that item with individual bits reset, sorted by the number of set bits.
range(len(_modifiers)))): '''
nummod(b) - nummod(a)) def nbits(n):
"number of bits set in n base 2"
nb = 0
while n:
n, rem = divmod(n, 2)
nb += rem
return nb
statelist = []
for state in states:
substates = list(set(state & x for x in states))
substates.sort(lambda a,b: nbits(b) - nbits(a))
statelist.append(substates)
return statelist
_state_subsets = expand_substates(_states)
# _state_codes gives for each state, the portable code to be passed as mc_state # _state_codes gives for each state, the portable code to be passed as mc_state
_state_codes = [] _state_codes = []
for s in _states: for s in _states:
......
...@@ -351,8 +351,6 @@ class ModifiedInterpreter(InteractiveInterpreter): ...@@ -351,8 +351,6 @@ class ModifiedInterpreter(InteractiveInterpreter):
def build_subprocess_arglist(self): def build_subprocess_arglist(self):
w = ['-W' + s for s in sys.warnoptions] w = ['-W' + s for s in sys.warnoptions]
if 1/2 > 0: # account for new division
w.append('-Qnew')
# Maybe IDLE is installed and is being accessed via sys.path, # Maybe IDLE is installed and is being accessed via sys.path,
# or maybe it's not installed and the idle.py script is being # or maybe it's not installed and the idle.py script is being
# run from the IDLE source directory. # run from the IDLE source directory.
......
...@@ -19,7 +19,7 @@ class WidgetRedirector: ...@@ -19,7 +19,7 @@ class WidgetRedirector:
self.widget._w) self.widget._w)
def close(self): def close(self):
for name in self.dict.keys(): for name in list(self.dict.keys()):
self.unregister(name) self.unregister(name)
widget = self.widget; del self.widget widget = self.widget; del self.widget
orig = self.orig; del self.orig orig = self.orig; del self.orig
......
IDLE_VERSION = "2.6a0" IDLE_VERSION = "3.0x"
...@@ -3,6 +3,7 @@ A number of function that enhance IDLE on MacOSX when it used as a normal ...@@ -3,6 +3,7 @@ A number of function that enhance IDLE on MacOSX when it used as a normal
GUI application (as opposed to an X11 application). GUI application (as opposed to an X11 application).
""" """
import sys import sys
import Tkinter
def runningAsOSXApp(): def runningAsOSXApp():
""" Returns True iff running from the IDLE.app bundle on OSX """ """ Returns True iff running from the IDLE.app bundle on OSX """
...@@ -23,7 +24,11 @@ def addOpenEventSupport(root, flist): ...@@ -23,7 +24,11 @@ def addOpenEventSupport(root, flist):
root.createcommand("::tk::mac::OpenDocument", doOpenFile) root.createcommand("::tk::mac::OpenDocument", doOpenFile)
def hideTkConsole(root): def hideTkConsole(root):
try:
root.tk.call('console', 'hide') root.tk.call('console', 'hide')
except Tkinter.TclError:
# Some versions of the Tk framework don't have a console object
pass
def overrideRootMenu(root, flist): def overrideRootMenu(root, flist):
""" """
...@@ -75,15 +80,27 @@ def overrideRootMenu(root, flist): ...@@ -75,15 +80,27 @@ def overrideRootMenu(root, flist):
import configDialog import configDialog
configDialog.ConfigDialog(root, 'Settings') configDialog.ConfigDialog(root, 'Settings')
root.bind('<<about-idle>>', about_dialog) root.bind('<<about-idle>>', about_dialog)
root.bind('<<open-config-dialog>>', config_dialog) root.bind('<<open-config-dialog>>', config_dialog)
if flist: if flist:
root.bind('<<close-all-windows>>', flist.close_all_callback) root.bind('<<close-all-windows>>', flist.close_all_callback)
###check if Tk version >= 8.4.14; if so, use hard-coded showprefs binding
tkversion = root.tk.eval('info patchlevel')
if tkversion >= '8.4.14':
Bindings.menudefs[0] = ('application', [
('About IDLE', '<<about-idle>>'),
None,
])
root.createcommand('::tk::mac::ShowPreferences', config_dialog)
else:
for mname, entrylist in Bindings.menudefs: for mname, entrylist in Bindings.menudefs:
menu = menudict.get(mname) menu = menudict.get(mname)
if not menu: if not menu:
continue continue
else:
for entry in entrylist: for entry in entrylist:
if not entry: if not entry:
menu.add_separator() menu.add_separator()
...@@ -97,10 +114,6 @@ def overrideRootMenu(root, flist): ...@@ -97,10 +114,6 @@ def overrideRootMenu(root, flist):
menu.add_command(label=label, underline=underline, menu.add_command(label=label, underline=underline,
command=command, accelerator=accelerator) command=command, accelerator=accelerator)
def setupApp(root, flist): def setupApp(root, flist):
""" """
Perform setup for the OSX application bundle. Perform setup for the OSX application bundle.
......
...@@ -690,7 +690,6 @@ def _getfullargs(co): ...@@ -690,7 +690,6 @@ def _getfullargs(co):
if not iscode(co): if not iscode(co):
raise TypeError('arg is not a code object') raise TypeError('arg is not a code object')
code = co.co_code
nargs = co.co_argcount nargs = co.co_argcount
names = co.co_varnames names = co.co_varnames
nkwargs = co.co_kwonlyargcount nkwargs = co.co_kwonlyargcount
......
...@@ -1680,7 +1680,7 @@ class Tk(Misc, Wm): ...@@ -1680,7 +1680,7 @@ class Tk(Misc, Wm):
def destroy(self): def destroy(self):
"""Destroy this and all descendants widgets. This will """Destroy this and all descendants widgets. This will
end the application of this Tcl interpreter.""" end the application of this Tcl interpreter."""
for c in self.children.values(): c.destroy() for c in list(self.children.values()): c.destroy()
self.tk.call('destroy', self._w) self.tk.call('destroy', self._w)
Misc.destroy(self) Misc.destroy(self)
global _default_root global _default_root
......
...@@ -107,7 +107,7 @@ class Mailbox: ...@@ -107,7 +107,7 @@ class Mailbox:
yield value yield value
def __iter__(self): def __iter__(self):
return self.values() return self.itervalues()
def values(self): def values(self):
"""Return a list of messages. Memory intensive.""" """Return a list of messages. Memory intensive."""
...@@ -456,7 +456,11 @@ class Maildir(Mailbox): ...@@ -456,7 +456,11 @@ class Maildir(Mailbox):
"""Update table of contents mapping.""" """Update table of contents mapping."""
self._toc = {} self._toc = {}
for subdir in ('new', 'cur'): for subdir in ('new', 'cur'):
for entry in os.listdir(os.path.join(self._path, subdir)): subdir_path = os.path.join(self._path, subdir)
for entry in os.listdir(subdir_path):
p = os.path.join(subdir_path, entry)
if os.path.isdir(p):
continue
uniq = entry.split(self.colon)[0] uniq = entry.split(self.colon)[0]
self._toc[uniq] = os.path.join(subdir, entry) self._toc[uniq] = os.path.join(subdir, entry)
......
This diff is collapsed.
This diff is collapsed.
...@@ -9,6 +9,7 @@ maxsize = MAX_Py_ssize_t ...@@ -9,6 +9,7 @@ maxsize = MAX_Py_ssize_t
# test on unicode strings as well # test on unicode strings as well
overflowok = 1 overflowok = 1
overflowrequired = 0
def testformat(formatstr, args, output=None): def testformat(formatstr, args, output=None):
if verbose: if verbose:
...@@ -25,7 +26,11 @@ def testformat(formatstr, args, output=None): ...@@ -25,7 +26,11 @@ def testformat(formatstr, args, output=None):
if verbose: if verbose:
print('overflow (this is fine)') print('overflow (this is fine)')
else: else:
if output and result != output: if overflowrequired:
if verbose:
print('no')
print("overflow expected on %r %% %r" % (formatstr, args))
elif output and result != output:
if verbose: if verbose:
print('no') print('no')
print("%r %% %r == %r != %r" %\ print("%r %% %r == %r != %r" %\
...@@ -56,6 +61,14 @@ testboth("%#.*g", (110, -1.e+100/3.)) ...@@ -56,6 +61,14 @@ testboth("%#.*g", (110, -1.e+100/3.))
# test some ridiculously large precision, expect overflow # test some ridiculously large precision, expect overflow
testboth('%12.*f', (123456, 1.0)) testboth('%12.*f', (123456, 1.0))
# check for internal overflow validation on length of precision
overflowrequired = 1
testboth("%#.*g", (110, -1.e+100/3.))
testboth("%#.*G", (110, -1.e+100/3.))
testboth("%#.*f", (110, -1.e+100/3.))
testboth("%#.*F", (110, -1.e+100/3.))
overflowrequired = 0
# Formatting of long integers. Overflow is not ok # Formatting of long integers. Overflow is not ok
overflowok = 0 overflowok = 0
testboth("%x", 10, "a") testboth("%x", 10, "a")
......
...@@ -697,6 +697,20 @@ class GrammarTests(unittest.TestCase): ...@@ -697,6 +697,20 @@ class GrammarTests(unittest.TestCase):
def meth2(self, arg): pass def meth2(self, arg): pass
def meth3(self, a1, a2): pass def meth3(self, a1, a2): pass
# decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
# decorators: decorator+
# decorated: decorators (classdef | funcdef)
def class_decorator(x): return x
@class_decorator
class G: pass
def testDictcomps(self):
# dictorsetmaker: ( (test ':' test (comp_for |
# (',' test ':' test)* [','])) |
# (test (comp_for | (',' test)* [','])) )
nums = [1, 2, 3]
self.assertEqual({i:i+1 for i in nums}, {1: 2, 2: 3, 3: 4})
def testListcomps(self): def testListcomps(self):
# list comprehension tests # list comprehension tests
nums = [1, 2, 3, 4, 5] nums = [1, 2, 3, 4, 5]
......
...@@ -427,8 +427,8 @@ class TestMailboxSuperclass(TestBase): ...@@ -427,8 +427,8 @@ class TestMailboxSuperclass(TestBase):
self.assertRaises(NotImplementedError, lambda: box.__setitem__('', '')) self.assertRaises(NotImplementedError, lambda: box.__setitem__('', ''))
self.assertRaises(NotImplementedError, lambda: box.keys()) self.assertRaises(NotImplementedError, lambda: box.keys())
self.assertRaises(NotImplementedError, lambda: box.keys()) self.assertRaises(NotImplementedError, lambda: box.keys())
self.assertRaises(NotImplementedError, lambda: box.values().next()) self.assertRaises(NotImplementedError, lambda: box.values().__next__())
self.assertRaises(NotImplementedError, lambda: box.__iter__().next()) self.assertRaises(NotImplementedError, lambda: box.__iter__().__next__())
self.assertRaises(NotImplementedError, lambda: box.values()) self.assertRaises(NotImplementedError, lambda: box.values())
self.assertRaises(NotImplementedError, lambda: box.items().next()) self.assertRaises(NotImplementedError, lambda: box.items().next())
self.assertRaises(NotImplementedError, lambda: box.items()) self.assertRaises(NotImplementedError, lambda: box.items())
...@@ -679,7 +679,18 @@ class TestMaildir(TestMailbox): ...@@ -679,7 +679,18 @@ class TestMaildir(TestMailbox):
folder1_alias = box.get_folder('folder1') folder1_alias = box.get_folder('folder1')
self.assert_(folder1_alias._factory is dummy_factory) self.assert_(folder1_alias._factory is dummy_factory)
def test_directory_in_folder (self):
# Test that mailboxes still work if there's a stray extra directory
# in a folder.
for i in range(10):
self._box.add(mailbox.Message(_sample_message))
# Create a stray directory
os.mkdir(os.path.join(self._path, 'cur', 'stray-dir'))
# Check that looping still works with the directory present.
for msg in self._box:
pass
class _TestMboxMMDF(TestMailbox): class _TestMboxMMDF(TestMailbox):
......
...@@ -443,6 +443,12 @@ class CompileTestCase(unittest.TestCase): ...@@ -443,6 +443,12 @@ class CompileTestCase(unittest.TestCase):
st = parser.suite('1 = 3 + 4') st = parser.suite('1 = 3 + 4')
self.assertRaises(SyntaxError, parser.compilest, st) self.assertRaises(SyntaxError, parser.compilest, st)
def test_compile_badunicode(self):
st = parser.suite('a = u"\U12345678"')
self.assertRaises(SyntaxError, parser.compilest, st)
st = parser.suite('a = u"\u1"')
self.assertRaises(SyntaxError, parser.compilest, st)
def test_main(): def test_main():
test_support.run_unittest( test_support.run_unittest(
RoundtripLegalSyntaxTestCase, RoundtripLegalSyntaxTestCase,
......
...@@ -380,6 +380,12 @@ class MockPasswordManager: ...@@ -380,6 +380,12 @@ class MockPasswordManager:
class OpenerDirectorTests(unittest.TestCase): class OpenerDirectorTests(unittest.TestCase):
def test_add_non_handler(self):
class NonHandler(object):
pass
self.assertRaises(TypeError,
OpenerDirector().add_handler, NonHandler())
def test_badly_named_methods(self): def test_badly_named_methods(self):
# test work-around for three methods that accidentally follow the # test work-around for three methods that accidentally follow the
# naming conventions for handler methods # naming conventions for handler methods
......
import base64
import datetime import datetime
import sys import sys
import time
import unittest import unittest
import xmlrpclib import xmlrpclib
from test import test_support from test import test_support
...@@ -18,6 +20,10 @@ alist = [{'astring': 'foo@bar.baz.spam', ...@@ -18,6 +20,10 @@ alist = [{'astring': 'foo@bar.baz.spam',
(2005, 2, 10, 11, 41, 23, 0, 1, -1)), (2005, 2, 10, 11, 41, 23, 0, 1, -1)),
'datetime3': xmlrpclib.DateTime( 'datetime3': xmlrpclib.DateTime(
datetime.datetime(2005, 2, 10, 11, 41, 23)), datetime.datetime(2005, 2, 10, 11, 41, 23)),
'datetime4': xmlrpclib.DateTime(
datetime.date(2005, 2, 10)),
'datetime5': xmlrpclib.DateTime(
datetime.time(11, 41, 23)),
}] }]
class XMLRPCTestCase(unittest.TestCase): class XMLRPCTestCase(unittest.TestCase):
...@@ -94,11 +100,37 @@ class XMLRPCTestCase(unittest.TestCase): ...@@ -94,11 +100,37 @@ class XMLRPCTestCase(unittest.TestCase):
def test_dump_bad_dict(self): def test_dump_bad_dict(self):
self.assertRaises(TypeError, xmlrpclib.dumps, ({(1,2,3): 1},)) self.assertRaises(TypeError, xmlrpclib.dumps, ({(1,2,3): 1},))
def test_dump_recursive_seq(self):
l = [1,2,3]
t = [3,4,5,l]
l.append(t)
self.assertRaises(TypeError, xmlrpclib.dumps, (l,))
def test_dump_recursive_dict(self):
d = {'1':1, '2':1}
t = {'3':3, 'd':d}
d['t'] = t
self.assertRaises(TypeError, xmlrpclib.dumps, (d,))
def test_dump_big_int(self): def test_dump_big_int(self):
if sys.maxint > 2**31-1: if sys.maxint > 2**31-1:
self.assertRaises(OverflowError, xmlrpclib.dumps, self.assertRaises(OverflowError, xmlrpclib.dumps,
(int(2**34),)) (int(2**34),))
xmlrpclib.dumps((xmlrpclib.MAXINT, xmlrpclib.MININT))
self.assertRaises(OverflowError, xmlrpclib.dumps, (xmlrpclib.MAXINT+1,))
self.assertRaises(OverflowError, xmlrpclib.dumps, (xmlrpclib.MININT-1,))
def dummy_write(s):
pass
m = xmlrpclib.Marshaller()
m.dump_int(xmlrpclib.MAXINT, dummy_write)
m.dump_int(xmlrpclib.MININT, dummy_write)
self.assertRaises(OverflowError, m.dump_int, xmlrpclib.MAXINT+1, dummy_write)
self.assertRaises(OverflowError, m.dump_int, xmlrpclib.MININT-1, dummy_write)
def test_dump_none(self): def test_dump_none(self):
value = alist + [None] value = alist + [None]
arg1 = (alist + [None],) arg1 = (alist + [None],)
...@@ -146,8 +178,109 @@ class XMLRPCTestCase(unittest.TestCase): ...@@ -146,8 +178,109 @@ class XMLRPCTestCase(unittest.TestCase):
self.assert_(isinstance(items[0][0], str)) self.assert_(isinstance(items[0][0], str))
self.assert_(isinstance(items[0][1], str)) self.assert_(isinstance(items[0][1], str))
class HelperTestCase(unittest.TestCase):
def test_escape(self):
self.assertEqual(xmlrpclib.escape("a&b"), "a&amp;b")
self.assertEqual(xmlrpclib.escape("a<b"), "a&lt;b")
self.assertEqual(xmlrpclib.escape("a>b"), "a&gt;b")
class FaultTestCase(unittest.TestCase):
def test_repr(self):
f = xmlrpclib.Fault(42, 'Test Fault')
self.assertEqual(repr(f), "<Fault 42: 'Test Fault'>")
self.assertEqual(repr(f), str(f))
def test_dump_fault(self):
f = xmlrpclib.Fault(42, 'Test Fault')
s = xmlrpclib.dumps((f,))
(newf,), m = xmlrpclib.loads(s)
self.assertEquals(newf, {'faultCode': 42, 'faultString': 'Test Fault'})
self.assertEquals(m, None)
s = xmlrpclib.Marshaller().dumps(f)
self.assertRaises(xmlrpclib.Fault, xmlrpclib.loads, s)
class DateTimeTestCase(unittest.TestCase):
def test_default(self):
t = xmlrpclib.DateTime()
def test_time(self):
d = 1181399930.036952
t = xmlrpclib.DateTime(d)
self.assertEqual(str(t), time.strftime("%Y%m%dT%H:%M:%S", time.localtime(d)))
def test_time_tuple(self):
d = (2007,6,9,10,38,50,5,160,0)
t = xmlrpclib.DateTime(d)
self.assertEqual(str(t), '20070609T10:38:50')
def test_time_struct(self):
d = time.localtime(1181399930.036952)
t = xmlrpclib.DateTime(d)
self.assertEqual(str(t), time.strftime("%Y%m%dT%H:%M:%S", d))
def test_datetime_datetime(self):
d = datetime.datetime(2007,1,2,3,4,5)
t = xmlrpclib.DateTime(d)
self.assertEqual(str(t), '20070102T03:04:05')
def test_datetime_date(self):
d = datetime.date(2007,9,8)
t = xmlrpclib.DateTime(d)
self.assertEqual(str(t), '20070908T00:00:00')
def test_datetime_time(self):
d = datetime.time(13,17,19)
# allow for date rollover by checking today's or tomorrow's dates
dd1 = datetime.datetime.now().date()
dd2 = dd1 + datetime.timedelta(days=1)
vals = (dd1.strftime('%Y%m%dT13:17:19'),
dd2.strftime('%Y%m%dT13:17:19'))
t = xmlrpclib.DateTime(d)
self.assertEqual(str(t) in vals, True)
def test_repr(self):
d = datetime.datetime(2007,1,2,3,4,5)
t = xmlrpclib.DateTime(d)
val ="<DateTime '20070102T03:04:05' at %x>" % id(t)
self.assertEqual(repr(t), val)
def test_decode(self):
d = ' 20070908T07:11:13 '
t1 = xmlrpclib.DateTime()
t1.decode(d)
tref = xmlrpclib.DateTime(datetime.datetime(2007,9,8,7,11,13))
self.assertEqual(t1, tref)
t2 = xmlrpclib._datetime(d)
self.assertEqual(t1, tref)
class BinaryTestCase(unittest.TestCase):
def test_default(self):
t = xmlrpclib.Binary()
self.assertEqual(str(t), '')
def test_string(self):
d = '\x01\x02\x03abc123\xff\xfe'
t = xmlrpclib.Binary(d)
self.assertEqual(str(t), d)
def test_decode(self):
d = '\x01\x02\x03abc123\xff\xfe'
de = base64.encodestring(d)
t1 = xmlrpclib.Binary()
t1.decode(de)
self.assertEqual(str(t1), d)
t2 = xmlrpclib._binary(de)
self.assertEqual(str(t2), d)
def test_main(): def test_main():
test_support.run_unittest(XMLRPCTestCase) test_support.run_unittest(XMLRPCTestCase, HelperTestCase,
DateTimeTestCase, BinaryTestCase, FaultTestCase)
if __name__ == "__main__": if __name__ == "__main__":
......
...@@ -12,7 +12,7 @@ import test.test_support as support ...@@ -12,7 +12,7 @@ import test.test_support as support
from test.test_support import TESTFN, run_unittest from test.test_support import TESTFN, run_unittest
TESTFN2 = TESTFN + "2" TESTFN2 = TESTFN + "2"
FIXEDTEST_SIZE = 10 FIXEDTEST_SIZE = 1000
class TestsWithSourceFile(unittest.TestCase): class TestsWithSourceFile(unittest.TestCase):
def setUp(self): def setUp(self):
...@@ -232,6 +232,63 @@ class TestsWithSourceFile(unittest.TestCase): ...@@ -232,6 +232,63 @@ class TestsWithSourceFile(unittest.TestCase):
self.assertEqual(zipfp.namelist(), ["absolute"]) self.assertEqual(zipfp.namelist(), ["absolute"])
zipfp.close() zipfp.close()
def testAppendToZipFile(self):
# Test appending to an existing zipfile
zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED)
zipfp.write(TESTFN, TESTFN)
zipfp.close()
zipfp = zipfile.ZipFile(TESTFN2, "a", zipfile.ZIP_STORED)
zipfp.writestr("strfile", self.data)
self.assertEqual(zipfp.namelist(), [TESTFN, "strfile"])
zipfp.close()
def testAppendToNonZipFile(self):
# Test appending to an existing file that is not a zipfile
# NOTE: this test fails if len(d) < 22 because of the first
# line "fpin.seek(-22, 2)" in _EndRecData
d = 'I am not a ZipFile!'*10
f = file(TESTFN2, 'wb')
f.write(d)
f.close()
zipfp = zipfile.ZipFile(TESTFN2, "a", zipfile.ZIP_STORED)
zipfp.write(TESTFN, TESTFN)
zipfp.close()
f = file(TESTFN2, 'rb')
f.seek(len(d))
zipfp = zipfile.ZipFile(f, "r")
self.assertEqual(zipfp.namelist(), [TESTFN])
zipfp.close()
f.close()
def test_WriteDefaultName(self):
# Check that calling ZipFile.write without arcname specified produces the expected result
zipfp = zipfile.ZipFile(TESTFN2, "w")
zipfp.write(TESTFN)
self.assertEqual(zipfp.read(TESTFN), file(TESTFN).read())
zipfp.close()
def test_PerFileCompression(self):
# Check that files within a Zip archive can have different compression options
zipfp = zipfile.ZipFile(TESTFN2, "w")
zipfp.write(TESTFN, 'storeme', zipfile.ZIP_STORED)
zipfp.write(TESTFN, 'deflateme', zipfile.ZIP_DEFLATED)
sinfo = zipfp.getinfo('storeme')
dinfo = zipfp.getinfo('deflateme')
self.assertEqual(sinfo.compress_type, zipfile.ZIP_STORED)
self.assertEqual(dinfo.compress_type, zipfile.ZIP_DEFLATED)
zipfp.close()
def test_WriteToReadonly(self):
# Check that trying to call write() on a readonly ZipFile object
# raises a RuntimeError
zipf = zipfile.ZipFile(TESTFN2, mode="w")
zipf.writestr("somefile.txt", "bogus")
zipf.close()
zipf = zipfile.ZipFile(TESTFN2, mode="r")
self.assertRaises(RuntimeError, zipf.write, TESTFN)
zipf.close()
def tearDown(self): def tearDown(self):
os.remove(TESTFN) os.remove(TESTFN)
os.remove(TESTFN2) os.remove(TESTFN2)
...@@ -349,7 +406,6 @@ class TestZip64InSmallFiles(unittest.TestCase): ...@@ -349,7 +406,6 @@ class TestZip64InSmallFiles(unittest.TestCase):
self.assertEqual(zipfp.namelist(), ["absolute"]) self.assertEqual(zipfp.namelist(), ["absolute"])
zipfp.close() zipfp.close()
def tearDown(self): def tearDown(self):
zipfile.ZIP64_LIMIT = self._limit zipfile.ZIP64_LIMIT = self._limit
os.remove(TESTFN) os.remove(TESTFN)
...@@ -420,6 +476,11 @@ class PyZipFileTests(unittest.TestCase): ...@@ -420,6 +476,11 @@ class PyZipFileTests(unittest.TestCase):
finally: finally:
shutil.rmtree(TESTFN2) shutil.rmtree(TESTFN2)
def testWriteNonPyfile(self):
zipfp = zipfile.PyZipFile(TemporaryFile(), "w")
file(TESTFN, 'w').write('most definitely not a python file')
self.assertRaises(RuntimeError, zipfp.writepy, TESTFN)
os.remove(TESTFN)
class OtherTests(unittest.TestCase): class OtherTests(unittest.TestCase):
...@@ -501,7 +562,56 @@ class OtherTests(unittest.TestCase): ...@@ -501,7 +562,56 @@ class OtherTests(unittest.TestCase):
# a RuntimeError, and so should calling .testzip. An earlier # a RuntimeError, and so should calling .testzip. An earlier
# version of .testzip would swallow this exception (and any other) # version of .testzip would swallow this exception (and any other)
# and report that the first file in the archive was corrupt. # and report that the first file in the archive was corrupt.
self.assertRaises(RuntimeError, zipf.read, "foo.txt")
self.assertRaises(RuntimeError, zipf.open, "foo.txt")
self.assertRaises(RuntimeError, zipf.testzip) self.assertRaises(RuntimeError, zipf.testzip)
self.assertRaises(RuntimeError, zipf.writestr, "bogus.txt", "bogus")
file(TESTFN, 'w').write('zipfile test data')
self.assertRaises(RuntimeError, zipf.write, TESTFN)
def test_BadConstructorMode(self):
# Check that bad modes passed to ZipFile constructor are caught
self.assertRaises(RuntimeError, zipfile.ZipFile, TESTFN, "q")
def test_BadOpenMode(self):
# Check that bad modes passed to ZipFile.open are caught
zipf = zipfile.ZipFile(TESTFN, mode="w")
zipf.writestr("foo.txt", "O, for a Muse of Fire!")
zipf.close()
zipf = zipfile.ZipFile(TESTFN, mode="r")
# read the data to make sure the file is there
zipf.read("foo.txt")
self.assertRaises(RuntimeError, zipf.open, "foo.txt", "q")
zipf.close()
def test_Read0(self):
# Check that calling read(0) on a ZipExtFile object returns an empty
# string and doesn't advance file pointer
zipf = zipfile.ZipFile(TESTFN, mode="w")
zipf.writestr("foo.txt", "O, for a Muse of Fire!")
# read the data to make sure the file is there
f = zipf.open("foo.txt")
for i in range(FIXEDTEST_SIZE):
self.assertEqual(f.read(0), '')
self.assertEqual(f.read(), "O, for a Muse of Fire!")
zipf.close()
def test_OpenNonexistentItem(self):
# Check that attempting to call open() for an item that doesn't
# exist in the archive raises a RuntimeError
zipf = zipfile.ZipFile(TESTFN, mode="w")
self.assertRaises(KeyError, zipf.open, "foo.txt", "r")
def test_BadCompressionMode(self):
# Check that bad compression methods passed to ZipFile.open are caught
self.assertRaises(RuntimeError, zipfile.ZipFile, TESTFN, "w", -1)
def test_NullByteInFilename(self):
# Check that a filename containing a null byte is properly terminated
zipf = zipfile.ZipFile(TESTFN, mode="w")
zipf.writestr("foo.txt\x00qqq", "O, for a Muse of Fire!")
self.assertEqual(zipf.namelist(), ['foo.txt'])
def tearDown(self): def tearDown(self):
support.unlink(TESTFN) support.unlink(TESTFN)
......
...@@ -293,6 +293,10 @@ class OpenerDirector: ...@@ -293,6 +293,10 @@ class OpenerDirector:
self.process_request = {} self.process_request = {}
def add_handler(self, handler): def add_handler(self, handler):
if not hasattr(handler, "add_parent"):
raise TypeError("expected BaseHandler instance, got %r" %
type(handler))
added = False added = False
for meth in dir(handler): for meth in dir(handler):
if meth in ["redirect_request", "do_open", "proxy_open"]: if meth in ["redirect_request", "do_open", "proxy_open"]:
......
...@@ -574,8 +574,9 @@ class ZipFile: ...@@ -574,8 +574,9 @@ class ZipFile:
def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=False): def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=False):
"""Open the ZIP file with mode read "r", write "w" or append "a".""" """Open the ZIP file with mode read "r", write "w" or append "a"."""
self._allowZip64 = allowZip64 if mode not in ("r", "w", "a"):
self._didModify = False raise RuntimeError('ZipFile() requires mode "r", "w", or "a"')
if compression == ZIP_STORED: if compression == ZIP_STORED:
pass pass
elif compression == ZIP_DEFLATED: elif compression == ZIP_DEFLATED:
...@@ -584,6 +585,9 @@ class ZipFile: ...@@ -584,6 +585,9 @@ class ZipFile:
"Compression requires the (missing) zlib module" "Compression requires the (missing) zlib module"
else: else:
raise RuntimeError, "That compression method is not supported" raise RuntimeError, "That compression method is not supported"
self._allowZip64 = allowZip64
self._didModify = False
self.debug = 0 # Level of printing: 0 through 3 self.debug = 0 # Level of printing: 0 through 3
self.NameToInfo = {} # Find file info given name self.NameToInfo = {} # Find file info given name
self.filelist = [] # List of ZipInfo instances for archive self.filelist = [] # List of ZipInfo instances for archive
...@@ -729,7 +733,12 @@ class ZipFile: ...@@ -729,7 +733,12 @@ class ZipFile:
def getinfo(self, name): def getinfo(self, name):
"""Return the instance of ZipInfo given 'name'.""" """Return the instance of ZipInfo given 'name'."""
return self.NameToInfo[name] info = self.NameToInfo.get(name)
if info is None:
raise KeyError(
'There is no item named %r in the archive' % name)
return info
def setpassword(self, pwd): def setpassword(self, pwd):
"""Set default password for encrypted files.""" """Set default password for encrypted files."""
...@@ -834,6 +843,10 @@ class ZipFile: ...@@ -834,6 +843,10 @@ class ZipFile:
def write(self, filename, arcname=None, compress_type=None): def write(self, filename, arcname=None, compress_type=None):
"""Put the bytes from filename into the archive under the name """Put the bytes from filename into the archive under the name
arcname.""" arcname."""
if not self.fp:
raise RuntimeError(
"Attempt to write to ZIP archive that was already closed")
st = os.stat(filename) st = os.stat(filename)
mtime = time.localtime(st.st_mtime) mtime = time.localtime(st.st_mtime)
date_time = mtime[0:6] date_time = mtime[0:6]
...@@ -906,6 +919,11 @@ class ZipFile: ...@@ -906,6 +919,11 @@ class ZipFile:
zinfo.compress_type = self.compression zinfo.compress_type = self.compression
else: else:
zinfo = zinfo_or_arcname zinfo = zinfo_or_arcname
if not self.fp:
raise RuntimeError(
"Attempt to write to ZIP archive that was already closed")
zinfo.file_size = len(bytes) # Uncompressed size zinfo.file_size = len(bytes) # Uncompressed size
zinfo.header_offset = self.fp.tell() # Start of header bytes zinfo.header_offset = self.fp.tell() # Start of header bytes
self._writecheck(zinfo) self._writecheck(zinfo)
......
...@@ -393,7 +393,7 @@ $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK): \ ...@@ -393,7 +393,7 @@ $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK): \
-compatibility_version $(VERSION) \ -compatibility_version $(VERSION) \
-current_version $(VERSION); \ -current_version $(VERSION); \
else \ else \
libtool -o $(LDLIBRARY) -dynamic $(OTHER_LIBTOOL_OPT) $(LIBRARY) \ /usr/bin/libtool -o $(LDLIBRARY) -dynamic $(OTHER_LIBTOOL_OPT) $(LIBRARY) \
@LIBTOOL_CRUFT@ ;\ @LIBTOOL_CRUFT@ ;\
fi fi
$(INSTALL) -d -m $(DIRMODE) \ $(INSTALL) -d -m $(DIRMODE) \
......
...@@ -4466,11 +4466,6 @@ create_comerror(void) ...@@ -4466,11 +4466,6 @@ create_comerror(void)
PyObject *s; PyObject *s;
int status; int status;
ComError = PyErr_NewException("_ctypes.COMError",
NULL,
dict);
if (ComError == NULL)
return -1;
while (methods->ml_name) { while (methods->ml_name) {
/* get a wrapper for the built-in function */ /* get a wrapper for the built-in function */
PyObject *func = PyCFunction_New(methods, NULL); PyObject *func = PyCFunction_New(methods, NULL);
...@@ -4485,13 +4480,24 @@ create_comerror(void) ...@@ -4485,13 +4480,24 @@ create_comerror(void)
Py_DECREF(meth); Py_DECREF(meth);
++methods; ++methods;
} }
Py_INCREF(ComError);
s = PyString_FromString(comerror_doc); s = PyString_FromString(comerror_doc);
if (s == NULL) if (s == NULL)
return -1; return -1;
status = PyDict_SetItemString(dict, "__doc__", s); status = PyDict_SetItemString(dict, "__doc__", s);
Py_DECREF(s); Py_DECREF(s);
return status; if (status == -1) {
Py_DECREF(dict);
return -1;
}
ComError = PyErr_NewException("_ctypes.COMError",
NULL,
dict);
if (ComError == NULL)
return -1;
return 0;
} }
#endif #endif
......
...@@ -264,7 +264,7 @@ ffi_info *AllocFunctionCallback(PyObject *callable, ...@@ -264,7 +264,7 @@ ffi_info *AllocFunctionCallback(PyObject *callable,
ffi_abi cc; ffi_abi cc;
nArgs = PySequence_Size(converters); nArgs = PySequence_Size(converters);
p = (ffi_info *)PyMem_Malloc(sizeof(ffi_info) + sizeof(ffi_type) * (nArgs + 1)); p = (ffi_info *)PyMem_Malloc(sizeof(ffi_info) + sizeof(ffi_type) * (nArgs));
if (p == NULL) { if (p == NULL) {
PyErr_NoMemory(); PyErr_NoMemory();
return NULL; return NULL;
......
...@@ -58,7 +58,7 @@ typedef struct { ...@@ -58,7 +58,7 @@ typedef struct {
PyObject *callable; PyObject *callable;
SETFUNC setfunc; SETFUNC setfunc;
ffi_type *restype; ffi_type *restype;
ffi_type *atypes[0]; ffi_type *atypes[1];
} ffi_info; } ffi_info;
typedef struct { typedef struct {
......
...@@ -457,13 +457,11 @@ StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct) ...@@ -457,13 +457,11 @@ StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct)
if (!prop) { if (!prop) {
Py_DECREF(pair); Py_DECREF(pair);
Py_DECREF((PyObject *)stgdict);
return -1; return -1;
} }
if (-1 == PyDict_SetItem(realdict, name, prop)) { if (-1 == PyDict_SetItem(realdict, name, prop)) {
Py_DECREF(prop); Py_DECREF(prop);
Py_DECREF(pair); Py_DECREF(pair);
Py_DECREF((PyObject *)stgdict);
return -1; return -1;
} }
Py_DECREF(pair); Py_DECREF(pair);
......
...@@ -4156,7 +4156,8 @@ formatfloat(char *buf, size_t buflen, int flags, ...@@ -4156,7 +4156,8 @@ formatfloat(char *buf, size_t buflen, int flags,
always given), therefore increase the length by one. always given), therefore increase the length by one.
*/ */
if ((type == 'g' && buflen <= (size_t)10 + (size_t)prec) || if (((type == 'g' || type == 'G') &&
buflen <= (size_t)10 + (size_t)prec) ||
(type == 'f' && buflen <= (size_t)53 + (size_t)prec)) { (type == 'f' && buflen <= (size_t)53 + (size_t)prec)) {
PyErr_SetString(PyExc_OverflowError, PyErr_SetString(PyExc_OverflowError,
"formatted float is too long (precision too large?)"); "formatted float is too long (precision too large?)");
......
...@@ -7935,7 +7935,8 @@ formatfloat(Py_UNICODE *buf, ...@@ -7935,7 +7935,8 @@ formatfloat(Py_UNICODE *buf,
always given), therefore increase the length by one. always given), therefore increase the length by one.
*/ */
if ((type == 'g' && buflen <= (size_t)10 + (size_t)prec) || if (((type == 'g' || type == 'G') &&
buflen <= (size_t)10 + (size_t)prec) ||
(type == 'f' && buflen <= (size_t)53 + (size_t)prec)) { (type == 'f' && buflen <= (size_t)53 + (size_t)prec)) {
PyErr_SetString(PyExc_OverflowError, PyErr_SetString(PyExc_OverflowError,
"formatted float is too long (precision too large?)"); "formatted float is too long (precision too large?)");
......
...@@ -1271,9 +1271,26 @@ ast_for_atom(struct compiling *c, const node *n) ...@@ -1271,9 +1271,26 @@ ast_for_atom(struct compiling *c, const node *n)
return Name(NEW_IDENTIFIER(ch), Load, LINENO(n), n->n_col_offset, c->c_arena); return Name(NEW_IDENTIFIER(ch), Load, LINENO(n), n->n_col_offset, c->c_arena);
case STRING: { case STRING: {
PyObject *str = parsestrplus(c, n, &bytesmode); PyObject *str = parsestrplus(c, n, &bytesmode);
if (!str) if (!str) {
if (PyErr_ExceptionMatches(PyExc_UnicodeError)){
PyObject *type, *value, *tback, *errstr;
PyErr_Fetch(&type, &value, &tback);
errstr = ((PyUnicodeErrorObject *)value)->reason;
if (errstr) {
char *s = "";
char buf[128];
s = PyString_AsString(errstr);
PyOS_snprintf(buf, sizeof(buf), "(unicode error) %s", s);
ast_error(n, buf);
} else {
ast_error(n, "(unicode error) unknown error");
}
Py_DECREF(type);
Py_DECREF(value);
Py_XDECREF(tback);
}
return NULL; return NULL;
}
PyArena_AddPyObject(c->c_arena, str); PyArena_AddPyObject(c->c_arena, str);
if (bytesmode) if (bytesmode)
return Bytes(str, LINENO(n), n->n_col_offset, c->c_arena); return Bytes(str, LINENO(n), n->n_col_offset, c->c_arena);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment