[Python-checkins] r74541 - in python/branches/tk_and_idle_maintenance: Doc/install/index.rst Doc/library/cgi.rst Doc/library/csv.rst Doc/library/logging.rst Doc/library/site.rst Doc/library/weakref.rst Lib/distutils/filelist.py Lib/distutils/tests/test_filelist.py Lib/fnmatch.py Lib/hashlib.py Lib/httplib.py Lib/lib-tk/ScrolledText.py Lib/lib-tk/Tix.py Lib/site.py Lib/test/test_array.py Lib/test/test_ast.py Lib/test/test_fnmatch.py Lib/test/test_module.py Lib/test/test_site.py Misc/ACKS Misc/NEWS Modules/threadmodule.c Objects/object.c Python/ast.c setup.py

guilherme.polo python-checkins at python.org
Sat Aug 22 17:20:53 CEST 2009


Author: guilherme.polo
Date: Sat Aug 22 17:20:52 2009
New Revision: 74541

Log:
Merged revisions 74457,74463-74465,74467,74471-74472,74475,74477,74479,74488,74490,74492-74493,74495,74501,74503,74507-74511,74513,74517,74519,74522-74524,74526,74531,74533,74537 via svnmerge from 
svn+ssh://pythondev/python/trunk

........
  r74457 | benjamin.peterson | 2009-08-15 10:16:38 -0300 (Sat, 15 Aug 2009) | 1 line
  
  #6707 fix a crash with dir() on an uninitialized module
........
  r74463 | gregory.p.smith | 2009-08-15 19:39:03 -0300 (Sat, 15 Aug 2009) | 6 lines
  
  Force the http connection to close after any request returned when
  buffering=True as our buffered data is not known to the HTTPConnection and may
  contain data needed by a future request if the connection were left open.
  
  See http://bugs.python.org/issue2576 and http://bugs.python.org/issue4879.
........
  r74464 | benjamin.peterson | 2009-08-15 19:59:21 -0300 (Sat, 15 Aug 2009) | 4 lines
  
  better col_offsets for "for" statements with tuple unpacking #6704
  
  Patch from Frank Wierzbicki.
........
  r74465 | vinay.sajip | 2009-08-15 20:23:12 -0300 (Sat, 15 Aug 2009) | 1 line
  
  Added section on logging to one file from multiple processes.
........
  r74467 | vinay.sajip | 2009-08-15 20:34:47 -0300 (Sat, 15 Aug 2009) | 1 line
  
  Refined section on logging to one file from multiple processes.
........
  r74471 | guilherme.polo | 2009-08-16 11:34:26 -0300 (Sun, 16 Aug 2009) | 1 line
  
  Issue #6244: Allow detect_tkinter to look for Tcl/Tk 8.6.
........
  r74472 | guilherme.polo | 2009-08-16 11:38:57 -0300 (Sun, 16 Aug 2009) | 1 line
  
  Wrong place for issue #6244.
........
  r74475 | gregory.p.smith | 2009-08-16 15:52:58 -0300 (Sun, 16 Aug 2009) | 2 lines
  
  Issue 6665: Fix fnmatch to properly match filenames with newlines in them.
........
  r74477 | frank.wierzbicki | 2009-08-16 17:22:51 -0300 (Sun, 16 Aug 2009) | 2 lines
  
  Add test of file.write(array) extracted from Jython.
........
  r74479 | gregory.p.smith | 2009-08-16 18:54:45 -0300 (Sun, 16 Aug 2009) | 2 lines
  
  Clean up the C library import code (based on suggestions in issue6281).
........
  r74488 | vinay.sajip | 2009-08-17 10:14:37 -0300 (Mon, 17 Aug 2009) | 1 line
  
  Further refined section on logging to one file from multiple processes.
........
  r74490 | benjamin.peterson | 2009-08-17 10:39:41 -0300 (Mon, 17 Aug 2009) | 1 line
  
  typos
........
  r74492 | r.david.murray | 2009-08-17 16:26:49 -0300 (Mon, 17 Aug 2009) | 2 lines
  
  Issue 6685: 'toupper' -> 'upper' in cgi doc example explanation.
........
  r74493 | tarek.ziade | 2009-08-17 18:28:34 -0300 (Mon, 17 Aug 2009) | 1 line
  
  fixed how fnmatch.translate is used (since it has changed in r74475 for #6665). Now the code is not harcoding the usage of $ anymore
........
  r74495 | tarek.ziade | 2009-08-17 18:48:22 -0300 (Mon, 17 Aug 2009) | 1 line
  
  module cleanup
........
  r74501 | tarek.ziade | 2009-08-18 05:16:33 -0300 (Tue, 18 Aug 2009) | 1 line
  
  added more test coverage for distutils.filelist to prevent regressions when fnmatch or re are changed
........
  r74503 | tarek.ziade | 2009-08-18 05:21:49 -0300 (Tue, 18 Aug 2009) | 1 line
  
  fixed typo
........
  r74507 | guilherme.polo | 2009-08-18 10:23:08 -0300 (Tue, 18 Aug 2009) | 1 line
  
  Issue #1119673: Do not override Tkinter.Text methods when creating a ScrolledText.
........
  r74508 | guilherme.polo | 2009-08-18 10:29:20 -0300 (Tue, 18 Aug 2009) | 1 line
  
  Issue #1250469: Fix the return value of Tix.PanedWindow.panes.
........
  r74509 | guilherme.polo | 2009-08-18 10:33:30 -0300 (Tue, 18 Aug 2009) | 1 line
  
  Mark the "radio" option of Tix.CheckList as static.
........
  r74510 | guilherme.polo | 2009-08-18 11:23:00 -0300 (Tue, 18 Aug 2009) | 1 line
  
  Issue #1522587: New constants and methods for the Tix.Grid widget.
........
  r74511 | guilherme.polo | 2009-08-18 11:34:44 -0300 (Tue, 18 Aug 2009) | 1 line
  
  Fixes for Tix.Grid from issue #1522587.
........
  r74513 | skip.montanaro | 2009-08-18 11:37:52 -0300 (Tue, 18 Aug 2009) | 1 line
  
  missing module ref (issue6723)
........
  r74517 | guilherme.polo | 2009-08-18 11:46:57 -0300 (Tue, 18 Aug 2009) | 1 line
  
  Issue #1356969: Add missing info methods in Tix.HList.
........
  r74519 | guilherme.polo | 2009-08-18 13:39:36 -0300 (Tue, 18 Aug 2009) | 1 line
  
  Added missing static option for OptionMenu. Issue #5961.
........
  r74522 | gregory.p.smith | 2009-08-19 02:33:48 -0300 (Wed, 19 Aug 2009) | 8 lines
  
  Revert the changes from r74463, they were causing test_xmlrpc to fail.
  We do not need to force a close when using socket buffering on a
  httplib.HTTPRequest as the library does not support streaming requests
  so there should never been extra data beyond the end of the current
  request to have left over in the requests socket buffer.
  
  see http://bugs.python.org/issue6724
........
  r74523 | gregory.p.smith | 2009-08-20 06:38:43 -0300 (Thu, 20 Aug 2009) | 2 lines
  
  comment typo fix
........
  r74524 | gregory.p.smith | 2009-08-20 06:39:38 -0300 (Thu, 20 Aug 2009) | 2 lines
  
  Add weakref support to the thread.lock type.
........
  r74526 | tarek.ziade | 2009-08-20 18:23:13 -0300 (Thu, 20 Aug 2009) | 1 line
  
  #6693: New functions in site.py to get user/global site packages paths.
........
  r74531 | vinay.sajip | 2009-08-20 19:04:32 -0300 (Thu, 20 Aug 2009) | 1 line
  
  Added section on exceptions raised during logging.
........
  r74533 | tarek.ziade | 2009-08-21 11:11:26 -0300 (Fri, 21 Aug 2009) | 1 line
  
  Fixed #6556: Corrected doc on how Distutils looks for its user configuration file under Windows
........
  r74537 | tarek.ziade | 2009-08-21 11:28:38 -0300 (Fri, 21 Aug 2009) | 1 line
  
  fixed misplaced Issue line
........


Modified:
   python/branches/tk_and_idle_maintenance/   (props changed)
   python/branches/tk_and_idle_maintenance/Doc/install/index.rst
   python/branches/tk_and_idle_maintenance/Doc/library/cgi.rst
   python/branches/tk_and_idle_maintenance/Doc/library/csv.rst
   python/branches/tk_and_idle_maintenance/Doc/library/logging.rst
   python/branches/tk_and_idle_maintenance/Doc/library/site.rst
   python/branches/tk_and_idle_maintenance/Doc/library/weakref.rst
   python/branches/tk_and_idle_maintenance/Lib/distutils/filelist.py
   python/branches/tk_and_idle_maintenance/Lib/distutils/tests/test_filelist.py
   python/branches/tk_and_idle_maintenance/Lib/fnmatch.py
   python/branches/tk_and_idle_maintenance/Lib/hashlib.py
   python/branches/tk_and_idle_maintenance/Lib/httplib.py
   python/branches/tk_and_idle_maintenance/Lib/lib-tk/ScrolledText.py
   python/branches/tk_and_idle_maintenance/Lib/lib-tk/Tix.py
   python/branches/tk_and_idle_maintenance/Lib/site.py
   python/branches/tk_and_idle_maintenance/Lib/test/test_array.py
   python/branches/tk_and_idle_maintenance/Lib/test/test_ast.py
   python/branches/tk_and_idle_maintenance/Lib/test/test_fnmatch.py
   python/branches/tk_and_idle_maintenance/Lib/test/test_module.py
   python/branches/tk_and_idle_maintenance/Lib/test/test_site.py
   python/branches/tk_and_idle_maintenance/Misc/ACKS
   python/branches/tk_and_idle_maintenance/Misc/NEWS
   python/branches/tk_and_idle_maintenance/Modules/threadmodule.c
   python/branches/tk_and_idle_maintenance/Objects/object.c
   python/branches/tk_and_idle_maintenance/Python/ast.c
   python/branches/tk_and_idle_maintenance/setup.py

Modified: python/branches/tk_and_idle_maintenance/Doc/install/index.rst
==============================================================================
--- python/branches/tk_and_idle_maintenance/Doc/install/index.rst	(original)
+++ python/branches/tk_and_idle_maintenance/Doc/install/index.rst	Sat Aug 22 17:20:52 2009
@@ -706,7 +706,8 @@
 (2)
    On Unix, if the :envvar:`HOME` environment variable is not defined, the user's
    home directory will be determined with the :func:`getpwuid` function from the
-   standard :mod:`pwd` module.
+   standard :mod:`pwd` module. This is done by the :func:`os.path.expanduser`
+   function used by Distutils.
 
 (3)
    I.e., in the current directory (usually the location of the setup script).
@@ -721,9 +722,10 @@
    1.5.2 installation under Windows.
 
 (5)
-   On Windows, if the :envvar:`HOME` environment variable is not defined, no
-   personal configuration file will be found or used.  (In other words, the
-   Distutils make no attempt to guess your home directory on Windows.)
+   On Windows, if the :envvar:`HOME` environment variable is not defined,
+   :envvar:`USERPROFILE` then :envvar:`HOMEDRIVE` and :envvar:`HOMEPATH` will
+   be tried. This is done by the :func:`os.path.expanduser` function used
+   by Distutils.
 
 
 .. _inst-config-syntax:

Modified: python/branches/tk_and_idle_maintenance/Doc/library/cgi.rst
==============================================================================
--- python/branches/tk_and_idle_maintenance/Doc/library/cgi.rst	(original)
+++ python/branches/tk_and_idle_maintenance/Doc/library/cgi.rst	Sat Aug 22 17:20:52 2009
@@ -213,7 +213,7 @@
 provide valid input to your scripts.  For example, if a curious user appends
 another ``user=foo`` pair to the query string, then the script would crash,
 because in this situation the ``getvalue("user")`` method call returns a list
-instead of a string.  Calling the :meth:`toupper` method on a list is not valid
+instead of a string.  Calling the :meth:`~str.upper` method on a list is not valid
 (since lists do not have a method of this name) and results in an
 :exc:`AttributeError` exception.
 

Modified: python/branches/tk_and_idle_maintenance/Doc/library/csv.rst
==============================================================================
--- python/branches/tk_and_idle_maintenance/Doc/library/csv.rst	(original)
+++ python/branches/tk_and_idle_maintenance/Doc/library/csv.rst	Sat Aug 22 17:20:52 2009
@@ -117,7 +117,7 @@
 
       >>> import csv
       >>> spamWriter = csv.writer(open('eggs.csv', 'w'), delimiter=' ',
-      ...                         quotechar='|', quoting=QUOTE_MINIMAL)
+      ...                         quotechar='|', quoting=csv.QUOTE_MINIMAL)
       >>> spamWriter.writerow(['Spam'] * 5 + ['Baked Beans'])
       >>> spamWriter.writerow(['Spam', 'Lovely Spam', 'Wonderful Spam'])
 

