]> granicus.if.org Git - python/commitdiff
Merged revisions 56301-56442 via svnmerge from
authorGuido van Rossum <guido@python.org>
Wed, 18 Jul 2007 18:15:48 +0000 (18:15 +0000)
committerGuido van Rossum <guido@python.org>
Wed, 18 Jul 2007 18:15:48 +0000 (18:15 +0000)
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.)
  ........
................

42 files changed:
Doc/lib/email.tex
Doc/lib/libitertools.tex
Doc/lib/libnis.tex
Doc/lib/libsubprocess.tex
Doc/lib/libtime.tex
Doc/lib/libwebbrowser.tex
Doc/lib/libzipfile.tex
Doc/tut/tut.tex
Include/opcode.h
Lib/ctypes/__init__.py
Lib/ctypes/test/test_find.py
Lib/ctypes/test/test_win32.py
Lib/email/test/test_email.py
Lib/email/test/test_email_renamed.py
Lib/idlelib/FileList.py
Lib/idlelib/MultiCall.py
Lib/idlelib/PyShell.py
Lib/idlelib/WidgetRedirector.py
Lib/idlelib/idlever.py
Lib/idlelib/macosxSupport.py
Lib/inspect.py
Lib/lib-tk/Tkinter.py
Lib/mailbox.py
Lib/test/regrtest.py
Lib/test/test_asyncore.py [new file with mode: 0644]
Lib/test/test_format.py
Lib/test/test_grammar.py
Lib/test/test_mailbox.py
Lib/test/test_parser.py
Lib/test/test_urllib2.py
Lib/test/test_xmlrpc.py
Lib/test/test_zipfile.py
Lib/urllib2.py
Lib/zipfile.py
Makefile.pre.in
Modules/_ctypes/_ctypes.c
Modules/_ctypes/callbacks.c
Modules/_ctypes/ctypes.h
Modules/_ctypes/stgdict.c
Objects/stringobject.c
Objects/unicodeobject.c
Python/ast.c

index 47727a7a67b698ba7d3a68c4c72ee6f9d3210a9e..3de3df32283b0c71c615185214cb5457680f9103 100644 (file)
@@ -94,7 +94,7 @@ package, a section on differences and porting is provided.
 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
 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
 of the package.
 
index 19bc826e772dc1bb43197f356f071a5c806275b5..b4784a83a7a079ae9f8e1c3b9898a2398fd8151e 100644 (file)
@@ -117,7 +117,7 @@ by functions or loops that truncate the stream.
   Make an iterator that drops elements from the iterable as long as
   the predicate is true; afterwards, returns every element.  Note,
   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}
      def dropwhile(predicate, iterable):
@@ -509,8 +509,8 @@ def iteritems(mapping):
     return izip(mapping.iterkeys(), mapping.itervalues())
 
 def nth(iterable, n):
-    "Returns the nth item or raise IndexError"
-    return list(islice(iterable, n, n+1))[0]
+    "Returns the nth item or raise StopIteration"
+    return islice(iterable, n, None).next()
 
 def all(seq, pred=None):
     "Returns True if pred(x) is true for every element in the iterable"
index cc1482db5657195c7a1b3a74cf1becfec5a1bb6f..fe4acb5d63e63cdf3d5191694285b4bbb47a9c22 100644 (file)
@@ -2,7 +2,7 @@
          Interface to Sun's NIS (Yellow Pages)}
 
 \declaremodule{extension}{nis}
-  \platform{UNIX}
+  \platform{Unix}
 \moduleauthor{Fred Gansevles}{Fred.Gansevles@cs.utwente.nl}
 \sectionauthor{Moshe Zadka}{moshez@zadka.site.co.il}
 \modulesynopsis{Interface to Sun's NIS (Yellow Pages) library.}
index dc386bfb4e7080f150d6637805e3ce18d769ad37..e2a9bb659720e0cc70ff996e0e3ab92f61e11212 100644 (file)
@@ -145,6 +145,8 @@ The arguments are the same as for the Popen constructor.  Example:
 \begin{verbatim}
     check_call(["ls", "-l"])
 \end{verbatim}
+
+\versionadded{2.5}
 \end{funcdesc}
 
 \subsubsection{Exceptions}
index e27604530a620e66e2e8a25437ba7936768b3278..8a45bfcc9c9dec3998a81d1768068d4679baeb93 100644 (file)
@@ -309,15 +309,23 @@ The field width is normally 2 except for \code{\%j} where it is 3.
 \begin{funcdesc}{strptime}{string\optional{, format}}
 Parse a string representing a time according to a format.  The return 
 value is a \class{struct_time} as returned by \function{gmtime()} or
-\function{localtime()}.  The \var{format} parameter uses the same
-directives as those used by \function{strftime()}; it defaults to
-\code{"\%a \%b \%d \%H:\%M:\%S \%Y"} which matches the formatting
-returned by \function{ctime()}.  If \var{string} cannot be parsed
-according to \var{format}, \exception{ValueError} is raised.  If the
-string to be parsed has excess data after parsing,
-\exception{ValueError} is raised.  The default values used to fill in
-any missing data when more accurate values cannot be inferred are
-\code{(1900, 1, 1, 0, 0, 0, 0, 1, -1)} .
+\function{localtime()}.  
+
+The \var{format} parameter uses the same directives as those used by
+\function{strftime()}; it defaults to \code{"\%a \%b \%d \%H:\%M:\%S
+  \%Y"} which matches the formatting returned by \function{ctime()}.
+If \var{string} cannot be parsed according to \var{format}, or if it
+has excess data after parsing, \exception{ValueError} is raised.  The
+default values used to fill in any missing data when more accurate
+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
 \code{tzname} and whether \code{daylight} is true.  Because of this,
index 50366ba96544c8debb7f32c51ad63c844c67037c..5d5f2365d9c590a24d958ca5a720cf0b81f35611 100644 (file)
@@ -47,7 +47,7 @@ The following functions are defined:
 
 \begin{funcdesc}{open}{url\optional{, new=0\optional{, autoraise=1}}}
   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 page ("tab") is opened if possible.  If \var{autoraise} is
   true, the window is raised if possible (note that under many window
index 6cdd1d35e6f66fd18b1110f1896563e91ce167fd..366cee9a4f73d04b9a3ddf71a924a2a52a75f77e 100644 (file)
@@ -24,8 +24,8 @@ it cannot currently create an encrypted file.
 
 The available attributes of this module are:
 
-\begin{excdesc}{error}
-  The error raised for bad ZIP files.
+\begin{excdesc}{BadZipfile}
+  The error raised for bad ZIP files (old name: \code{zipfile.error}).
 \end{excdesc}
 
 \begin{excdesc}{LargeZipFile}
@@ -90,7 +90,7 @@ The available attributes of this module are:
   (a string) or a file-like object.  The \var{mode} parameter
   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
-  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
   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
@@ -128,7 +128,8 @@ cat myzip.zip >> python.exe
 
 \begin{methoddesc}{getinfo}{name}
   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}
 
 \begin{methoddesc}{infolist}{}
@@ -147,7 +148,9 @@ cat myzip.zip >> python.exe
     parameter, if included, must be one of the following: \code{'r'} (the 
     default), \code{'U'}, or \code{'rU'}. Choosing \code{'U'} or 
     \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}
         The file-like object is read-only and provides the following methods:
         \method{read()}, \method{readline()}, \method{readlines()},
@@ -182,7 +185,8 @@ cat myzip.zip >> python.exe
   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 
   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}
 \end{methoddesc}