Modified: python/branches/tk_and_idle_maintenance/Doc/library/logging.rst
==============================================================================
--- python/branches/tk_and_idle_maintenance/Doc/library/logging.rst	(original)
+++ python/branches/tk_and_idle_maintenance/Doc/library/logging.rst	Sat Aug 22 17:20:52 2009
@@ -1211,6 +1211,28 @@
 This example uses console and file handlers, but you can use any number and
 combination of handlers you choose.
 
+.. _logging-exceptions:
+
+Exceptions raised during logging
+--------------------------------
+
+The logging package is designed to swallow exceptions which occur while logging
+in production. This is so that errors which occur while handling logging events
+- such as logging misconfiguration, network or other similar errors - do not
+cause the application using logging to terminate prematurely.
+
+:class:`SystemExit` and :class:`KeyboardInterrupt` exceptions are never
+swallowed. Other exceptions which occur during the :meth:`emit` method of a
+:class:`Handler` subclass are passed to its :meth:`handleError` method.
+
+The default implementation of :meth:`handleError` in :class:`Handler` checks
+to see if a module-level variable, `raiseExceptions`, is set. If set, a
+traceback is printed to `sys.stderr`. If not set, the exception is swallowed.
+
+**Note:** The default value of `raiseExceptions` is `True`. This is because
+during development, you typically want to be notified of any exceptions that
+occur. It's advised that you set `raiseExceptions` to `False` for production
+usage.
 
 .. _context-info:
 
@@ -1337,6 +1359,31 @@
 
 The :class:`LoggerAdapter` class was not present in previous versions.
 
+.. _multiple-processes:
+
+Logging to a single file from multiple processes
+------------------------------------------------
+
+Although logging is thread-safe, and logging to a single file from multiple
+threads in a single process *is* supported, logging to a single file from
+*multiple processes* is *not* supported, because there is no standard way to
+serialize access to a single file across multiple processes in Python. If you
+need to log to a single file from multiple processes, the best way of doing
+this is to have all the processes log to a :class:`SocketHandler`, and have a
+separate process which implements a socket server which reads from the socket
+and logs to file. (If you prefer, you can dedicate one thread in one of the
+existing processes to perform this function.) The following section documents
+this approach in more detail and includes a working socket receiver which can
+be used as a starting point for you to adapt in your own applications.
+
+If you are using a recent version of Python which includes the
+:mod:`multiprocessing` module, you can write your own handler which uses the
+:class:`Lock` class from this module to serialize access to the file from
+your processes. The existing :class:`FileHandler` and subclasses do not make
+use of :mod:`multiprocessing` at present, though they may do so in the future.
+Note that at present, the :mod:`multiprocessing` module does not provide
+working lock functionality on all platforms (see
+http://bugs.python.org/issue3770).
 
 .. _network-logging:
 

Modified: python/branches/tk_and_idle_maintenance/Doc/library/site.rst
==============================================================================
--- python/branches/tk_and_idle_maintenance/Doc/library/site.rst	(original)
+++ python/branches/tk_and_idle_maintenance/Doc/library/site.rst	Sat Aug 22 17:20:52 2009
@@ -131,6 +131,32 @@
 
    Adds a directory to sys.path and processes its pth files.
 
+.. function:: getsitepackages()
+
+   Returns a list containing all global site-packages directories
+   (and possibly site-python).
+
+   .. versionadded:: 2.7
+
+.. function:: getuserbase()
+
+   Returns the `user base` directory path.
+
+   The `user base` directory can be used to store data. If the global
+   variable ``USER_BASE`` is not initialized yet, this function will also set
+   it.
+
+   .. versionadded:: 2.7
+
+.. function:: getusersitepackages()
+
+   Returns the user-specific site-packages directory path.
+
+   If the global variable ``USER_SITE`` is not initialized yet, this
+   function will also set it.
+
+   .. versionadded:: 2.7
 
 XXX Update documentation
 XXX document python -m site --user-base --user-site
+

Modified: python/branches/tk_and_idle_maintenance/Doc/library/weakref.rst
==============================================================================
--- python/branches/tk_and_idle_maintenance/Doc/library/weakref.rst	(original)
+++ python/branches/tk_and_idle_maintenance/Doc/library/weakref.rst	Sat Aug 22 17:20:52 2009
@@ -65,6 +65,9 @@
 .. versionchanged:: 2.4
    Added support for files, sockets, arrays, and patterns.
 
+.. versionchanged:: 2.7
+   Added support for thread.lock and threading.Lock.
+
 Several built-in types such as :class:`list` and :class:`dict` do not directly
 support weak references but can add support through subclassing::
 

Modified: python/branches/tk_and_idle_maintenance/Lib/distutils/filelist.py
==============================================================================
--- python/branches/tk_and_idle_maintenance/Lib/distutils/filelist.py	(original)
+++ python/branches/tk_and_idle_maintenance/Lib/distutils/filelist.py	Sat Aug 22 17:20:52 2009
@@ -6,15 +6,13 @@
 
 __revision__ = "$Id$"
 
-import os, string, re
+import os, re
 import fnmatch
-from types import *
 from distutils.util import convert_path
 from distutils.errors import DistutilsTemplateError, DistutilsInternalError
 from distutils import log
 
 class FileList:
-
     """A list of files built by on exploring the filesystem and filtered by
     applying various patterns to what we find there.
 
@@ -29,22 +27,19 @@
         filtering applied)
     """
 
-    def __init__(self,
-                 warn=None,
-                 debug_print=None):
+    def __init__(self, warn=None, debug_print=None):
         # ignore argument to FileList, but keep them for backwards
         # compatibility
-
         self.allfiles = None
         self.files = []
 
-    def set_allfiles (self, allfiles):
+    def set_allfiles(self, allfiles):
         self.allfiles = allfiles
 
-    def findall (self, dir=os.curdir):
+    def findall(self, dir=os.curdir):
         self.allfiles = findall(dir)
 
-    def debug_print (self, msg):
+    def debug_print(self, msg):
         """Print 'msg' to stdout if the global DEBUG (taken from the
         DISTUTILS_DEBUG environment variable) flag is true.
         """
@@ -54,13 +49,13 @@
 
     # -- List-like methods ---------------------------------------------
 
-    def append (self, item):
+    def append(self, item):
         self.files.append(item)
 
-    def extend (self, items):
+    def extend(self, items):
         self.files.extend(items)
 
-    def sort (self):
+    def sort(self):
         # Not a strict lexical sort!
         sortable_files = map(os.path.split, self.files)
         sortable_files.sort()
@@ -71,7 +66,7 @@
 
     # -- Other miscellaneous utility methods ---------------------------
 
-    def remove_duplicates (self):
+    def remove_duplicates(self):
         # Assumes list has been sorted!
         for i in range(len(self.files) - 1, 0, -1):
             if self.files[i] == self.files[i - 1]:
@@ -80,8 +75,8 @@
 
     # -- "File template" methods ---------------------------------------
 
-    def _parse_template_line (self, line):
-        words = string.split(line)
+    def _parse_template_line(self, line):
+        words = line.split()
         action = words[0]
 
         patterns = dir = dir_pattern = None
@@ -114,44 +109,40 @@
 
         return (action, patterns, dir, dir_pattern)
 
-    # _parse_template_line ()
-
-
-    def process_template_line (self, line):
-
+    def process_template_line(self, line):
         # Parse the line: split it up, make sure the right number of words
         # is there, and return the relevant words.  'action' is always
         # defined: it's the first word of the line.  Which of the other
         # three are defined depends on the action; it'll be either
         # patterns, (dir and patterns), or (dir_pattern).
-        (action, patterns, dir, dir_pattern) = self._parse_template_line(line)
+        action, patterns, dir, dir_pattern = self._parse_template_line(line)
 
         # OK, now we know that the action is valid and we have the
         # right number of words on the line for that action -- so we
         # can proceed with minimal error-checking.
         if action == 'include':
-            self.debug_print("include " + string.join(patterns))
+            self.debug_print("include " + ' '.join(patterns))
             for pattern in patterns:
                 if not self.include_pattern(pattern, anchor=1):
                     log.warn("warning: no files found matching '%s'",
                              pattern)
 
         elif action == 'exclude':
-            self.debug_print("exclude " + string.join(patterns))
+            self.debug_print("exclude " + ' '.join(patterns))
             for pattern in patterns:
                 if not self.exclude_pattern(pattern, anchor=1):
                     log.warn(("warning: no previously-included files "
                               "found matching '%s'"), pattern)
 
         elif action == 'global-include':
-            self.debug_print("global-include " + string.join(patterns))
+            self.debug_print("global-include " + ' '.join(patterns))
             for pattern in patterns:
                 if not self.include_pattern(pattern, anchor=0):
                     log.warn(("warning: no files found matching '%s' " +
                               "anywhere in distribution"), pattern)
 
         elif action == 'global-exclude':
-            self.debug_print("global-exclude " + string.join(patterns))
+            self.debug_print("global-exclude " + ' '.join(patterns))
             for pattern in patterns:
                 if not self.exclude_pattern(pattern, anchor=0):
                     log.warn(("warning: no previously-included files matching "
@@ -160,7 +151,7 @@
 
         elif action == 'recursive-include':
             self.debug_print("recursive-include %s %s" %
-                             (dir, string.join(patterns)))
+                             (dir, ' '.join(patterns)))
             for pattern in patterns:
                 if not self.include_pattern(pattern, prefix=dir):
                     log.warn(("warning: no files found matching '%s' " +
@@ -169,7 +160,7 @@
 
         elif action == 'recursive-exclude':
             self.debug_print("recursive-exclude %s %s" %
-                             (dir, string.join(patterns)))
+                             (dir, ' '.join(patterns)))
             for pattern in patterns:
                 if not self.exclude_pattern(pattern, prefix=dir):
                     log.warn(("warning: no previously-included files matching "
@@ -191,18 +182,15 @@
             raise DistutilsInternalError, \
                   "this cannot happen: invalid action '%s'" % action
 
-    # process_template_line ()
-
-
     # -- Filtering/selection methods -----------------------------------
 
-    def include_pattern (self, pattern,
-                         anchor=1, prefix=None, is_regex=0):
+    def include_pattern(self, pattern, anchor=1, prefix=None, is_regex=0):
         """Select strings (presumably filenames) from 'self.files' that
-        match 'pattern', a Unix-style wildcard (glob) pattern.  Patterns
-        are not quite the same as implemented by the 'fnmatch' module: '*'
-        and '?'  match non-special characters, where "special" is platform-
-        dependent: slash on Unix; colon, slash, and backslash on
+        match 'pattern', a Unix-style wildcard (glob) pattern.
+
+        Patterns are not quite the same as implemented by the 'fnmatch'
+        module: '*' and '?'  match non-special characters, where "special"
+        is platform-dependent: slash on Unix; colon, slash, and backslash on
         DOS/Windows; and colon on Mac OS.
 
         If 'anchor' is true (the default), then the pattern match is more
@@ -239,16 +227,14 @@
 
         return files_found
 
-    # include_pattern ()
-
 
-    def exclude_pattern (self, pattern,
-                         anchor=1, prefix=None, is_regex=0):
+    def exclude_pattern(self, pattern, anchor=1, prefix=None, is_regex=0):
         """Remove strings (presumably filenames) from 'files' that match
-        'pattern'.  Other parameters are the same as for
-        'include_pattern()', above.
-        The list 'self.files' is modified in place.
-        Return 1 if files are found.
+        'pattern'.
+
+        Other parameters are the same as for 'include_pattern()', above.
+        The list 'self.files' is modified in place. Return 1 if files are
+        found.
         """
         files_found = 0
         pattern_re = translate_pattern(pattern, anchor, prefix, is_regex)
@@ -262,15 +248,11 @@
 
         return files_found
 
-    # exclude_pattern ()
-
-# class FileList
-
 
 # ----------------------------------------------------------------------
 # Utility functions
 
-def findall (dir = os.curdir):
+def findall(dir = os.curdir):
     """Find all files under 'dir' and return the list of full filenames
     (relative to 'dir').
     """
@@ -303,10 +285,11 @@
 
 
 def glob_to_re(pattern):
-    """Translate a shell-like glob pattern to a regular expression; return
-    a string containing the regex.  Differs from 'fnmatch.translate()' in
-    that '*' does not match "special characters" (which are
-    platform-specific).
+    """Translate a shell-like glob pattern to a regular expression.
+
+    Return a string containing the regex.  Differs from
+    'fnmatch.translate()' in that '*' does not match "special characters"
+    (which are platform-specific).
     """
     pattern_re = fnmatch.translate(pattern)
 
@@ -321,17 +304,17 @@
 
     return pattern_re
 
-# glob_to_re ()
-
 
-def translate_pattern (pattern, anchor=1, prefix=None, is_regex=0):
+def translate_pattern(pattern, anchor=1, prefix=None, is_regex=0):
     """Translate a shell-like wildcard pattern to a compiled regular
-    expression.  Return the compiled regex.  If 'is_regex' true,
+    expression.
+
+    Return the compiled regex.  If 'is_regex' true,
     then 'pattern' is directly compiled to a regex (if it's a string)
     or just returned as-is (assumes it's a regex object).
     """
     if is_regex:
-        if type(pattern) is StringType:
+        if isinstance(pattern, str):
             return re.compile(pattern)
         else:
             return pattern
@@ -342,12 +325,12 @@
         pattern_re = ''
 
     if prefix is not None:
-        prefix_re = (glob_to_re(prefix))[0:-1] # ditch trailing $
+        # ditch end of pattern character
+        empty_pattern = glob_to_re('')
+        prefix_re = glob_to_re(prefix)[:-len(empty_pattern)]
         pattern_re = "^" + os.path.join(prefix_re, ".*" + pattern_re)
     else:                               # no prefix -- respect anchor flag
         if anchor:
             pattern_re = "^" + pattern_re
 
     return re.compile(pattern_re)
-
-# translate_pattern ()

Modified: python/branches/tk_and_idle_maintenance/Lib/distutils/tests/test_filelist.py
==============================================================================
--- python/branches/tk_and_idle_maintenance/Lib/distutils/tests/test_filelist.py	(original)
+++ python/branches/tk_and_idle_maintenance/Lib/distutils/tests/test_filelist.py	Sat Aug 22 17:20:52 2009
@@ -1,20 +1,63 @@
 """Tests for distutils.filelist."""
+from os.path import join
 import unittest
-from distutils.filelist import glob_to_re
+from distutils.filelist import glob_to_re, FileList
+
+MANIFEST_IN = """\
+include ok
+include xo
+exclude xo
+include foo.tmp
+global-include *.x
+global-include *.txt
+global-exclude *.tmp
+recursive-include f *.oo
+recursive-exclude global *.x
+graft dir
+prune dir3
+"""
 
 class FileListTestCase(unittest.TestCase):
 
     def test_glob_to_re(self):
         # simple cases
-        self.assertEquals(glob_to_re('foo*'), 'foo[^/]*$')
-        self.assertEquals(glob_to_re('foo?'), 'foo[^/]$')
-        self.assertEquals(glob_to_re('foo??'), 'foo[^/][^/]$')
+        self.assertEquals(glob_to_re('foo*'), 'foo[^/]*\\Z(?ms)')
+        self.assertEquals(glob_to_re('foo?'), 'foo[^/]\\Z(?ms)')
+        self.assertEquals(glob_to_re('foo??'), 'foo[^/][^/]\\Z(?ms)')
 
         # special cases
-        self.assertEquals(glob_to_re(r'foo\\*'), r'foo\\\\[^/]*$')
-        self.assertEquals(glob_to_re(r'foo\\\*'), r'foo\\\\\\[^/]*$')
-        self.assertEquals(glob_to_re('foo????'), r'foo[^/][^/][^/][^/]$')
-        self.assertEquals(glob_to_re(r'foo\\??'), r'foo\\\\[^/][^/]$')
+        self.assertEquals(glob_to_re(r'foo\\*'), r'foo\\\\[^/]*\Z(?ms)')
+        self.assertEquals(glob_to_re(r'foo\\\*'), r'foo\\\\\\[^/]*\Z(?ms)')
+        self.assertEquals(glob_to_re('foo????'), r'foo[^/][^/][^/][^/]\Z(?ms)')
+        self.assertEquals(glob_to_re(r'foo\\??'), r'foo\\\\[^/][^/]\Z(?ms)')
+
+    def test_process_template_line(self):
+        # testing  all MANIFEST.in template patterns
+        file_list = FileList()
+
+        # simulated file list
+        file_list.allfiles = ['foo.tmp', 'ok', 'xo', 'four.txt',
+                              join('global', 'one.txt'),
+                              join('global', 'two.txt'),
+                              join('global', 'files.x'),
+                              join('global', 'here.tmp'),
+                              join('f', 'o', 'f.oo'),
+                              join('dir', 'graft-one'),
+                              join('dir', 'dir2', 'graft2'),
+                              join('dir3', 'ok'),
+                              join('dir3', 'sub', 'ok.txt')
+                              ]
+
+        for line in MANIFEST_IN.split('\n'):
+            if line.strip() == '':
+                continue
+            file_list.process_template_line(line)
+
+        wanted = ['ok', 'four.txt', join('global', 'one.txt'),
+                  join('global', 'two.txt'), join('f', 'o', 'f.oo'),
+                  join('dir', 'graft-one'), join('dir', 'dir2', 'graft2')]
+
+        self.assertEquals(file_list.files, wanted)
 
 def test_suite():
     return unittest.makeSuite(FileListTestCase)

Modified: python/branches/tk_and_idle_maintenance/Lib/fnmatch.py
==============================================================================
--- python/branches/tk_and_idle_maintenance/Lib/fnmatch.py	(original)
+++ python/branches/tk_and_idle_maintenance/Lib/fnmatch.py	Sat Aug 22 17:20:52 2009
@@ -104,4 +104,4 @@
                 res = '%s[%s]' % (res, stuff)
         else:
             res = res + re.escape(c)
-    return res + "$"
+    return res + '\Z(?ms)'

Modified: python/branches/tk_and_idle_maintenance/Lib/hashlib.py
==============================================================================
--- python/branches/tk_and_idle_maintenance/Lib/hashlib.py	(original)
+++ python/branches/tk_and_idle_maintenance/Lib/hashlib.py	Sat Aug 22 17:20:52 2009
@@ -54,6 +54,12 @@
 
 """
 
+# This tuple and __get_builtin_constructor() must be modified if a new
+# always available algorithm is added.
+__always_supported = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512')
+
+__all__ = __always_supported + ('new',)
+
 
 def __get_builtin_constructor(name):
     if name in ('SHA1', 'sha1'):
@@ -77,7 +83,19 @@
         elif bs == '384':
             return _sha512.sha384
 
-    raise ValueError, "unsupported hash type"
+    raise ValueError('unsupported hash type %s' % name)
+
+
+def __get_openssl_constructor(name):
+    try:
+        f = getattr(_hashlib, 'openssl_' + name)
+        # Allow the C module to raise ValueError.  The function will be
+        # defined but the hash not actually available thanks to OpenSSL.
+        f()
+        # Use the C function directly (very fast)
+        return f
+    except (AttributeError, ValueError):
+        return __get_builtin_constructor(name)
 
 
 def __py_new(name, string=''):
@@ -103,39 +121,21 @@
 
 try:
     import _hashlib
-    # use the wrapper of the C implementation
     new = __hash_new
-
-    for opensslFuncName in filter(lambda n: n.startswith('openssl_'), dir(_hashlib)):
-        funcName = opensslFuncName[len('openssl_'):]
-        try:
-            # try them all, some may not work due to the OpenSSL
-            # version not supporting that algorithm.
-            f = getattr(_hashlib, opensslFuncName)
-            f()
-            # Use the C function directly (very fast)
-            exec funcName + ' = f'
-        except ValueError:
-            try:
-                # Use the builtin implementation directly (fast)
-                exec funcName + ' = __get_builtin_constructor(funcName)'
-            except ValueError:
-                # this one has no builtin implementation, don't define it
-                pass
-    # clean up our locals
-    del f
-    del opensslFuncName
-    del funcName
-
+    __get_hash = __get_openssl_constructor
 except ImportError:
-    # We don't have the _hashlib OpenSSL module?
-    # use the built in legacy interfaces via a wrapper function
     new = __py_new
+    __get_hash = __get_builtin_constructor
+
+for __func_name in __always_supported:
+    # try them all, some may not work due to the OpenSSL
+    # version not supporting that algorithm.
+    try:
+        globals()[__func_name] = __get_hash(__func_name)
+    except ValueError:
+        import logging
+        logging.exception('code for hash %s was not found.', __func_name)
 
-    # lookup the C function to use directly for the named constructors
-    md5 = __get_builtin_constructor('md5')
-    sha1 = __get_builtin_constructor('sha1')
-    sha224 = __get_builtin_constructor('sha224')
-    sha256 = __get_builtin_constructor('sha256')
-    sha384 = __get_builtin_constructor('sha384')
-    sha512 = __get_builtin_constructor('sha512')
+# Cleanup locals()
+del __always_supported, __func_name, __get_hash
+del __py_new, __hash_new, __get_openssl_constructor

Modified: python/branches/tk_and_idle_maintenance/Lib/httplib.py
==============================================================================
--- python/branches/tk_and_idle_maintenance/Lib/httplib.py	(original)
+++ python/branches/tk_and_idle_maintenance/Lib/httplib.py	Sat Aug 22 17:20:52 2009
@@ -328,7 +328,7 @@
     def __init__(self, sock, debuglevel=0, strict=0, method=None, buffering=False):
         if buffering:
             # The caller won't be using any sock.recv() calls, so buffering
-            # is fine and recommendef for performance
+            # is fine and recommended for performance.
             self.fp = sock.makefile('rb')
         else:
             # The buffer size is specified as zero, because the headers of
@@ -622,6 +622,11 @@
         reading. If the bytes are truly not available (due to EOF), then the
         IncompleteRead exception can be used to detect the problem.
         """
+        # NOTE(gps): As of svn r74426 socket._fileobject.read(x) will never
+        # return less than x bytes unless EOF is encountered.  It now handles
+        # signal interruptions (socket.error EINTR) internally.  This code
+        # never caught that exception anyways.  It seems largely pointless.
+        # self.fp.read(amt) will work fine.
         s = []
         while amt > 0:
             chunk = self.fp.read(min(amt, MAXAMOUNT))

Modified: python/branches/tk_and_idle_maintenance/Lib/lib-tk/ScrolledText.py
==============================================================================
--- python/branches/tk_and_idle_maintenance/Lib/lib-tk/ScrolledText.py	(original)
+++ python/branches/tk_and_idle_maintenance/Lib/lib-tk/ScrolledText.py	Sat Aug 22 17:20:52 2009
@@ -27,8 +27,11 @@
         self.pack(side=LEFT, fill=BOTH, expand=True)
         self.vbar['command'] = self.yview
 
-        # Copy geometry methods of self.frame -- hack!
+        # Copy geometry methods of self.frame without overriding Text
+        # methods -- hack!
+        text_meths = vars(Text).keys()
         methods = vars(Pack).keys() + vars(Grid).keys() + vars(Place).keys()
+        methods = set(methods).difference(text_meths)
 
         for m in methods:
             if m[0] != '_' and m != 'config' and m != 'configure':

Modified: python/branches/tk_and_idle_maintenance/Lib/lib-tk/Tix.py
==============================================================================
--- python/branches/tk_and_idle_maintenance/Lib/lib-tk/Tix.py	(original)
+++ python/branches/tk_and_idle_maintenance/Lib/lib-tk/Tix.py	Sat Aug 22 17:20:52 2009
@@ -46,6 +46,21 @@
 AUTO = 'auto'
 ACROSSTOP = 'acrosstop'
 
+# A few useful constants for the Grid widget
+ASCII = 'ascii'
+CELL = 'cell'
+COLUMN = 'column'
+DECREASING = 'decreasing'
+INCREASING = 'increasing'
+INTEGER = 'integer'
+MAIN = 'main'
+MAX = 'max'
+REAL = 'real'
+ROW = 'row'
+S_REGION = 's-region'
+X_REGION = 'x-region'
+Y_REGION = 'y-region'
+
 # Some constants used by Tkinter dooneevent()
 TCL_DONT_WAIT     = 1 << 1
 TCL_WINDOW_EVENTS = 1 << 2
@@ -961,6 +976,10 @@
     def info_anchor(self):
         return self.tk.call(self._w, 'info', 'anchor')
 
+    def info_bbox(self, entry):
+        return self._getints(
+                self.tk.call(self._w, 'info', 'bbox', entry)) or None
+
     def info_children(self, entry=None):
         c = self.tk.call(self._w, 'info', 'children', entry)
         return self.tk.splitlist(c)
@@ -968,6 +987,12 @@
     def info_data(self, entry):
         return self.tk.call(self._w, 'info', 'data', entry)
 
+    def info_dragsite(self):
+        return self.tk.call(self._w, 'info', 'dragsite')
+
+    def info_dropsite(self):
+        return self.tk.call(self._w, 'info', 'dropsite')
+
     def info_exists(self, entry):
         return self.tk.call(self._w, 'info', 'exists', entry)
 
@@ -1176,7 +1201,8 @@
     menu            Menu"""
 
     def __init__(self, master, cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixOptionMenu', ['options'], cnf, kw)
+        TixWidget.__init__(self, master, 'tixOptionMenu',
+                ['labelside', 'options'], cnf, kw)
         self.subwidget_list['menubutton'] = _dummyMenubutton(self, 'menubutton')
         self.subwidget_list['menu'] = _dummyMenu(self, 'menu')
 
@@ -1235,11 +1261,8 @@
         self.tk.call(self._w, 'paneconfigure', entry, *self._options(cnf, kw))
 
     def panes(self):
-        names = self.tk.call(self._w, 'panes')
-        ret = []
-        for x in names:
-            ret.append(self.subwidget(x))
-        return ret
+        names = self.tk.splitlist(self.tk.call(self._w, 'panes'))
+        return [self.subwidget(x) for x in names]
 
 class PopupMenu(TixWidget):
     """PopupMenu widget can be used as a replacement of the tk_popup command.
@@ -1551,7 +1574,7 @@
     # FIXME: It should inherit -superclass tixTree
     def __init__(self, master=None, cnf={}, **kw):
         TixWidget.__init__(self, master, 'tixCheckList',
-                           ['options'], cnf, kw)
+                           ['options', 'radio'], cnf, kw)
         self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
         self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
         self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
@@ -1789,16 +1812,21 @@
         TixWidget.__init__(self, master, 'tixGrid', static, cnf, kw)
 
     # valid options as of Tk 8.4
-    # anchor, bdtype, cget, configure, delete, dragsite, dropsite, entrycget, edit
-    # entryconfigure, format, geometryinfo, info, index, move, nearest, selection
-    # set, size, unset, xview, yview
-    # def anchor option ?args ...?
+    # anchor, bdtype, cget, configure, delete, dragsite, dropsite, entrycget,
+    # edit, entryconfigure, format, geometryinfo, info, index, move, nearest,
+    # selection, set, size, unset, xview, yview
+    def anchor_clear(self):
+        """Removes the selection anchor."""
+        self.tk.call(self, 'anchor', 'clear')
+
     def anchor_get(self):
         "Get the (x,y) coordinate of the current anchor cell"
         return self._getints(self.tk.call(self, 'anchor', 'get'))
 
-    # def bdtype
-    # def delete dim from ?to?
+    def anchor_set(self, x, y):
+        """Set the selection anchor to the cell at (x, y)."""
+        self.tk.call(self, 'anchor', 'set', x, y)
+
     def delete_row(self, from_, to=None):
         """Delete rows between from_ and to inclusive.
         If to is not provided,  delete only row at from_"""
@@ -1806,6 +1834,7 @@
             self.tk.call(self, 'delete', 'row', from_)
         else:
             self.tk.call(self, 'delete', 'row', from_, to)
+
     def delete_column(self, from_, to=None):
         """Delete columns between from_ and to inclusive.
         If to is not provided,  delete only column at from_"""
@@ -1813,26 +1842,49 @@
             self.tk.call(self, 'delete', 'column', from_)
         else:
             self.tk.call(self, 'delete', 'column', from_, to)
-    # def edit apply
-    # def edit set x y
+
+    def edit_apply(self):
+        """If any cell is being edited, de-highlight the cell  and  applies
+        the changes."""
+        self.tk.call(self, 'edit', 'apply')
+
+    def edit_set(self, x, y):
+        """Highlights  the  cell  at  (x, y) for editing, if the -editnotify
+        command returns True for this cell."""
+        self.tk.call(self, 'edit', 'set', x, y)
 
     def entrycget(self, x, y, option):
         "Get the option value for cell at (x,y)"
+        if option and option[0] != '-':
+            option = '-' + option
         return self.tk.call(self, 'entrycget', x, y, option)
 
-    def entryconfigure(self, x, y, **kw):
-        return self.tk.call(self, 'entryconfigure', x, y, *self._options(None, kw))
+    def entryconfigure(self, x, y, cnf=None, **kw):
+        return self._configure(('entryconfigure', x, y), cnf, kw)
+
     # def format
     # def index
 
     def info_exists(self, x, y):
         "Return True if display item exists at (x,y)"
-        return bool(int(self.tk.call(self, 'info', 'exists', x, y)))
+        return self._getboolean(self.tk.call(self, 'info', 'exists', x, y))
 
     def info_bbox(self, x, y):
         # This seems to always return '', at least for 'text' displayitems
         return self.tk.call(self, 'info', 'bbox', x, y)
 
+    def move_column(self, from_, to, offset):
+        """Moves the the range of columns from position FROM through TO by
+        the distance indicated by OFFSET. For example, move_column(2, 4, 1)
+        moves the columns 2,3,4 to columns 3,4,5."""
+        self.tk.call(self, 'move', 'column', from_, to, offset)
+
+    def move_row(self, from_, to, offset):
+        """Moves the the range of rows from position FROM through TO by
+        the distance indicated by OFFSET.
+        For example, move_row(2, 4, 1) moves the rows 2,3,4 to rows 3,4,5."""
+        self.tk.call(self, 'move', 'row', from_, to, offset)
+
     def nearest(self, x, y):
         "Return coordinate of cell nearest pixel coordinate (x,y)"
         return self._getints(self.tk.call(self, 'nearest', x, y))
@@ -1842,7 +1894,6 @@
     # def selection includes
     # def selection set
     # def selection toggle
-    # def move dim from to offset
 
     def set(self, x, y, itemtype=None, **kw):
         args= self._options(self.cnf, kw)
@@ -1850,8 +1901,59 @@
             args= ('-itemtype', itemtype) + args
         self.tk.call(self, 'set', x, y, *args)
 
-    # def size dim index ?option value ...?
-    # def unset x y
+    def size_column(self, index, **kw):
+        """Queries  or  sets the size of the column given by
+        INDEX.  INDEX may be any  non-negative
+        integer  that  gives  the  position  of a given column.
+        INDEX can also be the string "default"; in this case, this command
+        queries or sets the default size of all columns.
+        When  no  option-value  pair is given, this command returns a tuple
+        containing the current size setting of the given  column.  When
+        option-value  pairs  are  given,  the corresponding options of the
+        size setting of the given column are changed. Options may be one
+        of  the  follwing:
+              pad0 pixels
+                     Specifies the paddings to the left of a column.
+              pad1 pixels
+                     Specifies the paddings to the right of a  column.
+              size val
+                     Specifies  the  width of a column .
+                     Val may be: "auto" -- the width of the column is set the
+                     the widest cell in the column; a valid Tk screen distance
+                     unit; or a real number following by the word chars
+                     (e.g. 3.4chars) that sets the width of the column to the
+                     given number of characters."""
+        return self.tk.split(self.tk.call(self._w, 'size', 'column', index,
+                             *self._options({}, kw)))
+
+    def size_row(self, index, **kw):
+        """Queries  or  sets the size of the row given by
+        INDEX. INDEX may be any  non-negative
+        integer  that  gives  the  position  of a given row .
+        INDEX can also be the string "default"; in this case, this command
+        queries or sets the default size of all rows.
+        When  no option-value pair is given, this command returns a list con-
+        taining the current size setting of the given  row . When option-value
+        pairs are given, the corresponding options of the size setting of the
+        given row are changed. Options may be one of the follwing:
+              pad0 pixels
+                     Specifies the paddings to the top of a row.
+              pad1 pixels
+                     Specifies the paddings to the the bottom of a row.
+              size val
+                     Specifies  the height of a row.
+                     Val may be: "auto" -- the height of the row  is  set  the
+                     the highest cell in the row; a valid Tk screen distance
+                     unit; or a real number following by the word chars
+                     (e.g. 3.4chars) that sets the height of the row to the
+                     given number of characters."""
+        return self.tk.split(self.tk.call(
+                    self, 'size', 'row', index, *self._options({}, kw)))
+
+    def unset(self, x, y):
+        """Clears the cell at (x, y) by removing its display item."""
+        self.tk.call(self._w, 'unset', x, y)
+
 
 class ScrolledGrid(Grid):
     '''Scrolled Grid widgets'''

Modified: python/branches/tk_and_idle_maintenance/Lib/site.py
==============================================================================
--- python/branches/tk_and_idle_maintenance/Lib/site.py	(original)
+++ python/branches/tk_and_idle_maintenance/Lib/site.py	Sat Aug 22 17:20:52 2009
@@ -67,7 +67,10 @@
 # Enable per user site-packages directory
 # set it to False to disable the feature or True to force the feature
 ENABLE_USER_SITE = None
+
 # for distutils.commands.install
+# These values are initialized by the getuserbase() and getusersitepackages()
+# functions, through the main() function when Python starts.
 USER_SITE = None
 USER_BASE = None
 
@@ -212,49 +215,75 @@
 
     return True
 
+def getuserbase():
+    """Returns the `user base` directory path.
 
-def addusersitepackages(known_paths):
-    """Add a per user site-package to sys.path
-
-    Each user has its own python directory with site-packages in the
-    home directory.
-
-    USER_BASE is the root directory for all Python versions
-
-    USER_SITE is the user specific site-packages directory
-
-    USER_SITE/.. can be used for data.
+    The `user base` directory can be used to store data. If the global
+    variable ``USER_BASE`` is not initialized yet, this function will also set
+    it.
     """
-    global USER_BASE, USER_SITE, ENABLE_USER_SITE
+    global USER_BASE
+    if USER_BASE is not None:
+        return USER_BASE
+
     env_base = os.environ.get("PYTHONUSERBASE", None)
 
     def joinuser(*args):
         return os.path.expanduser(os.path.join(*args))
 
-    #if sys.platform in ('os2emx', 'riscos'):
-    #    # Don't know what to put here
-    #    USER_BASE = ''
-    #    USER_SITE = ''
+    # what about 'os2emx', 'riscos' ?
     if os.name == "nt":
         base = os.environ.get("APPDATA") or "~"
         USER_BASE = env_base if env_base else joinuser(base, "Python")
-        USER_SITE = os.path.join(USER_BASE,
-                                 "Python" + sys.version[0] + sys.version[2],
-                                 "site-packages")
     else:
         USER_BASE = env_base if env_base else joinuser("~", ".local")
-        USER_SITE = os.path.join(USER_BASE, "lib",
-                                 "python" + sys.version[:3],
+
+    return USER_BASE
+
+def getusersitepackages():
+    """Returns the user-specific site-packages directory path.
+
+    If the global variable ``USER_SITE`` is not initialized yet, this
+    function will also set it.
+    """
+    global USER_SITE
+    user_base = getuserbase() # this will also set USER_BASE
+
+    if USER_SITE is not None:
+        return USER_SITE
+
+    if os.name == "nt":
+        USER_SITE = os.path.join(user_base, "Python" + sys.version[0] +
+                                 sys.version[2], "site-packages")
+    else:
+        USER_SITE = os.path.join(user_base, "lib", "python" + sys.version[:3],
                                  "site-packages")
 
-    if ENABLE_USER_SITE and os.path.isdir(USER_SITE):
-        addsitedir(USER_SITE, known_paths)
-    return known_paths
+    return USER_SITE
 
+def addusersitepackages(known_paths):
+    """Add a per user site-package to sys.path
 
-def addsitepackages(known_paths):
-    """Add site-packages (and possibly site-python) to sys.path"""
-    sitedirs = []
+    Each user has its own python directory with site-packages in the
+    home directory.
+    """
+    # get the per user site-package path
+    # this call will also make sure USER_BASE and USER_SITE are set
+    user_site = getusersitepackages()
+
+    if ENABLE_USER_SITE and os.path.isdir(user_site):
+        addsitedir(user_site, known_paths)
+    return known_paths
+
+def getsitepackages():
+    """Returns a list containing all global site-packages directories
+    (and possibly site-python).
+
+    For each directory present in the global ``PREFIXES``, this function
+    will find its `site-packages` subdirectory depending on the system
+    environment, and will return a list of full paths.
+    """
+    sitepackages = []
     seen = []
 
     for prefix in PREFIXES:
@@ -263,35 +292,36 @@
         seen.append(prefix)
 
         if sys.platform in ('os2emx', 'riscos'):
-            sitedirs.append(os.path.join(prefix, "Lib", "site-packages"))
+            sitepackages.append(os.path.join(prefix, "Lib", "site-packages"))
         elif os.sep == '/':
-            sitedirs.append(os.path.join(prefix, "lib",
+            sitepackages.append(os.path.join(prefix, "lib",
                                         "python" + sys.version[:3],
                                         "site-packages"))
-            sitedirs.append(os.path.join(prefix, "lib", "site-python"))
+            sitepackages.append(os.path.join(prefix, "lib", "site-python"))
         else:
-            sitedirs.append(prefix)
-            sitedirs.append(os.path.join(prefix, "lib", "site-packages"))
-
+            sitepackages.append(prefix)
+            sitepackages.append(os.path.join(prefix, "lib", "site-packages"))
         if sys.platform == "darwin":
             # for framework builds *only* we add the standard Apple
             # locations.
             if 'Python.framework' in prefix:
-                sitedirs.append(
+                sitepackages.append(
                     os.path.expanduser(
                         os.path.join("~", "Library", "Python",
                                      sys.version[:3], "site-packages")))
-                sitedirs.append(
+                sitepackages.append(
                         os.path.join("/Library", "Python",
                             sys.version[:3], "site-packages"))
+    return sitepackages
 
-    for sitedir in sitedirs:
+def addsitepackages(known_paths):
+    """Add site-packages (and possibly site-python) to sys.path"""
+    for sitedir in getsitepackages():
         if os.path.isdir(sitedir):
             addsitedir(sitedir, known_paths)
 
     return known_paths
 
-
 def setBEGINLIBPATH():
     """The OS/2 EMX port has optional extension modules that do double duty
     as DLLs (and must use the .DLL file extension) for other extensions.

Modified: python/branches/tk_and_idle_maintenance/Lib/test/test_array.py
==============================================================================
--- python/branches/tk_and_idle_maintenance/Lib/test/test_array.py	(original)
+++ python/branches/tk_and_idle_maintenance/Lib/test/test_array.py	Sat Aug 22 17:20:52 2009
@@ -188,6 +188,25 @@
                 f.close()
             test_support.unlink(test_support.TESTFN)
 
+    def test_filewrite(self):
+        a = array.array(self.typecode, 2*self.example)
+        f = open(test_support.TESTFN, 'wb')
+        try:
+            f.write(a)
+            f.close()
+            b = array.array(self.typecode)
+            f = open(test_support.TESTFN, 'rb')
+            b.fromfile(f, len(self.example))
+            self.assertEqual(b, array.array(self.typecode, self.example))
+            self.assertNotEqual(a, b)
+            b.fromfile(f, len(self.example))
+            self.assertEqual(a, b)
+            f.close()
+        finally:
+            if not f.closed:
+                f.close()
+            test_support.unlink(test_support.TESTFN)
+
     def test_tofromlist(self):
         a = array.array(self.typecode, 2*self.example)
         b = array.array(self.typecode)

Modified: python/branches/tk_and_idle_maintenance/Lib/test/test_ast.py
==============================================================================
--- python/branches/tk_and_idle_maintenance/Lib/test/test_ast.py	(original)
+++ python/branches/tk_and_idle_maintenance/Lib/test/test_ast.py	Sat Aug 22 17:20:52 2009
@@ -64,6 +64,10 @@
     "break",
     # Continue
     "continue",
+    # for statements with naked tuples (see http://bugs.python.org/issue6704)
+    "for a,b in c: pass",
+    "[(a,b) for a,b in c]",
+    "((a,b) for a,b in c)",
 ]
 
 # These are compiled through "single"
@@ -301,7 +305,7 @@
             print kind+"_results = ["
             for s in statements:
                 print repr(to_tuple(compile(s, "?", kind, 0x400)))+","
-                print "]"
+            print "]"
         print "main()"
         raise SystemExit
     test_main()
@@ -330,6 +334,9 @@
 ('Module', [('Pass', (1, 0))]),
 ('Module', [('Break', (1, 0))]),
 ('Module', [('Continue', (1, 0))]),
+('Module', [('For', (1, 0), ('Tuple', (1, 4), [('Name', (1, 4), 'a', ('Store',)), ('Name', (1, 6), 'b', ('Store',))], ('Store',)), ('Name', (1, 11), 'c', ('Load',)), [('Pass', (1, 14))], [])]),
+('Module', [('Expr', (1, 0), ('ListComp', (1, 1), ('Tuple', (1, 2), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [])]))]),
+('Module', [('Expr', (1, 0), ('GeneratorExp', (1, 1), ('Tuple', (1, 2), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [])]))]),
 ]
 single_results = [
 ('Interactive', [('Expr', (1, 0), ('BinOp', (1, 0), ('Num', (1, 0), 1), ('Add',), ('Num', (1, 2), 2)))]),

Modified: python/branches/tk_and_idle_maintenance/Lib/test/test_fnmatch.py
==============================================================================
--- python/branches/tk_and_idle_maintenance/Lib/test/test_fnmatch.py	(original)
+++ python/branches/tk_and_idle_maintenance/Lib/test/test_fnmatch.py	Sat Aug 22 17:20:52 2009
@@ -32,11 +32,18 @@
         check('a', 'b', 0)
 
         # these test that '\' is handled correctly in character sets;
-        # see SF bug #???
+        # see SF bug #409651
         check('\\', r'[\]')
         check('a', r'[!\]')
         check('\\', r'[!\]', 0)
 
+        # test that filenames with newlines in them are handled correctly.
+        # http://bugs.python.org/issue6665
+        check('foo\nbar', 'foo*')
+        check('foo\nbar\n', 'foo*')
+        check('\nfoo', 'foo*', False)
+        check('\n', '*')
+
 
 def test_main():
     test_support.run_unittest(FnmatchTestCase)

Modified: python/branches/tk_and_idle_maintenance/Lib/test/test_module.py
==============================================================================
--- python/branches/tk_and_idle_maintenance/Lib/test/test_module.py	(original)
+++ python/branches/tk_and_idle_maintenance/Lib/test/test_module.py	Sat Aug 22 17:20:52 2009
@@ -11,6 +11,7 @@
         # and __doc__ is None
         foo = ModuleType.__new__(ModuleType)
         self.assertTrue(foo.__dict__ is None)
+        self.assertRaises(SystemError, dir, foo)
         try:
             s = foo.__name__
             self.fail("__name__ = %s" % repr(s))

Modified: python/branches/tk_and_idle_maintenance/Lib/test/test_site.py
==============================================================================
--- python/branches/tk_and_idle_maintenance/Lib/test/test_site.py	(original)
+++ python/branches/tk_and_idle_maintenance/Lib/test/test_site.py	Sat Aug 22 17:20:52 2009
@@ -35,10 +35,16 @@
     def setUp(self):
         """Save a copy of sys.path"""
         self.sys_path = sys.path[:]
+        self.old_base = site.USER_BASE
+        self.old_site = site.USER_SITE
+        self.old_prefixes = site.PREFIXES
 
     def tearDown(self):
         """Restore sys.path"""
         sys.path = self.sys_path
+        site.USER_BASE = self.old_base
+        site.USER_SITE = self.old_site
+        site.PREFIXES = self.old_prefixes
 
     def test_makepath(self):
         # Test makepath() have an absolute path for its first return value
@@ -123,6 +129,60 @@
             env=env)
         self.assertEqual(rc, 1)
 