@@ -190,6 +194,8 @@ cat myzip.zip >> python.exe
 \begin{methoddesc}{testzip}{}
   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}.
+  Calling \method{testzip()} on a closed ZipFile will raise a
+  \exception{RuntimeError}.
 \end{methoddesc}
 
 \begin{methoddesc}{write}{filename\optional{, arcname\optional{,
@@ -200,7 +206,10 @@ cat myzip.zip >> python.exe
   separators removed).  If given, \var{compress_type} overrides the
   value given for the \var{compression} parameter to the constructor
   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.
   If you have unicode file names, please convert them to byte strings
@@ -210,6 +219,11 @@ cat myzip.zip >> python.exe
 
   \note{Archive names should be relative to the archive root, that is,
         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}
 
 \begin{methoddesc}{writestr}{zinfo_or_arcname, bytes}
@@ -218,7 +232,10 @@ cat myzip.zip >> python.exe
   \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
   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}
 
 
@@ -243,12 +260,13 @@ those of \class{ZipFile} objects.
   available, else a \file{*.pyc} file, compiling if necessary.  If the
   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
-  (no path information).  If it is a directory, and the directory is
-  not a package directory, then all the files \file{*.py[co]} are
-  added at the top level.  If the directory is a package directory,
-  then all \file{*.py[oc]} are added under the package name as a file
-  path, and if any subdirectories are package directories, all of
-  these are added recursively.  \var{basename} is intended for
+  (no path information).  If the pathname is a file that does not end with
+  \file{.py}, a \exception{RuntimeError} will be raised.  If it is a
+  directory, and the directory is not a package directory, then all the
+  files \file{*.py[co]} are added at the top level.  If the directory is
+  a package directory, then all \file{*.py[co]} are added under the package
+  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
   with file names like this:
 
index 53a84a9d49d811266707699da94b1835c78a3557..a41487be1451d29d8fc8fbd76a60d4e200fbaf82 100644 (file)
@@ -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
 (\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}}
 