+    def test_getuserbase(self):
+        site.USER_BASE = None
+        user_base = site.getuserbase()
+
+        # the call sets site.USER_BASE
+        self.assertEquals(site.USER_BASE, user_base)
+
+        # let's set PYTHONUSERBASE and see if it uses it
+        site.USER_BASE = None
+        with EnvironmentVarGuard() as environ:
+            environ['PYTHONUSERBASE'] = 'xoxo'
+            self.assertTrue(site.getuserbase().startswith('xoxo'))
+
+    def test_getusersitepackages(self):
+        site.USER_SITE = None
+        site.USER_BASE = None
+        user_site = site.getusersitepackages()
+
+        # the call sets USER_BASE *and* USER_SITE
+        self.assertEquals(site.USER_SITE, user_site)
+        self.assertTrue(user_site.startswith(site.USER_BASE))
+
+    def test_getsitepackages(self):
+        site.PREFIXES = ['xoxo']
+        dirs = site.getsitepackages()
+
+        if sys.platform in ('os2emx', 'riscos'):
+            self.assertTrue(len(dirs), 1)
+            wanted = os.path.join('xoxo', 'Lib', 'site-packages')
+            self.assertEquals(dirs[0], wanted)
+        elif os.sep == '/':
+            self.assertTrue(len(dirs), 2)
+            wanted = os.path.join('xoxo', 'lib', 'python' + sys.version[:3],
+                                  'site-packages')
+            self.assertEquals(dirs[0], wanted)
+            wanted = os.path.join('xoxo', 'lib', 'site-python')
+            self.assertEquals(dirs[1], wanted)
+        else:
+            self.assertTrue(len(dirs), 2)
+            self.assertEquals(dirs[0], 'xoxo')
+            wanted = os.path.join('xoxo', 'Lib', 'site-packages')
+            self.assertEquals(dirs[1], wanted)
+
+        # let's try the specific Apple location
+        if sys.platform == "darwin":
+            site.PREFIXES = ['Python.framework']
+            dirs = site.getsitepackages()
+            self.assertTrue(len(dirs), 4)
+            wanted = os.path.join('~', 'Library', 'Python',
+                                  sys.version[:3], 'site-packages')
+            self.assertEquals(dirs[2], os.path.expanduser(wanted))
+            wanted = os.path.join('/Library', 'Python', sys.version[:3],
+                                  'site-packages')
+            self.assertEquals(dirs[3], wanted)
 
 class PthFile(object):
     """Helper class for handling testing of .pth files"""

Modified: python/branches/tk_and_idle_maintenance/Misc/ACKS
==============================================================================
--- python/branches/tk_and_idle_maintenance/Misc/ACKS	(original)
+++ python/branches/tk_and_idle_maintenance/Misc/ACKS	Sat Aug 22 17:20:52 2009
@@ -794,6 +794,7 @@
 Dik Winter
 Blake Winton
 Jean-Claude Wippler
+Frank Wierzbicki
 Lars Wirzenius
 Chris Withers
 Stefan Witzel

Modified: python/branches/tk_and_idle_maintenance/Misc/NEWS
==============================================================================
--- python/branches/tk_and_idle_maintenance/Misc/NEWS	(original)
+++ python/branches/tk_and_idle_maintenance/Misc/NEWS	Sat Aug 22 17:20:52 2009
@@ -12,6 +12,11 @@
 Core and Builtins
 -----------------
 
+- Issue #6704: Improve the col_offset in AST for "for" statements with
+  a target of tuple unpacking.
+
+- Issue #6707: dir() on an uninitialized module caused a crash.
+
 - Issue #6540: Fixed crash for bytearray.translate() with invalid parameters.
 
 - Issue #6573: set.union() stopped processing inputs if an instance of self
@@ -354,6 +359,24 @@
 Library
 -------
 