index 6717977e63ae6fcb090ae7e3bb067de5771e0b2f..1c6683d33e35a87b871226b646cce041234a5af9 100644 (file)
@@ -112,7 +112,7 @@ extern "C" {
 #define LOAD_GLOBAL    116     /* Index in name list */
 
 #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_FINALLY  122     /* "" */
 
index f62c345428ad68e03fdb3361911d6f67ac912507..2cddb11bfc1fab3ed9262d6a2413f75799e0cb7e 100644 (file)
@@ -223,6 +223,14 @@ _check_size(c_char)
 
 class c_char_p(_SimpleCData):
     _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")
 
 class c_void_p(_SimpleCData):
index 71cfe935265158b6656686a8f664650e3dae9d67..9f61cdb3558092835cfd7ad6246a16fccf5ebc96 100644 (file)
@@ -7,25 +7,21 @@ from ctypes.test import is_resource_enabled
 if sys.platform == "win32":
     lib_gl = find_library("OpenGL32")
     lib_glu = find_library("Glu32")
-    lib_glut = find_library("glut32")
     lib_gle = None
 elif sys.platform == "darwin":
     lib_gl = lib_glu = find_library("OpenGL")
-    lib_glut = find_library("GLUT")
     lib_gle = None
 else:
     lib_gl = find_library("GL")
     lib_glu = find_library("GLU")
-    lib_glut = find_library("glut")
     lib_gle = find_library("gle")
 
 ## print, for debugging
 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:")
         for item in (("GL", lib_gl),
                      ("GLU", lib_glu),
-                     ("glut", lib_glut),
                      ("gle", lib_gle)):
             print("\t", item)
 
@@ -33,24 +29,11 @@ if is_resource_enabled("printing"):
 # On some systems, loading the OpenGL libraries needs the RTLD_GLOBAL mode.
 class Test_OpenGL_libs(unittest.TestCase):
     def setUp(self):
-        self.gl = self.glu = self.gle = self.glut = None
+        self.gl = self.glu = self.gle = None
         if lib_gl:
             self.gl = CDLL(lib_gl, mode=RTLD_GLOBAL)
         if lib_glu:
             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:
             try:
                 self.gle = CDLL(lib_gle)
@@ -67,11 +50,6 @@ class Test_OpenGL_libs(unittest.TestCase):
             if self.glu:
                 self.glu.gluBeginCurve
 
-    if lib_glut:
-        def test_glut(self):
-            if self.glut:
-                self.glut.glutWireTetrahedron
-
     if lib_gle:
         def test_gle(self):
             if self.gle:
index 057873c57e62213a271302b763530b8bd2071d6c..5067b6081564262c0b5eca00684a88a6bd74ff67 100644 (file)
@@ -58,6 +58,15 @@ if sys.platform == "win32":
             self.failUnlessEqual(sizeof(wintypes.LPARAM),
                                  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):
 
     def test_struct_by_value(self):
index e1d0eb7156b4c144734663a7bbd0cda07f772824..c7c61efeee1761790ee54d175d3674db7df5adb2 100644 (file)
@@ -1491,6 +1491,18 @@ counter to RFC 2822, there's no separating newline here
         self.failUnless(isinstance(bad.defects[0],
                                    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')
+
+
 
 \f
 # Test RFC 2047 header encoding and decoding
index 4ce2184f79e29cacb384af1b01cf1c8a42b967e7..4688a1b5a04ad1b36a01b05111a353c1c65c13be 100644 (file)
@@ -1489,6 +1489,17 @@ counter to RFC 2822, there's no separating newline here
         self.failUnless(isinstance(bad.defects[0],
                                    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')
+
 
 \f
 # Test RFC 2047 header encoding and decoding
index 9c6fafeaa4d5f2a9e59dba39bc3573e835bcace3..860dbaefda6dfd25a6ebc28c3989f560a0a28c1b 100644 (file)
@@ -44,7 +44,7 @@ class FileList:
         return self.EditorWindow(self, filename)
 
     def close_all_callback(self, event):
-        for edit in self.inversedict.keys():
+        for edit in list(self.inversedict):
             reply = edit.close()
             if reply == "cancel":
                 break
index 4311999a2fad7502ec663a72556eb6228ad551b0..f43f83e893418b5babe91a4ad28707cd64b8b1cf 100644 (file)
@@ -105,18 +105,32 @@ class _SimpleBinder:
 # _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
 # number of modifiers is the state - the most specific state comes first.
-# XXX rewrite without overusing functional primitives :-)
 _states = range(1 << len(_modifiers))
 _state_names = [''.join(m[0]+'-'
                         for i, m in enumerate(_modifiers)
                         if (1 << i) & s)
                 for s in _states]
-_state_subsets = map(lambda i: filter(lambda j: not (j & (~i)), _states),
-                     _states)
-for l in _state_subsets:
-    l.sort(lambda a, b, nummod = lambda x: len(filter(lambda i: (1<<i) & x,
-                                                      range(len(_modifiers)))):
-           nummod(b) - nummod(a))
+
+def expand_substates(states):
+    '''For each item of states return a list containing all combinations of
+    that item with individual bits reset, sorted by the number of set bits.
+    '''
+    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 = []
 for s in _states:
index 2d69157b1ae952a759255eb4d7795c1bd62881b2..f11e609d9ce75e585696e8f1aeaca65851234eb2 100644 (file)
@@ -351,8 +351,6 @@ class ModifiedInterpreter(InteractiveInterpreter):
 
     def build_subprocess_arglist(self):
         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,
         # or maybe it's not installed and the idle.py script is being
         # run from the IDLE source directory.
index 59005b8708c2009ebfaf97c465a668be4daab003..459fea704c5a2f473e8035d406987b9cb6d375fb 100644 (file)
@@ -19,7 +19,7 @@ class WidgetRedirector:
                                              self.widget._w)
 
     def close(self):
-        for name in self.dict.keys():
+        for name in list(self.dict.keys()):
             self.unregister(name)
         widget = self.widget; del self.widget
         orig = self.orig; del self.orig
index f56b4d4404b2ef586d6a97b34660e50c4c73ee3f..636299d3f7a9ed4f66210dfc0062dc1afe47cbb3 100644 (file)
@@ -1 +1 @@
-IDLE_VERSION = "2.6a0"
+IDLE_VERSION = "3.0x"
index ad61fff46f4f3de8ed10f82503227b32f2a3af35..222abfce753d4bb7080047ca1fda26707f9af1a9 100644 (file)
@@ -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).
 """
 import sys
+import Tkinter
 
 def runningAsOSXApp():
     """ Returns True iff running from the IDLE.app bundle on OSX """
@@ -23,7 +24,11 @@ def addOpenEventSupport(root, flist):
     root.createcommand("::tk::mac::OpenDocument", doOpenFile)
 
 def hideTkConsole(root):
-    root.tk.call('console', 'hide')
+    try:
+        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):
     """
@@ -75,32 +80,40 @@ def overrideRootMenu(root, flist):
         import configDialog
         configDialog.ConfigDialog(root, 'Settings')
 
+
     root.bind('<<about-idle>>', about_dialog)
     root.bind('<<open-config-dialog>>', config_dialog)
     if flist:
         root.bind('<<close-all-windows>>', flist.close_all_callback)
 
-    for mname, entrylist in Bindings.menudefs:
-        menu = menudict.get(mname)
-        if not menu:
-            continue
-        for entry in entrylist:
-            if not entry:
-                menu.add_separator()
+
+    ###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:
+            menu = menudict.get(mname)
+            if not menu:
+                continue
             else:
-                label, eventname = entry
-                underline, label = prepstr(label)
-                accelerator = get_accelerator(Bindings.default_keydefs,
+                for entry in entrylist:
+                    if not entry:
+                        menu.add_separator()
+                    else:
+                        label, eventname = entry
+                        underline, label = prepstr(label)
+                        accelerator = get_accelerator(Bindings.default_keydefs,
                         eventname)
-                def command(text=root, eventname=eventname):
-                    text.event_generate(eventname)
-                menu.add_command(label=label, underline=underline,
+                        def command(text=root, eventname=eventname):
+                            text.event_generate(eventname)
+                        menu.add_command(label=label, underline=underline,
                         command=command, accelerator=accelerator)
 
-
-
-
-
 def setupApp(root, flist):
     """
     Perform setup for the OSX application bundle.
index b5e9ff23feda1705a1e45cdb9b807cd670fae08f..45db8eefc2378f20351bdbb8302b6db0908d7078 100644 (file)
@@ -690,7 +690,6 @@ def _getfullargs(co):
     if not iscode(co):
         raise TypeError('arg is not a code object')
 
-    code = co.co_code
     nargs = co.co_argcount
     names = co.co_varnames
     nkwargs = co.co_kwonlyargcount
index 1e4d771876e7dcb23076736ed568c150645df6f1..ef588e87bc10939d4f46a79d203921d98455d635 100644 (file)
@@ -1680,7 +1680,7 @@ class Tk(Misc, Wm):
     def destroy(self):
         """Destroy this and all descendants widgets. This will
         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)
         Misc.destroy(self)
         global _default_root
index b9f4497d022dfebd65f5f432d867cb2ae9f62b21..fdb118d99fa483744f7a23490dd3d53a5d8283e7 100755 (executable)
@@ -107,7 +107,7 @@ class Mailbox:
             yield value
 
     def __iter__(self):
-        return self.values()
+        return self.itervalues()
 
     def values(self):
         """Return a list of messages. Memory intensive."""
@@ -456,7 +456,11 @@ class Maildir(Mailbox):
         """Update table of contents mapping."""
         self._toc = {}
         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]
                 self._toc[uniq] = os.path.join(subdir, entry)
 
index 8c4b5e5fc00f20451a76bc797ffbfd93e575286a..de7807c54f756a575cd97c3722d98d571f0c6ded 100755 (executable)
@@ -335,12 +335,12 @@ def main(tests=None, testdir=None, verbose=0, quiet=False, generate=False,
         tests = map(removepy, tests)
 
     stdtests = STDTESTS[:]
-    nottests = NOTTESTS[:]
+    nottests = NOTTESTS.copy()
     if exclude:
         for arg in args:
             if arg in stdtests:
                 stdtests.remove(arg)
-        nottests[:0] = args
+            nottests.add(arg)
         args = []
     tests = tests or args or findtests(testdir, stdtests, nottests)
     if single:
@@ -478,14 +478,14 @@ STDTESTS = [
     'test_unittest',
     'test_doctest',
     'test_doctest2',
-   ]
+]
 
-NOTTESTS = [
+NOTTESTS = {
     'test_support',
     'test_future1',
     'test_future2',
     'test_future3',
-    ]
+}
 
 def findtests(testdir=None, stdtests=STDTESTS, nottests=NOTTESTS):
     """Return a list of all applicable test modules."""
@@ -818,12 +818,14 @@ def printlist(x, width=70, indent=4):
 #     test_timeout
 #         Controlled by test_timeout.skip_expected.  Requires the network
 #         resource and a socket module.
+#
+# Tests that are expected to be skipped everywhere except on one platform
+# are also handled separately.
 
 _expectations = {
     'win32':
         """
         test__locale
-        test_applesingle
         test_bsddb3
         test_commands
         test_crypt
@@ -836,9 +838,7 @@ _expectations = {
         test_grp
         test_ioctl
         test_largefile
-        test_linuxaudiodev
         test_mhlib
-        test_nis
         test_openpty
         test_ossaudiodev
         test_poll
@@ -847,24 +847,16 @@ _expectations = {
         test_pwd
         test_resource
         test_signal
-        test_sunaudiodev
         test_threadsignals
         test_wait3
         test_wait4
         """,
     'linux2':
         """
-        test_applesingle
         test_curses
         test_dl
         test_largefile
-        test_linuxaudiodev
-        test_nis
-        test_ntpath
         test_ossaudiodev
-        test_sqlite
-        test_startfile
-        test_sunaudiodev
         """,
    'mac':
         """
@@ -882,11 +874,8 @@ _expectations = {
         test_grp
         test_ioctl
         test_largefile
-        test_linuxaudiodev
         test_locale
         test_mmap
-        test_nis
-        test_ntpath
         test_openpty
         test_ossaudiodev
         test_poll
@@ -896,69 +885,45 @@ _expectations = {
         test_pwd
         test_resource
         test_signal
-        test_sqlite
-        test_startfile
-        test_sunaudiodev
         test_sundry
         test_tarfile
         """,
     'unixware7':
         """
-        test_applesingle
         test_bsddb
         test_dl
         test_largefile
-        test_linuxaudiodev
         test_minidom
-        test_nis
-        test_ntpath
         test_openpty
         test_pyexpat
         test_sax
-        test_startfile
-        test_sqlite
-        test_sunaudiodev
         test_sundry
         """,
     'openunix8':
         """
-        test_applesingle
         test_bsddb
         test_dl
         test_largefile
-        test_linuxaudiodev
         test_minidom
-        test_nis
-        test_ntpath
         test_openpty
         test_pyexpat
         test_sax
-        test_sqlite
-        test_startfile
-        test_sunaudiodev
         test_sundry
         """,
     'sco_sv3':
         """
-        test_applesingle
         test_asynchat
         test_bsddb
         test_dl
         test_fork1
         test_gettext
         test_largefile
-        test_linuxaudiodev
         test_locale
         test_minidom
-        test_nis
-        test_ntpath
         test_openpty
         test_pyexpat
         test_queue
         test_sax
-        test_sqlite
-        test_startfile
-        test_sunaudiodev
         test_sundry
         test_thread
         test_threaded_import
@@ -967,7 +932,6 @@ _expectations = {
         """,
     'riscos':
         """
-        test_applesingle
         test_asynchat
         test_atexit
         test_bsddb
@@ -981,18 +945,12 @@ _expectations = {
         test_gdbm
         test_grp
         test_largefile
-        test_linuxaudiodev
         test_locale
         test_mmap
-        test_nis
-        test_ntpath
         test_openpty
         test_poll
         test_pty
         test_pwd
-        test_sqlite
-        test_startfile
-        test_sunaudiodev
         test_sundry
         test_thread
         test_threaded_import
@@ -1001,209 +959,135 @@ _expectations = {
         """,
     'darwin':
         """
+        test__locale
+        test_bsddb
+        test_bsddb3
+        test_curses
         test_gdbm
         test_largefile
-        test_linuxaudiodev
         test_locale
-        test_nis
         test_ossaudiodev
-        test_startfile
-        test_sunaudiodev
+        test_poll
         """,
     'sunos5':
         """
-        test_applesingle
         test_bsddb
         test_curses
         test_dbm
         test_gdbm
         test_gzip
-        test_linuxaudiodev
         test_openpty
-        test_sqlite
-        test_startfile
         test_zipfile
         test_zlib
         """,
     'hp-ux11':
         """
-        test_applesingle
         test_bsddb
         test_curses
         test_dl
         test_gdbm
         test_gzip
         test_largefile
-        test_linuxaudiodev
         test_locale
         test_minidom
-        test_nis
-        test_ntpath
         test_openpty
         test_pyexpat
         test_sax
-        test_sqlite
-        test_startfile
-        test_sunaudiodev
         test_zipfile
         test_zlib
         """,
     'atheos':
         """
-        test_applesingle
         test_curses
         test_dl
         test_gdbm
         test_largefile
-        test_linuxaudiodev
         test_locale
         test_mhlib
         test_mmap
-        test_nis
         test_poll
         test_resource
-        test_sqlite
-        test_startfile
-        test_sunaudiodev
         """,
     'cygwin':
         """
-        test_applesingle
         test_bsddb3
         test_curses
         test_dbm
         test_ioctl
         test_largefile
-        test_linuxaudiodev
         test_locale
-        test_nis
         test_ossaudiodev
         test_socketserver
-        test_sqlite
-        test_sunaudiodev
         """,
     'os2emx':
         """
-        test_applesingle
         test_audioop
         test_bsddb3
         test_commands
         test_curses
         test_dl
         test_largefile
-        test_linuxaudiodev
         test_mhlib
         test_mmap
-        test_nis
         test_openpty
         test_ossaudiodev
         test_pty
         test_resource
         test_signal
-        test_sqlite
-        test_startfile
-        test_sunaudiodev
         """,
     'freebsd4':
         """
-        test_aepack
-        test_applesingle
         test_bsddb
         test_bsddb3
         test_gdbm
-        test_linuxaudiodev
         test_locale
-        test_macostools
-        test_nis
         test_ossaudiodev
         test_pep277
-        test_plistlib
         test_pty
-        test_scriptpackages
         test_socket_ssl
         test_socketserver
-        test_sqlite
-        test_startfile
-        test_sunaudiodev
         test_tcl
         test_timeout
-        test_unicode_file
         test_urllibnet
-        test_winreg
-        test_winsound
         """,
     'aix5':
         """
-        test_aepack
-        test_applesingle
         test_bsddb
         test_bsddb3
         test_bz2
         test_dl
         test_gdbm
         test_gzip
-        test_linuxaudiodev
-        test_macostools
-        test_nis
         test_ossaudiodev
-        test_sqlite
-        test_startfile
-        test_sunaudiodev
         test_tcl
-        test_winreg
-        test_winsound
         test_zipimport
         test_zlib
         """,
     'openbsd3':
         """
-        test_aepack
-        test_applesingle
         test_bsddb
         test_bsddb3
         test_ctypes
         test_dl
         test_gdbm
-        test_linuxaudiodev
         test_locale
-        test_macostools
-        test_nis
         test_normalization
         test_ossaudiodev
         test_pep277
-        test_plistlib
-        test_scriptpackages
         test_tcl
-        test_sqlite
-        test_startfile
-        test_sunaudiodev
-        test_unicode_file
-        test_winreg
-        test_winsound
         """,
     'netbsd3':
         """
-        test_aepack
-        test_applesingle
         test_bsddb
         test_bsddb3
         test_ctypes
         test_curses
         test_dl
         test_gdbm
-        test_linuxaudiodev
         test_locale
-        test_macostools
-        test_nis
         test_ossaudiodev
         test_pep277
-        test_sqlite
-        test_startfile
-        test_sunaudiodev
         test_tcl
-        test_unicode_file
-        test_winreg
-        test_winsound
         """,
 }
 _expectations['freebsd5'] = _expectations['freebsd4']
@@ -1221,6 +1105,9 @@ class _ExpectedSkips:
             s = _expectations[sys.platform]
             self.expected = set(s.split())
 
+            # expected to be skipped on every platform, even Linux
+            self.expected.add('test_linuxaudiodev')
+
             if not os.path.supports_unicode_filenames:
                 self.expected.add('test_pep277')
 
@@ -1232,20 +1119,23 @@ class _ExpectedSkips:
 
             if not sys.platform in ("mac", "darwin"):
                 MAC_ONLY = ["test_macostools", "test_aepack",
-                            "test_plistlib", "test_scriptpackages"]
+                            "test_plistlib", "test_scriptpackages",
+                            "test_applesingle"]
                 for skip in MAC_ONLY:
                     self.expected.add(skip)
 
             if sys.platform != "win32":
+                # test_sqlite is only reliable on Windows where the library
+                # is distributed with Python
                 WIN_ONLY = ["test_unicode_file", "test_winreg",
-                            "test_winsound"]
+                            "test_winsound", "test_startfile",
+                            "test_sqlite"]
                 for skip in WIN_ONLY:
                     self.expected.add(skip)
 
-            if sys.platform != 'irix':
-                IRIX_ONLY =["test_imageop"]
-                for skip in IRIX_ONLY:
-                    self.expected.add(skip)
+            if sys.platform != 'sunos5':
+                self.expected.add('test_sunaudiodev')
+                self.expected.add('test_nis')
 
             self.valid = True
 
diff --git a/Lib/test/test_asyncore.py b/Lib/test/test_asyncore.py
new file mode 100644 (file)
index 0000000..7602b9f
--- /dev/null
@@ -0,0 +1,406 @@
+import asyncore
+import unittest
+import select
+import os
+import socket
+import threading
+import sys
+import time
+
+from test import test_support
+from test.test_support import TESTFN, run_unittest, unlink
+from StringIO import StringIO
+
+HOST = "127.0.0.1"
+PORT = 54329
+
+class dummysocket:
+    def __init__(self):
+        self.closed = False
+
+    def close(self):
+        self.closed = True
+
+    def fileno(self):
+        return 42
+
+class dummychannel:
+    def __init__(self):
+        self.socket = dummysocket()
+
+class exitingdummy:
+    def __init__(self):
+        pass
+
+    def handle_read_event(self):
+        raise asyncore.ExitNow()
+
+    handle_write_event = handle_read_event
+    handle_expt_event = handle_read_event
+
+class crashingdummy:
+    def __init__(self):
+        self.error_handled = False
+
+    def handle_read_event(self):
+        raise Exception()
+
+    handle_write_event = handle_read_event
+    handle_expt_event = handle_read_event
+
+    def handle_error(self):
+        self.error_handled = True
+
+# used when testing senders; just collects what it gets until newline is sent
+def capture_server(evt, buf):
+    serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+    serv.settimeout(3)
+    serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+    serv.bind(("", PORT))
+    serv.listen(5)
+    try:
+        conn, addr = serv.accept()
+    except socket.timeout:
+        pass
+    else:
+        n = 200
+        while n > 0:
+            data = conn.recv(10)
+            # keep everything except for the newline terminator
+            buf.write(data.replace('\n', ''))
+            if '\n' in data:
+                break
+            n -= 1
+            time.sleep(0.01)
+
+        conn.close()
+    finally:
+        serv.close()
+        evt.set()
+
+
+class HelperFunctionTests(unittest.TestCase):
+    def test_readwriteexc(self):
+        # Check exception handling behavior of read, write and _exception
+
+        # check that ExitNow exceptions in the object handler method
+        # bubbles all the way up through asyncore read/write/_exception calls
+        tr1 = exitingdummy()
+        self.assertRaises(asyncore.ExitNow, asyncore.read, tr1)
+        self.assertRaises(asyncore.ExitNow, asyncore.write, tr1)
+        self.assertRaises(asyncore.ExitNow, asyncore._exception, tr1)
+
+        # check that an exception other than ExitNow in the object handler
+        # method causes the handle_error method to get called
+        tr2 = crashingdummy()
+        asyncore.read(tr2)
+        self.assertEqual(tr2.error_handled, True)
+
+        tr2 = crashingdummy()
+        asyncore.write(tr2)
+        self.assertEqual(tr2.error_handled, True)
+
+        tr2 = crashingdummy()
+        asyncore._exception(tr2)
+        self.assertEqual(tr2.error_handled, True)
+
+##    Commented out these tests because test a non-documented function
+##    (which is actually public, why it's not documented?). Anyway, the
+##    tests *and* the function uses constants in the select module that
+##    are not present in Windows systems (see this thread:
+##    http://mail.python.org/pipermail/python-list/2001-October/109973.html)
+##    Note even that these constants are mentioned in the select
+##    documentation, as a parameter of "poll" method "register", but are
+##    not explicit declared as constants of the module.
+##    .    Facundo Batista
+##
+##    def test_readwrite(self):
+##        # Check that correct methods are called by readwrite()
+##
+##        class testobj:
+##            def __init__(self):
+##                self.read = False
+##                self.write = False
+##                self.expt = False
+##
+##            def handle_read_event(self):
+##                self.read = True
+##
+##            def handle_write_event(self):
+##                self.write = True
+##
+##            def handle_expt_event(self):
+##                self.expt = True
+##
+##            def handle_error(self):
+##                self.error_handled = True
+##
+##        for flag in (select.POLLIN, select.POLLPRI):
+##            tobj = testobj()
+##            self.assertEqual(tobj.read, False)
+##            asyncore.readwrite(tobj, flag)
+##            self.assertEqual(tobj.read, True)
+##
+##            # check that ExitNow exceptions in the object handler method
+##            # bubbles all the way up through asyncore readwrite call
+##            tr1 = exitingdummy()
+##            self.assertRaises(asyncore.ExitNow, asyncore.readwrite, tr1, flag)
+##
+##            # check that an exception other than ExitNow in the object handler
+##            # method causes the handle_error method to get called
+##            tr2 = crashingdummy()
+##            asyncore.readwrite(tr2, flag)
+##            self.assertEqual(tr2.error_handled, True)
+##
+##        tobj = testobj()
+##        self.assertEqual(tobj.write, False)
+##        asyncore.readwrite(tobj, select.POLLOUT)
+##        self.assertEqual(tobj.write, True)
+##
+##        # check that ExitNow exceptions in the object handler method
+##        # bubbles all the way up through asyncore readwrite call
+##        tr1 = exitingdummy()
+##        self.assertRaises(asyncore.ExitNow, asyncore.readwrite, tr1,
+##                          select.POLLOUT)
+##
+##        # check that an exception other than ExitNow in the object handler
+##        # method causes the handle_error method to get called
+##        tr2 = crashingdummy()
+##        asyncore.readwrite(tr2, select.POLLOUT)
+##        self.assertEqual(tr2.error_handled, True)
+##
+##        for flag in (select.POLLERR, select.POLLHUP, select.POLLNVAL):
+##            tobj = testobj()
+##            self.assertEqual(tobj.expt, False)
+##            asyncore.readwrite(tobj, flag)
+##            self.assertEqual(tobj.expt, True)
+##
+##            # check that ExitNow exceptions in the object handler method
+##            # bubbles all the way up through asyncore readwrite calls
+##            tr1 = exitingdummy()
+##            self.assertRaises(asyncore.ExitNow, asyncore.readwrite, tr1, flag)
+##
+##            # check that an exception other than ExitNow in the object handler
+##            # method causes the handle_error method to get called
+##            tr2 = crashingdummy()
+##            asyncore.readwrite(tr2, flag)
+##            self.assertEqual(tr2.error_handled, True)
+
+    def test_closeall(self):
+        self.closeall_check(False)
+
+    def test_closeall_default(self):
+        self.closeall_check(True)
+
+    def closeall_check(self, usedefault):
+        # Check that close_all() closes everything in a given map
+
+        l = []
+        testmap = {}
+        for i in range(10):
+            c = dummychannel()
+            l.append(c)
+            self.assertEqual(c.socket.closed, False)
+            testmap[i] = c
+
+        if usedefault:
+            socketmap = asyncore.socket_map
+            try:
+                asyncore.socket_map = testmap
+                asyncore.close_all()
+            finally:
+                testmap, asyncore.socket_map = asyncore.socket_map, socketmap
+        else:
+            asyncore.close_all(testmap)
+
+        self.assertEqual(len(testmap), 0)
+
+        for c in l:
+            self.assertEqual(c.socket.closed, True)
+
+    def test_compact_traceback(self):
+        try:
+            raise Exception("I don't like spam!")
+        except:
+            real_t, real_v, real_tb = sys.exc_info()
+            r = asyncore.compact_traceback()
+        else:
+            self.fail("Expected exception")
+
+        (f, function, line), t, v, info = r
+        self.assertEqual(os.path.split(f)[-1], 'test_asyncore.py')
+        self.assertEqual(function, 'test_compact_traceback')
+        self.assertEqual(t, real_t)
+        self.assertEqual(v, real_v)
+        self.assertEqual(info, '[%s|%s|%s]' % (f, function, line))
+
+
+class DispatcherTests(unittest.TestCase):
+    def setUp(self):
+        pass
+
+    def tearDown(self):
+        asyncore.close_all()
+
+    def test_basic(self):
+        d = asyncore.dispatcher()
+        self.assertEqual(d.readable(), True)
+        self.assertEqual(d.writable(), True)
+
+    def test_repr(self):
+        d = asyncore.dispatcher()
+        self.assertEqual(repr(d), '<asyncore.dispatcher at %#x>' % id(d))
+
+    def test_log(self):
+        d = asyncore.dispatcher()
+
+        # capture output of dispatcher.log() (to stderr)
+        fp = StringIO()
+        stderr = sys.stderr
+        l1 = "Lovely spam! Wonderful spam!"
+        l2 = "I don't like spam!"
+        try:
+            sys.stderr = fp
+            d.log(l1)
+            d.log(l2)
+        finally:
+            sys.stderr = stderr
+
+        lines = fp.getvalue().splitlines()
+        self.assertEquals(lines, ['log: %s' % l1, 'log: %s' % l2])
+
+    def test_log_info(self):
+        d = asyncore.dispatcher()
+
+        # capture output of dispatcher.log_info() (to stdout via print)
+        fp = StringIO()
+        stdout = sys.stdout
+        l1 = "Have you got anything without spam?"
+        l2 = "Why can't she have egg bacon spam and sausage?"
+        l3 = "THAT'S got spam in it!"
+        try:
+            sys.stdout = fp
+            d.log_info(l1, 'EGGS')
+            d.log_info(l2)
+            d.log_info(l3, 'SPAM')
+        finally:
+            sys.stdout = stdout
+
+        lines = fp.getvalue().splitlines()
+        if __debug__:
+            expected = ['EGGS: %s' % l1, 'info: %s' % l2, 'SPAM: %s' % l3]
+        else:
+            expected = ['EGGS: %s' % l1, 'SPAM: %s' % l3]
+
+        self.assertEquals(lines, expected)
+
+    def test_unhandled(self):
+        d = asyncore.dispatcher()
+
+        # capture output of dispatcher.log_info() (to stdout via print)
+        fp = StringIO()
+        stdout = sys.stdout
+        try:
+            sys.stdout = fp
+            d.handle_expt()
+            d.handle_read()
+            d.handle_write()
+            d.handle_connect()
+            d.handle_accept()
+        finally:
+            sys.stdout = stdout
+
+        lines = fp.getvalue().splitlines()
+        expected = ['warning: unhandled exception',
+                    'warning: unhandled read event',
+                    'warning: unhandled write event',
+                    'warning: unhandled connect event',
+                    'warning: unhandled accept event']
+        self.assertEquals(lines, expected)
+
+
+
+class dispatcherwithsend_noread(asyncore.dispatcher_with_send):
+    def readable(self):
+        return False
+
+    def handle_connect(self):
+        pass
+
+class DispatcherWithSendTests(unittest.TestCase):
+    usepoll = False
+
+    def setUp(self):
+        pass
+
+    def tearDown(self):
+        asyncore.close_all()
+
+    def test_send(self):
+        self.evt = threading.Event()
+        cap = StringIO()
+        threading.Thread(target=capture_server, args=(self.evt,cap)).start()
+        time.sleep(1) # Give server time to initialize
+
+        data = "Suppose there isn't a 16-ton weight?"*5
+        d = dispatcherwithsend_noread()
+        d.create_socket(socket.AF_INET, socket.SOCK_STREAM)
+        d.connect((HOST, PORT))
+        d.send(data)
+        d.send('\n')
+
+        n = 1000
+        while d.out_buffer and n > 0:
+            asyncore.poll()
+            n -= 1
+
+        self.evt.wait()
+
+        self.assertEqual(cap.getvalue(), data)
+
+
+class DispatcherWithSendTests_UsePoll(DispatcherWithSendTests):
+    usepoll = True
+
+if hasattr(asyncore, 'file_wrapper'):
+    class FileWrapperTest(unittest.TestCase):
+        def setUp(self):
+            self.d = "It's not dead, it's sleeping!"
+            file(TESTFN, 'w').write(self.d)
+
+        def tearDown(self):
+            unlink(TESTFN)
+
+        def test_recv(self):
+            fd = os.open(TESTFN, os.O_RDONLY)
+            w = asyncore.file_wrapper(fd)
+
+            self.assertEqual(w.fd, fd)
+            self.assertEqual(w.fileno(), fd)
+            self.assertEqual(w.recv(13), "It's not dead")
+            self.assertEqual(w.read(6), ", it's")
+            w.close()
+            self.assertRaises(OSError, w.read, 1)
+
+        def test_send(self):
+            d1 = "Come again?"
+            d2 = "I want to buy some cheese."
+            fd = os.open(TESTFN, os.O_WRONLY | os.O_APPEND)
+            w = asyncore.file_wrapper(fd)
+
+            w.write(d1)
+            w.send(d2)
+            w.close()
+            self.assertEqual(file(TESTFN).read(), self.d + d1 + d2)
+
+
+def test_main():
+    tests = [HelperFunctionTests, DispatcherTests, DispatcherWithSendTests,
+             DispatcherWithSendTests_UsePoll]
+    if hasattr(asyncore, 'file_wrapper'):
+        tests.append(FileWrapperTest)
+
+    run_unittest(*tests)
+
+if __name__ == "__main__":
+    test_main()
index 085768dc15d7b021bde26ceb5d5fac5c98eb7dc8..ade31322c851b8407c4914a1686e0c5cf84af544 100644 (file)
@@ -9,6 +9,7 @@ maxsize = MAX_Py_ssize_t
 # test on unicode strings as well
 
 overflowok = 1
+overflowrequired = 0
 
 def testformat(formatstr, args, output=None):
     if verbose:
@@ -25,7 +26,11 @@ def testformat(formatstr, args, output=None):
         if verbose:
             print('overflow (this is fine)')
     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:
                 print('no')
             print("%r %% %r == %r != %r" %\
@@ -56,6 +61,14 @@ testboth("%#.*g", (110, -1.e+100/3.))
 # test some ridiculously large precision, expect overflow
 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
 overflowok = 0
 testboth("%x", 10, "a")
index 8f4538298481fa65cc17ce3b012de7b8228139f6..bfc77feccfc5d72556a57b5a8b109c67a5ad8359 100644 (file)
@@ -697,6 +697,20 @@ class GrammarTests(unittest.TestCase):
             def meth2(self, arg): 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):
         # list comprehension tests
         nums = [1, 2, 3, 4, 5]
index 9d50225ec394c0c805738137c25a6bb0282ccbed..e5930d80f628967f87cc653f6401e6f7e6c7fd0a 100644 (file)
@@ -427,8 +427,8 @@ class TestMailboxSuperclass(TestBase):
         self.assertRaises(NotImplementedError, lambda: box.__setitem__('', ''))
         self.assertRaises(NotImplementedError, lambda: box.keys())
         self.assertRaises(NotImplementedError, lambda: box.keys())
-        self.assertRaises(NotImplementedError, lambda: box.values().next())
-        self.assertRaises(NotImplementedError, lambda: box.__iter__().next())
+        self.assertRaises(NotImplementedError, lambda: box.values().__next__())
+        self.assertRaises(NotImplementedError, lambda: box.__iter__().__next__())
         self.assertRaises(NotImplementedError, lambda: box.values())
         self.assertRaises(NotImplementedError, lambda: box.items().next())
         self.assertRaises(NotImplementedError, lambda: box.items())
@@ -679,7 +679,18 @@ class TestMaildir(TestMailbox):
         folder1_alias = box.get_folder('folder1')
         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):
 