+- Issue #6693: New functions in site.py to get user/global site packages paths.
+
+- The thread.lock type now supports weak references.
+
+- Issue #1356969: Add missing info methods in Tix.HList.
+
+- Issue #1522587: New constants and methods for the Tix.Grid widget.
+
+- Issue #1250469: Fix the return value of Tix.PanedWindow.panes.
+
+- Issue #1119673: Do not override Tkinter.Text methods when creating a
+  ScrolledText.
+
+- Issue #6665: Fix fnmatch to properly match filenames with newlines in them.
+
+- Issue #1135: Add the XView and YView mix-ins to avoid duplicating
+  the xview* and yview* methods.
+
 - Issue #6629: Fix a data corruption issue in the new `io` package, which could
   occur when writing to a BufferedRandom object (e.g. a file opened in "rb+" or
   "wb+" mode) after having buffered a certain amount of data for reading. This
@@ -1145,6 +1168,8 @@
 Build
 -----
 
+- Issue #6244: Allow detect_tkinter to look for Tcl/Tk 8.6.
+
 - Issue 5390: Add uninstall icon independent of whether file
   extensions are installed.
 
@@ -1193,11 +1218,17 @@
 
 - Issue #4204: Fixed module build errors on FreeBSD 4.
 
+Documentation
+-------------
+
+- Issue #6556: Fixed the Distutils configuration files location explanation
+  for Windows.
+
 C-API
 -----
 