index ddb58b5e8d2e68ff5dcadae217701670ff72ef5b..dbf6a92aab7cc530abcedeab3e009f2a9c715fed 100644 (file)
@@ -443,6 +443,12 @@ class CompileTestCase(unittest.TestCase):
         st = parser.suite('1 = 3 + 4')
         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():
     test_support.run_unittest(
         RoundtripLegalSyntaxTestCase,
index 99e304774d2086115e3f6c1081d7e3becf5fa56c..488e9e2b9326e6b22fa3c144dff1c6603e0e7691 100644 (file)
@@ -380,6 +380,12 @@ class MockPasswordManager:
 
 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):
         # test work-around for three methods that accidentally follow the
         # naming conventions for handler methods
index 791cca7666ad98390528f90dcc90e60aa182caeb..0b8a9639db7510248e24a4a249e5971390339aa6 100644 (file)
@@ -1,5 +1,7 @@
+import base64
 import datetime
 import sys
+import time
 import unittest
 import xmlrpclib
 from test import test_support
@@ -18,6 +20,10 @@ alist = [{'astring': 'foo@bar.baz.spam',
                         (2005, 2, 10, 11, 41, 23, 0, 1, -1)),
           'datetime3': xmlrpclib.DateTime(
                         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):
@@ -94,11 +100,37 @@ class XMLRPCTestCase(unittest.TestCase):
     def test_dump_bad_dict(self):
         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):
         if sys.maxint > 2**31-1:
             self.assertRaises(OverflowError, xmlrpclib.dumps,
                               (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):
         value = alist + [None]
         arg1 = (alist + [None],)
@@ -146,8 +178,109 @@ class XMLRPCTestCase(unittest.TestCase):
         self.assert_(isinstance(items[0][0], 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():
-    test_support.run_unittest(XMLRPCTestCase)
+    test_support.run_unittest(XMLRPCTestCase, HelperTestCase,
+            DateTimeTestCase, BinaryTestCase, FaultTestCase)
 
 
 if __name__ == "__main__":
index 197170a96eac0466a5c0dfd7df0e03c6a6fff31f..eda686323faf6ecac13938e9e8cd62fe768dd70c 100644 (file)
@@ -12,7 +12,7 @@ import test.test_support as support
 from test.test_support import TESTFN, run_unittest
 
 TESTFN2 = TESTFN + "2"
-FIXEDTEST_SIZE = 10
+FIXEDTEST_SIZE = 1000
 
 class TestsWithSourceFile(unittest.TestCase):
     def setUp(self):
@@ -232,6 +232,63 @@ class TestsWithSourceFile(unittest.TestCase):
         self.assertEqual(zipfp.namelist(), ["absolute"])
         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):
         os.remove(TESTFN)
         os.remove(TESTFN2)
@@ -349,7 +406,6 @@ class TestZip64InSmallFiles(unittest.TestCase):
         self.assertEqual(zipfp.namelist(), ["absolute"])
         zipfp.close()
 
-
     def tearDown(self):
         zipfile.ZIP64_LIMIT = self._limit
         os.remove(TESTFN)
@@ -420,6 +476,11 @@ class PyZipFileTests(unittest.TestCase):
         finally:
             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):
@@ -501,7 +562,56 @@ class OtherTests(unittest.TestCase):
         # a RuntimeError, and so should calling .testzip.  An earlier
         # version of .testzip would swallow this exception (and any other)
         # 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.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):
         support.unlink(TESTFN)
index 9e95fda2ccb362f47674d50f148e7a37fdce9bc8..9c773fcbf246d858c181b3736f135b5628b7ebfc 100644 (file)
@@ -293,6 +293,10 @@ class OpenerDirector:
         self.process_request = {}
 
     def add_handler(self, handler):
+        if not hasattr(handler, "add_parent"):
+            raise TypeError("expected BaseHandler instance, got %r" %
+                            type(handler))
+
         added = False
         for meth in dir(handler):
             if meth in ["redirect_request", "do_open", "proxy_open"]:
index 4791aea5ad45fffac8a3bb19c2f3c0ebfcc4daef..63551a653de2f3b449d9e4cc49dfd7aa08896453 100644 (file)
@@ -574,8 +574,9 @@ class ZipFile:
 
     def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=False):
         """Open the ZIP file with mode read "r", write "w" or append "a"."""
-        self._allowZip64 = allowZip64
-        self._didModify = False
+        if mode not in ("r", "w", "a"):
+            raise RuntimeError('ZipFile() requires mode "r", "w", or "a"')
+
         if compression == ZIP_STORED:
             pass
         elif compression == ZIP_DEFLATED:
@@ -584,6 +585,9 @@ class ZipFile:
                       "Compression requires the (missing) zlib module"
         else:
             raise RuntimeError, "That compression method is not supported"
+
+        self._allowZip64 = allowZip64
+        self._didModify = False
         self.debug = 0  # Level of printing: 0 through 3
         self.NameToInfo = {}    # Find file info given name
         self.filelist = []      # List of ZipInfo instances for archive
@@ -729,7 +733,12 @@ class ZipFile:
 
     def getinfo(self, 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):
         """Set default password for encrypted files."""
@@ -834,6 +843,10 @@ class ZipFile:
     def write(self, filename, arcname=None, compress_type=None):
         """Put the bytes from filename into the archive under the name
         arcname."""
+        if not self.fp:
+            raise RuntimeError(
+                  "Attempt to write to ZIP archive that was already closed")
+
         st = os.stat(filename)
         mtime = time.localtime(st.st_mtime)
         date_time = mtime[0:6]
@@ -906,6 +919,11 @@ class ZipFile:
             zinfo.compress_type = self.compression
         else:
             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.header_offset = self.fp.tell()    # Start of header bytes
         self._writecheck(zinfo)