-- Issue #6624: yArg_ParseTuple with "s" format when parsing argument with 
-  NUL: Bogus TypeError detail string.
+- Issue #6624: PyArg_ParseTuple with "s" format when parsing argument with 
+  NULL: Bogus TypeError detail string.
 
 - Issue #5954: Add a PyFrame_GetLineNumber() function to replace most uses of
   PyCode_Addr2Line().

Modified: python/branches/tk_and_idle_maintenance/Modules/threadmodule.c
==============================================================================
--- python/branches/tk_and_idle_maintenance/Modules/threadmodule.c	(original)
+++ python/branches/tk_and_idle_maintenance/Modules/threadmodule.c	Sat Aug 22 17:20:52 2009
@@ -3,6 +3,7 @@
 /* Interface to Sjoerd's portable C thread library */
 
 #include "Python.h"
+#include "structmember.h" /* offsetof */
 
 #ifndef WITH_THREAD
 #error "Error!  The rest of Python is not compiled with thread support."
@@ -20,12 +21,15 @@
 typedef struct {
 	PyObject_HEAD
 	PyThread_type_lock lock_lock;
+	PyObject *in_weakreflist;
 } lockobject;
 
 static void
 lock_dealloc(lockobject *self)
 {
 	assert(self->lock_lock);
+	if (self->in_weakreflist != NULL)
+		PyObject_ClearWeakRefs((PyObject *) self);
 	/* Unlock the lock so it's safe to free it */
 	PyThread_acquire_lock(self->lock_lock, 0);
 	PyThread_release_lock(self->lock_lock);
@@ -140,12 +144,12 @@
 	0,		                /* tp_getattro */
 	0,		                /* tp_setattro */
 	0,				/* tp_as_buffer */
-	0,	                        /* tp_flags */
+	Py_TPFLAGS_HAVE_WEAKREFS,       /* tp_flags */
 	0,				/* tp_doc */
 	0,		                /* tp_traverse */
 	0,			        /* tp_clear */
 	0,				/* tp_richcompare */
-	0,	                        /* tp_weaklistoffset */
+	offsetof(lockobject, in_weakreflist),	/* tp_weaklistoffset */
 	0,				/* tp_iter */
 	0,				/* tp_iternext */
 	lock_methods,			/* tp_methods */
@@ -159,6 +163,7 @@
 	if (self == NULL)
 		return NULL;
 	self->lock_lock = PyThread_allocate_lock();
+	self->in_weakreflist = NULL;
 	if (self->lock_lock == NULL) {
 		PyObject_Del(self);
 		self = NULL;

Modified: python/branches/tk_and_idle_maintenance/Objects/object.c
==============================================================================
--- python/branches/tk_and_idle_maintenance/Objects/object.c	(original)
+++ python/branches/tk_and_idle_maintenance/Objects/object.c	Sat Aug 22 17:20:52 2009
@@ -1810,9 +1810,11 @@
 		if (PyDict_Check(dict))
 			result = PyDict_Keys(dict);
 		else {
-			PyErr_Format(PyExc_TypeError,
-				     "%.200s.__dict__ is not a dictionary",
-				     PyModule_GetName(obj));
+			char *name = PyModule_GetName(obj);
+			if (name)
+				PyErr_Format(PyExc_TypeError,
+					     "%.200s.__dict__ is not a dictionary",
+					     name);
 		}
 	}
 

Modified: python/branches/tk_and_idle_maintenance/Python/ast.c
==============================================================================
--- python/branches/tk_and_idle_maintenance/Python/ast.c	(original)
+++ python/branches/tk_and_idle_maintenance/Python/ast.c	Sat Aug 22 17:20:52 2009
@@ -1047,7 +1047,7 @@
        list_if: 'if' test [list_iter]
        testlist_safe: test [(',' test)+ [',']]
     */
-    expr_ty elt;
+    expr_ty elt, first;
     asdl_seq *listcomps;
     int i, n_fors;
     node *ch;
@@ -1087,11 +1087,11 @@
         /* Check the # of children rather than the length of t, since
            [x for x, in ... ] has 1 element in t, but still requires a Tuple.
         */
+        first = (expr_ty)asdl_seq_GET(t, 0);
         if (NCH(for_ch) == 1)
-            lc = comprehension((expr_ty)asdl_seq_GET(t, 0), expression, NULL,
-                               c->c_arena);
+            lc = comprehension(first, expression, NULL, c->c_arena);
         else
-            lc = comprehension(Tuple(t, Store, LINENO(ch), ch->n_col_offset,
+            lc = comprehension(Tuple(t, Store, first->lineno, first->col_offset,
                                      c->c_arena),
                                expression, NULL, c->c_arena);
         if (!lc)
@@ -1226,7 +1226,7 @@
     for (i = 0; i < n_fors; i++) {
         comprehension_ty ge;
         asdl_seq *t;
-        expr_ty expression;
+        expr_ty expression, first;
         node *for_ch;
         
         REQ(ch, gen_for);
@@ -1241,11 +1241,11 @@
 
         /* Check the # of children rather than the length of t, since
            (x for x, in ...) has 1 element in t, but still requires a Tuple. */
+        first = (expr_ty)asdl_seq_GET(t, 0);
         if (NCH(for_ch) == 1)
-            ge = comprehension((expr_ty)asdl_seq_GET(t, 0), expression,
-                               NULL, c->c_arena);
+            ge = comprehension(first, expression, NULL, c->c_arena);
         else
-            ge = comprehension(Tuple(t, Store, LINENO(ch), ch->n_col_offset,
+            ge = comprehension(Tuple(t, Store, first->lineno, first->col_offset,
                                      c->c_arena),
                                expression, NULL, c->c_arena);
 
@@ -2844,7 +2844,7 @@
 {
     asdl_seq *_target, *seq = NULL, *suite_seq;
     expr_ty expression;
-    expr_ty target;
+    expr_ty target, first;
     const node *node_target;
     /* for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite] */
     REQ(n, for_stmt);
@@ -2861,10 +2861,11 @@
         return NULL;
     /* Check the # of children rather than the length of _target, since
        for x, in ... has 1 element in _target, but still requires a Tuple. */
+    first = (expr_ty)asdl_seq_GET(_target, 0);
     if (NCH(node_target) == 1)
-        target = (expr_ty)asdl_seq_GET(_target, 0);
+        target = first;
     else
-        target = Tuple(_target, Store, LINENO(n), n->n_col_offset, c->c_arena);
+        target = Tuple(_target, Store, first->lineno, first->col_offset, c->c_arena);
 
     expression = ast_for_testlist(c, CHILD(n, 3));
     if (!expression)

Modified: python/branches/tk_and_idle_maintenance/setup.py
==============================================================================
--- python/branches/tk_and_idle_maintenance/setup.py	(original)
+++ python/branches/tk_and_idle_maintenance/setup.py	Sat Aug 22 17:20:52 2009
@@ -1539,8 +1539,8 @@
         # The versions with dots are used on Unix, and the versions without
         # dots on Windows, for detection by cygwin.
         tcllib = tklib = tcl_includes = tk_includes = None
-        for version in ['8.5', '85', '8.4', '84', '8.3', '83', '8.2',
-                        '82', '8.1', '81', '8.0', '80']:
+        for version in ['8.6', '86', '8.5', '85', '8.4', '84', '8.3', '83',
+                        '8.2', '82', '8.1', '81', '8.0', '80']:
             tklib = self.compiler_obj.find_library_file(lib_dirs,
                                                         'tk' + version)
             tcllib = self.compiler_obj.find_library_file(lib_dirs,


More information about the Python-checkins mailing list