index 53fa3ce4f1e22cd029ad13421277afa50e2d2ac0..4ab92ce4d947a5a5e068f73ef3d08c08f1af439f 100644 (file)
@@ -393,7 +393,7 @@ $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK): \
                        -compatibility_version $(VERSION) \
                        -current_version $(VERSION); \
         else \
-               libtool -o $(LDLIBRARY) -dynamic $(OTHER_LIBTOOL_OPT) $(LIBRARY) \
+               /usr/bin/libtool -o $(LDLIBRARY) -dynamic $(OTHER_LIBTOOL_OPT) $(LIBRARY) \
                        @LIBTOOL_CRUFT@ ;\
        fi
        $(INSTALL) -d -m $(DIRMODE)  \
index 35f087df7ed71be0099f07ea97a4df378737bdc9..0350be38f4821ec503881fb70ff62f6846ae024b 100644 (file)
@@ -4466,11 +4466,6 @@ create_comerror(void)
        PyObject *s;
        int status;
 
-       ComError = PyErr_NewException("_ctypes.COMError",
-                                     NULL,
-                                     dict);
-       if (ComError == NULL)
-               return -1;
        while (methods->ml_name) {
                /* get a wrapper for the built-in function */
                PyObject *func = PyCFunction_New(methods, NULL);
@@ -4485,13 +4480,24 @@ create_comerror(void)
                Py_DECREF(meth);
                ++methods;
        }
-       Py_INCREF(ComError);
+
        s = PyString_FromString(comerror_doc);
        if (s == NULL)
                return -1;
        status = PyDict_SetItemString(dict, "__doc__", 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
index 82f6cc1ee812c9b8c5617fa5cfdc4fc978359de1..59154552b6a8b4c2cfec03d2b5dc21e89b814b6e 100644 (file)
@@ -264,7 +264,7 @@ ffi_info *AllocFunctionCallback(PyObject *callable,
        ffi_abi cc;
 
        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) {
                PyErr_NoMemory();
                return NULL;
index 5df9943d2669fc4a2971aca993d3013bdb570e2d..52f60656853152abd6f2f0289182957a26fd4b5e 100644 (file)
@@ -58,7 +58,7 @@ typedef struct {
        PyObject *callable;
        SETFUNC setfunc;
        ffi_type *restype;
-       ffi_type *atypes[0];
+       ffi_type *atypes[1];
 } ffi_info;
 
 typedef struct {
index fd6f5e255775de31b538bbf5fa8f517f255f4bac..b4a6e87f8c4874bd8b3c82dac30421b263db0023 100644 (file)
@@ -457,13 +457,11 @@ StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct)
 
                if (!prop) {
                        Py_DECREF(pair);
-                       Py_DECREF((PyObject *)stgdict);
                        return -1;
                }
                if (-1 == PyDict_SetItem(realdict, name, prop)) {
                        Py_DECREF(prop);
                        Py_DECREF(pair);
-                       Py_DECREF((PyObject *)stgdict);
                        return -1;
                }
                Py_DECREF(pair);
index b5abdb696ee9f063a0ea2071ae1195891fe968e0..4e343b2c80f2e08c50928570c5d61fdd593d546f 100644 (file)
@@ -4156,7 +4156,8 @@ formatfloat(char *buf, size_t buflen, int flags,
           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)) {
                PyErr_SetString(PyExc_OverflowError,
                        "formatted float is too long (precision too large?)");
index 860e38b84dfe8eeff08fc67c136eee61116812f3..5dc3b4150d5da3348ae547664aea4b7e3ef302ec 100644 (file)
@@ -7935,7 +7935,8 @@ formatfloat(Py_UNICODE *buf,
        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)) {
        PyErr_SetString(PyExc_OverflowError,
                        "formatted float is too long (precision too large?)");
index 23df29fc13db1b6f546dde1855d52892abbdb803..146cd0539ca8414254c703abd74b8705ef030afa 100644 (file)
@@ -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);
     case STRING: {
         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;
-
+        }
         PyArena_AddPyObject(c->c_arena, str);
         if (bytesmode)
             return Bytes(str, LINENO(n), n->n_col_offset, c->c_arena);