[Python-checkins] r62821 - in python/branches/tlee-ast-optimize: .bzrignore Doc/bugs.rst Doc/library/json.rst Doc/library/netdata.rst Doc/library/site.rst Doc/library/socket.rst Doc/library/stdtypes.rst Doc/library/undoc.rst Doc/library/warnings.rst Doc/using/cmdline.rst Doc/whatsnew/2.6.rst Include/pydebug.h Lib/audiodev.py Lib/distutils/command/install.py Lib/io.py Lib/json Lib/json/tests Lib/os.py Lib/site.py Lib/socket.py Lib/test/test___all__.py Lib/test/test_json.py Lib/test/test_py3kwarn.py Lib/test/test_site.py Lib/test/test_socket.py Lib/test/test_subprocess.py Lib/test/test_warnings.py Lib/test/test_zipfile.py Lib/urllib2.py Lib/warnings.py Lib/zipfile.py Misc/NEWS Misc/TextMate Modules/_json.c Modules/main.c PC/VC6/pythoncore.dsp PC/VS7.1/pythoncore.vcproj PC/VS8.0/pythoncore.vcproj PC/config.c PCbuild/pythoncore.vcproj Python/_warnings.c Python/pythonrun.c Python/sysmodule.c setup.py

thomas.lee python-checkins at python.org
Wed May 7 14:56:57 CEST 2008


Author: thomas.lee
Date: Wed May  7 14:56:55 2008
New Revision: 62821

Log:
Merged revisions 62707-62820 via svnmerge from 
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r62711 | benjamin.peterson | 2008-05-05 05:10:02 +1000 (Mon, 05 May 2008) | 2 lines
  
  Fix typo in bugs.rst
........
  r62713 | georg.brandl | 2008-05-05 07:40:44 +1000 (Mon, 05 May 2008) | 2 lines
  
  #2695: Do case-insensitive check for algorithms.
........
  r62715 | benjamin.peterson | 2008-05-05 08:39:33 +1000 (Mon, 05 May 2008) | 2 lines
  
  Remove method signatures from the docstrings of io.py
........
  r62720 | brett.cannon | 2008-05-05 15:32:07 +1000 (Mon, 05 May 2008) | 3 lines
  
  Add a DeprecationWarning for when warnings.showwarning() is set to a function
  that lacks support for the new 'line' argument.
........
  r62722 | brett.cannon | 2008-05-06 02:57:38 +1000 (Tue, 06 May 2008) | 4 lines
  
  Remove the use of 'inspect' from 'warnings' for detected deprecated use of the
  showwarning API. Turns out 'inspect' uses 'operator' which is an extension
  module. That's a problem when it has not been built yet by setup.py.
........
  r62724 | martin.v.loewis | 2008-05-06 03:16:58 +1000 (Tue, 06 May 2008) | 2 lines
  
  Issue #1734346: Support Unicode file names for zipfiles.
........
  r62726 | martin.v.loewis | 2008-05-06 03:47:06 +1000 (Tue, 06 May 2008) | 2 lines
  
  Fix Unicode filename test.
........
  r62728 | martin.v.loewis | 2008-05-06 03:54:01 +1000 (Tue, 06 May 2008) | 2 lines
  
  Revert bogus checkin in r62724 to that file.
........
  r62734 | brett.cannon | 2008-05-06 06:21:38 +1000 (Tue, 06 May 2008) | 5 lines
  
  Add the 'json' package. Code taken from simplejson 1.9 and contributed by Bob
  Ippolito.
  
  Closes issue #2750.
........
  r62736 | georg.brandl | 2008-05-06 06:53:39 +1000 (Tue, 06 May 2008) | 2 lines
  
  Fix JSON module docs.
........
  r62737 | georg.brandl | 2008-05-06 06:59:05 +1000 (Tue, 06 May 2008) | 2 lines
  
  #2769: markup glitch.
........
  r62740 | georg.brandl | 2008-05-06 07:06:48 +1000 (Tue, 06 May 2008) | 2 lines
  
  #2752: fix second example too.
........
  r62744 | gregory.p.smith | 2008-05-06 07:53:45 +1000 (Tue, 06 May 2008) | 13 lines
  
  Fix a bug introduced in r62627.  see issue2760 and issue2632.
  
  An assertion in readline() would fail as data was already in the
  internal buffer even though the socket was in unbuffered read mode.
  That case is now handled.  More importantly, read() has been fixed to
  not over-recv() and leave newly recv()d data in the _fileobject buffer.
  
  The max() vs min() issue in read() is now gone.  Neither was correct.
  On bounded reads, always ask recv() for the exact amount of data we
  still need.
  
  Candidate for backporting to release25-maint along with r62627.
........
  r62748 | benjamin.peterson | 2008-05-06 12:51:10 +1000 (Tue, 06 May 2008) | 2 lines
  
  PEP 8 nits in json package
........
  r62749 | brett.cannon | 2008-05-06 14:37:31 +1000 (Tue, 06 May 2008) | 3 lines
  
  Fix a bug in the handling of the stacklevel argument in warnings.warn() where
  the stack was being unwound by two levels instead of one each time.
........
  r62756 | gregory.p.smith | 2008-05-06 17:05:18 +1000 (Tue, 06 May 2008) | 2 lines
  
  fix issue2707 - os.walk docstring example correctness typo.
........
  r62769 | christian.heimes | 2008-05-07 02:18:41 +1000 (Wed, 07 May 2008) | 2 lines
  
  Intern static string
  Use float constructors instead of magic code for float constants
........
  r62774 | georg.brandl | 2008-05-07 03:11:42 +1000 (Wed, 07 May 2008) | 2 lines
  
  #2773: fix description of 'g' and 'G' formatting spec.
........
  r62775 | georg.brandl | 2008-05-07 03:20:54 +1000 (Wed, 07 May 2008) | 2 lines
  
  > != (!<).
........
  r62785 | benjamin.peterson | 2008-05-07 08:18:11 +1000 (Wed, 07 May 2008) | 2 lines
  
  Fix logic error in Python/_warnings.c and add a test to verify
........
  r62787 | benjamin.peterson | 2008-05-07 08:31:52 +1000 (Wed, 07 May 2008) | 2 lines
  
  Make the Python implementation of warnings compatible with the C implementation regarding non-callable showwarning
........
  r62788 | christian.heimes | 2008-05-07 08:41:46 +1000 (Wed, 07 May 2008) | 1 line
  
  Implemented PEP 370
........
  r62792 | brett.cannon | 2008-05-07 09:22:02 +1000 (Wed, 07 May 2008) | 2 lines
  
  When testing a module's __all__, we really don't care if it is deprecated.
........
  r62793 | brett.cannon | 2008-05-07 09:23:34 +1000 (Wed, 07 May 2008) | 2 lines
  
  Deprecate the audiodev module for 3.0.
........
  r62797 | brett.cannon | 2008-05-07 09:41:32 +1000 (Wed, 07 May 2008) | 2 lines
  
  Add an entry about audiodev being slated for removal in 3.0.
........
  r62799 | christian.heimes | 2008-05-07 09:42:58 +1000 (Wed, 07 May 2008) | 1 line
  
  Disabled some unit tests for the upcoming release. See #2777
........
  r62800 | brett.cannon | 2008-05-07 09:44:04 +1000 (Wed, 07 May 2008) | 2 lines
  
  Create a TextMate directory in Misc to house a Python-Dev bundle.
........
  r62805 | christian.heimes | 2008-05-07 09:59:53 +1000 (Wed, 07 May 2008) | 1 line
  
  Re-added getbuildinfo.c solution item
........
  r62811 | benjamin.peterson | 2008-05-07 12:23:43 +1000 (Wed, 07 May 2008) | 2 lines
  
  update .bzrignore
........


Added:
   python/branches/tlee-ast-optimize/Doc/library/json.rst
      - copied unchanged from r62811, /python/trunk/Doc/library/json.rst
   python/branches/tlee-ast-optimize/Lib/json/   (props changed)
      - copied from r62811, /python/trunk/Lib/json/
   python/branches/tlee-ast-optimize/Lib/test/test_json.py
      - copied unchanged from r62811, /python/trunk/Lib/test/test_json.py
   python/branches/tlee-ast-optimize/Misc/TextMate/
      - copied from r62811, /python/trunk/Misc/TextMate/
   python/branches/tlee-ast-optimize/Modules/_json.c
      - copied unchanged from r62811, /python/trunk/Modules/_json.c
Modified:
   python/branches/tlee-ast-optimize/   (props changed)
   python/branches/tlee-ast-optimize/.bzrignore
   python/branches/tlee-ast-optimize/Doc/bugs.rst
   python/branches/tlee-ast-optimize/Doc/library/netdata.rst
   python/branches/tlee-ast-optimize/Doc/library/site.rst
   python/branches/tlee-ast-optimize/Doc/library/socket.rst
   python/branches/tlee-ast-optimize/Doc/library/stdtypes.rst
   python/branches/tlee-ast-optimize/Doc/library/undoc.rst
   python/branches/tlee-ast-optimize/Doc/library/warnings.rst
   python/branches/tlee-ast-optimize/Doc/using/cmdline.rst
   python/branches/tlee-ast-optimize/Doc/whatsnew/2.6.rst
   python/branches/tlee-ast-optimize/Include/pydebug.h
   python/branches/tlee-ast-optimize/Lib/audiodev.py
   python/branches/tlee-ast-optimize/Lib/distutils/command/install.py
   python/branches/tlee-ast-optimize/Lib/io.py
   python/branches/tlee-ast-optimize/Lib/json/tests/   (props changed)
   python/branches/tlee-ast-optimize/Lib/os.py
   python/branches/tlee-ast-optimize/Lib/site.py
   python/branches/tlee-ast-optimize/Lib/socket.py
   python/branches/tlee-ast-optimize/Lib/test/test___all__.py
   python/branches/tlee-ast-optimize/Lib/test/test_py3kwarn.py
   python/branches/tlee-ast-optimize/Lib/test/test_site.py
   python/branches/tlee-ast-optimize/Lib/test/test_socket.py
   python/branches/tlee-ast-optimize/Lib/test/test_subprocess.py
   python/branches/tlee-ast-optimize/Lib/test/test_warnings.py
   python/branches/tlee-ast-optimize/Lib/test/test_zipfile.py
   python/branches/tlee-ast-optimize/Lib/urllib2.py
   python/branches/tlee-ast-optimize/Lib/warnings.py
   python/branches/tlee-ast-optimize/Lib/zipfile.py
   python/branches/tlee-ast-optimize/Misc/NEWS
   python/branches/tlee-ast-optimize/Modules/main.c
   python/branches/tlee-ast-optimize/PC/VC6/pythoncore.dsp
   python/branches/tlee-ast-optimize/PC/VS7.1/pythoncore.vcproj
   python/branches/tlee-ast-optimize/PC/VS8.0/pythoncore.vcproj
   python/branches/tlee-ast-optimize/PC/config.c
   python/branches/tlee-ast-optimize/PCbuild/pythoncore.vcproj
   python/branches/tlee-ast-optimize/Python/_warnings.c
   python/branches/tlee-ast-optimize/Python/pythonrun.c
   python/branches/tlee-ast-optimize/Python/sysmodule.c
   python/branches/tlee-ast-optimize/setup.py

Modified: python/branches/tlee-ast-optimize/.bzrignore
==============================================================================
--- python/branches/tlee-ast-optimize/.bzrignore	(original)
+++ python/branches/tlee-ast-optimize/.bzrignore	Wed May  7 14:56:55 2008
@@ -1,4 +1,4 @@
-.purify
+´.purify
 autom4te.cache
 config.log
 config.cache
@@ -41,3 +41,7 @@
 Modules/config.c
 Parser/pgen
 Lib/plat-mac/errors.rsrc.df.rsrc
+Lib/lib2to3/Grammar2.6.0.alpha.1.pickle
+Lib/lib2to3/Grammar2.6.0.alpha.2.pickle
+Lib/lib2to3/PatternGrammar2.6.0.alpha.1.pickle
+Lib/lib2to3/PatternGrammar2.6.0.alpha.2.pickle

Modified: python/branches/tlee-ast-optimize/Doc/bugs.rst
==============================================================================
--- python/branches/tlee-ast-optimize/Doc/bugs.rst	(original)
+++ python/branches/tlee-ast-optimize/Doc/bugs.rst	Wed May  7 14:56:55 2008
@@ -37,7 +37,7 @@
 "Type" field, select the type of your problem; also select the "Component" and
 "Versions" to which the bug relates.
 
-In the "Change Note" field, describe the problem in detail, including what you
+In the "Comment" field, describe the problem in detail, including what you
 expected to happen and what did happen.  Be sure to include whether any
 extension modules were involved, and what hardware and software platform you
 were using (including version information as appropriate).

Modified: python/branches/tlee-ast-optimize/Doc/library/netdata.rst
==============================================================================
--- python/branches/tlee-ast-optimize/Doc/library/netdata.rst	(original)
+++ python/branches/tlee-ast-optimize/Doc/library/netdata.rst	Wed May  7 14:56:55 2008
@@ -12,6 +12,7 @@
 .. toctree::
 
    email.rst
+   json.rst
    mailcap.rst
    mailbox.rst
    mhlib.rst

Modified: python/branches/tlee-ast-optimize/Doc/library/site.rst
==============================================================================
--- python/branches/tlee-ast-optimize/Doc/library/site.rst	(original)
+++ python/branches/tlee-ast-optimize/Doc/library/site.rst	Wed May  7 14:56:55 2008
@@ -85,3 +85,51 @@
 empty, and the path manipulations are skipped; however the import of
 :mod:`sitecustomize` is still attempted.
 
+
+.. data:: PREFIXES
+
+   A list of prefixes for site package directories
+
+   .. versionadded:: 2.6
+
+
+.. data:: ENABLE_USER_SITE
+
+   Flag showing the status of the user site directory. True means the
+   user site directory is enabled and added to sys.path. When the flag
+   is None the user site directory is disabled for security reasons.
+
+   .. versionadded:: 2.6
+
+
+.. data:: USER_SITE
+
+   Path to the user site directory for the current Python version or None
+
+   .. versionadded:: 2.6
+
+
+.. data:: USER_BASE
+
+   Path to the base directory for user site directories
+
+   .. versionadded:: 2.6
+
+
+.. envvar:: PYTHONNOUSERSITE
+
+   .. versionadded:: 2.6
+
+
+.. envvar:: PYTHONUSERBASE
+
+   .. versionadded:: 2.6
+
+
+.. function:: addsitedir(sitedir, known_paths=None)
+
+   Adds a directory to sys.path and processes its pth files.
+
+
+XXX Update documentation
+XXX document python -m site --user-base --user-site

Modified: python/branches/tlee-ast-optimize/Doc/library/socket.rst
==============================================================================
--- python/branches/tlee-ast-optimize/Doc/library/socket.rst	(original)
+++ python/branches/tlee-ast-optimize/Doc/library/socket.rst	Wed May  7 14:56:55 2008
@@ -846,7 +846,7 @@
    import socket
    import sys
 
-   HOST = ''                 # Symbolic name meaning the local host
+   HOST = ''                 # Symbolic name meaning all available interfaces
    PORT = 50007              # Arbitrary non-privileged port
    s = None
    for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC, socket.SOCK_STREAM, 0, socket.AI_PASSIVE):

Modified: python/branches/tlee-ast-optimize/Doc/library/stdtypes.rst
==============================================================================
--- python/branches/tlee-ast-optimize/Doc/library/stdtypes.rst	(original)
+++ python/branches/tlee-ast-optimize/Doc/library/stdtypes.rst	Wed May  7 14:56:55 2008
@@ -1212,13 +1212,13 @@
 +------------+-----------------------------------------------------+-------+
 | ``'F'``    | Floating point decimal format.                      | \(3)  |
 +------------+-----------------------------------------------------+-------+
-| ``'g'``    | Floating point format. Uses exponential format if   | \(4)  |
-|            | exponent is greater than -4 or less than precision, |       |
-|            | decimal format otherwise.                           |       |
+| ``'g'``    | Floating point format. Uses lowercase exponential   | \(4)  |
+|            | format if exponent is less than -4 or not less than |       |
+|            | precision, decimal format otherwise.                |       |
 +------------+-----------------------------------------------------+-------+
-| ``'G'``    | Floating point format. Uses exponential format if   | \(4)  |
-|            | exponent is greater than -4 or less than precision, |       |
-|            | decimal format otherwise.                           |       |
+| ``'G'``    | Floating point format. Uses uppercase exponential   | \(4)  |
+|            | format if exponent is less than -4 or not less than |       |
+|            | precision, decimal format otherwise.                |       |
 +------------+-----------------------------------------------------+-------+
 | ``'c'``    | Single character (accepts integer or single         |       |
 |            | character string).                                  |       |

Modified: python/branches/tlee-ast-optimize/Doc/library/undoc.rst
==============================================================================
--- python/branches/tlee-ast-optimize/Doc/library/undoc.rst	(original)
+++ python/branches/tlee-ast-optimize/Doc/library/undoc.rst	Wed May  7 14:56:55 2008
@@ -47,6 +47,8 @@
 :mod:`audiodev`
    --- Platform-independent API for playing audio data.
 
+   .. warning:: The :mod:`audiodev` module has been removed in 3.0.
+
 :mod:`linuxaudiodev`
    --- Play audio data on the Linux audio device.  Replaced in Python 2.3 by the
    :mod:`ossaudiodev` module.

Modified: python/branches/tlee-ast-optimize/Doc/library/warnings.rst
==============================================================================
--- python/branches/tlee-ast-optimize/Doc/library/warnings.rst	(original)
+++ python/branches/tlee-ast-optimize/Doc/library/warnings.rst	Wed May  7 14:56:55 2008
@@ -220,7 +220,8 @@
    ``warnings.showwarning``.
 
    .. versionchanged:: 2.6
-      Added the *line* argument.
+      Added the *line* argument. Implementations that lack the new argument
+      will trigger a :exc:`DeprecationWarning`.
 
 
 .. function:: formatwarning(message, category, filename, lineno[, line])

Modified: python/branches/tlee-ast-optimize/Doc/using/cmdline.rst
==============================================================================
--- python/branches/tlee-ast-optimize/Doc/using/cmdline.rst	(original)
+++ python/branches/tlee-ast-optimize/Doc/using/cmdline.rst	Wed May  7 14:56:55 2008
@@ -21,7 +21,7 @@
 
 When invoking Python, you may specify any of these options::
 
-    python [-dEiOQStuUvxX3?] [-c command | -m module-name | script | - ] [args]
+    python [-dEiOQsStuUvxX3?] [-c command | -m module-name | script | - ] [args]
 
 The most common use case is, of course, a simple invocation of a script::
 
@@ -240,6 +240,17 @@
       :pep:`238` -- Changing the division operator
 
 
+.. cmdoption:: -s
+
+   Don't add user site directory to sys.path
+
+   .. versionadded:: 2.6
+
+   .. seealso::
+
+      :pep:`370` -- Per user site-packages directory
+
+
 .. cmdoption:: -S
 
    Disable the import of the module :mod:`site` and the site-dependent
@@ -471,6 +482,28 @@
    .. versionadded:: 2.6
 
 
+.. envvar:: PYTHONNOUSERSITE
+
+   If this is set, Python won't add the user site directory to sys.path
+
+   .. versionadded:: 2.6
+
+   .. seealso::
+
+      :pep:`370` -- Per user site-packages directory
+
+
+.. envvar:: PYTHONUSERBASE
+
+   Sets the base directory for the user site directory
+
+   .. versionadded:: 2.6
+
+   .. seealso::
+
+      :pep:`370` -- Per user site-packages directory
+
+
 .. envvar:: PYTHONEXECUTABLE
 
    If this environment variable is set, ``sys.argv[0]`` will be set to its

Modified: python/branches/tlee-ast-optimize/Doc/whatsnew/2.6.rst
==============================================================================
--- python/branches/tlee-ast-optimize/Doc/whatsnew/2.6.rst	(original)
+++ python/branches/tlee-ast-optimize/Doc/whatsnew/2.6.rst	Wed May  7 14:56:55 2008
@@ -1210,6 +1210,7 @@
 long time.  This implementation was significantly updated by Jeffrey
 Yasskin.
 
+
 Other Language Changes
 ======================
 
@@ -1692,7 +1693,7 @@
 
   ``permutations(iter[, r])`` returns all the permutations of length *r* of
   the iterable's elements.  If *r* is not specified, it will default to the 
-  number of elements produced by the iterable.
+  number of elements produced by the iterable. ::
 
     itertools.permutations([1,2,3,4], 2) ->
       [(1, 2), (1, 3), (1, 4), 
@@ -2146,6 +2147,31 @@
 .. ======================================================================
 .. whole new modules get described in subsections here
 
+The :mod:`json` module
+----------------------
+
+The new :mod:`json` module supports the encoding and decoding of Python types in
+JSON (Javascript Object Notation). JSON is a lightweight interchange format
+often used in web applications. For more information about JSON, see
+http://www.json.org.
+
+:mod:`json` comes with support for decoding and encoding most builtin Python
+types. The following example encodes and decodes a dictionary::
+
+       >>> import json
+       >>> data = {"spam" : "foo", "parrot" : 42}
+       >>> in_json = json.dumps(data) # Encode the data
+       >>> in_json
+       '{"parrot": 42, "spam": "foo"}'
+       >>> json.loads(in_json) # Decode into a Python object
+       {"spam" : "foo", "parrot" : 42}
+
+It is also possible to write your own decoders and encoders to support more
+types. Pretty-printing of the JSON strings is also supported.
+
+:mod:`json` (originally called simplejson) was written by Bob Ippolito.
+
+
 Improved SSL Support
 --------------------------------------------------
 

Modified: python/branches/tlee-ast-optimize/Include/pydebug.h
==============================================================================
--- python/branches/tlee-ast-optimize/Include/pydebug.h	(original)
+++ python/branches/tlee-ast-optimize/Include/pydebug.h	Wed May  7 14:56:55 2008
@@ -19,6 +19,7 @@
 PyAPI_DATA(int) Py_IgnoreEnvironmentFlag;
 PyAPI_DATA(int) Py_DivisionWarningFlag;
 PyAPI_DATA(int) Py_DontWriteBytecodeFlag;
+PyAPI_DATA(int) Py_NoUserSiteDirectory;
 /* _XXX Py_QnewFlag should go away in 3.0.  It's true iff -Qnew is passed,
   on the command line, and is used in 2.2 by ceval.c to make all "/" divisions
   true divisions (which they will be in 3.0). */

Modified: python/branches/tlee-ast-optimize/Lib/audiodev.py
==============================================================================
--- python/branches/tlee-ast-optimize/Lib/audiodev.py	(original)
+++ python/branches/tlee-ast-optimize/Lib/audiodev.py	Wed May  7 14:56:55 2008
@@ -1,4 +1,7 @@
 """Classes for manipulating audio devices (currently only for Sun and SGI)"""
+from warnings import warnpy3k
+warnpy3k("the audiodev module has been removed in Python 3.0", stacklevel=2)
+del warnpy3k
 
 __all__ = ["error","AudioDev"]
 

Modified: python/branches/tlee-ast-optimize/Lib/distutils/command/install.py
==============================================================================
--- python/branches/tlee-ast-optimize/Lib/distutils/command/install.py	(original)
+++ python/branches/tlee-ast-optimize/Lib/distutils/command/install.py	Wed May  7 14:56:55 2008
@@ -18,6 +18,9 @@
 from distutils.util import convert_path, subst_vars, change_root
 from distutils.util import get_platform
 from distutils.errors import DistutilsOptionError
+from site import USER_BASE
+from site import USER_SITE
+
 
 if sys.version < "2.2":
     WINDOWS_SCHEME = {
@@ -51,7 +54,21 @@
         'scripts': '$base/bin',
         'data'   : '$base',
         },
+    'unix_user': {
+        'purelib': '$usersite',
+        'platlib': '$usersite',
+        'headers': '$userbase/include/python$py_version_short/$dist_name',
+        'scripts': '$userbase/bin',
+        'data'   : '$userbase',
+        },
     'nt': WINDOWS_SCHEME,
+    'nt_user': {
+        'purelib': '$usersite',
+        'platlib': '$usersite',
+        'headers': '$userbase/Python$py_version_nodot/Include/$dist_name',
+        'scripts': '$userbase/Scripts',
+        'data'   : '$userbase',
+        },
     'mac': {
         'purelib': '$base/Lib/site-packages',
         'platlib': '$base/Lib/site-packages',
@@ -59,13 +76,27 @@
         'scripts': '$base/Scripts',
         'data'   : '$base',
         },
+    'mac_user': {
+        'purelib': '$usersite',
+        'platlib': '$usersite',
+        'headers': '$userbase/$py_version_short/include/$dist_name',
+        'scripts': '$userbase/bin',
+        'data'   : '$userbase',
+        },
     'os2': {
         'purelib': '$base/Lib/site-packages',
         'platlib': '$base/Lib/site-packages',
         'headers': '$base/Include/$dist_name',
         'scripts': '$base/Scripts',
         'data'   : '$base',
-        }
+        },
+    'os2_home': {
+        'purelib': '$usersite',
+        'platlib': '$usersite',
+        'headers': '$userbase/include/python$py_version_short/$dist_name',
+        'scripts': '$userbase/bin',
+        'data'   : '$userbase',
+        },
     }
 
 # The keys to an installation scheme; if any new types of files are to be
@@ -86,6 +117,8 @@
          "(Unix only) prefix for platform-specific files"),
         ('home=', None,
          "(Unix only) home directory to install under"),
+        ('user', None,
+         "install in user site-package '%s'" % USER_SITE),
 
         # Or, just set the base director(y|ies)
         ('install-base=', None,
@@ -137,7 +170,7 @@
          "filename in which to record list of installed files"),
         ]
 
-    boolean_options = ['compile', 'force', 'skip-build']
+    boolean_options = ['compile', 'force', 'skip-build', 'user']
     negative_opt = {'no-compile' : 'compile'}
 
 
@@ -148,6 +181,7 @@
         self.prefix = None
         self.exec_prefix = None
         self.home = None
+        self.user = 0
 
         # These select only the installation base; it's up to the user to
         # specify the installation scheme (currently, that means supplying
@@ -166,6 +200,8 @@
         self.install_lib = None         # set to either purelib or platlib
         self.install_scripts = None
         self.install_data = None
+        self.install_userbase = USER_BASE
+        self.install_usersite = USER_SITE
 
         self.compile = None
         self.optimize = None
@@ -241,6 +277,11 @@
             raise DistutilsOptionError, \
                   "must supply either home or prefix/exec-prefix -- not both"
 
+        if self.user and (self.prefix or self.exec_prefix or self.home or
+                self.install_base or self.install_platbase):
+            raise DistutilsOptionError("can't combine user with with prefix/"
+                                       "exec_prefix/home or install_(plat)base")
+
         # Next, stuff that's wrong (or dubious) only on certain platforms.
         if os.name != "posix":
             if self.exec_prefix:
@@ -276,10 +317,13 @@
                             'dist_fullname': self.distribution.get_fullname(),
                             'py_version': py_version,
                             'py_version_short': py_version[0:3],
+                            'py_version_nodot': py_version[0] + py_version[2],
                             'sys_prefix': prefix,
                             'prefix': prefix,
                             'sys_exec_prefix': exec_prefix,
                             'exec_prefix': exec_prefix,
+                            'userbase': self.install_userbase,
+                            'usersite': self.install_usersite,
                            }
         self.expand_basedirs()
 
@@ -301,6 +345,10 @@
 
         self.dump_dirs("post-expand_dirs()")
 
+        # Create directories in the home dir:
+        if self.user:
+            self.create_home_path()
+
         # Pick the actual directory to install all modules to: either
         # install_purelib or install_platlib, depending on whether this
         # module distribution is pure or not.  Of course, if the user
@@ -315,7 +363,8 @@
         # Convert directories from Unix /-separated syntax to the local
         # convention.
         self.convert_paths('lib', 'purelib', 'platlib',
-                           'scripts', 'data', 'headers')
+                           'scripts', 'data', 'headers',
+                           'userbase', 'usersite')
 
         # Well, we're not actually fully completely finalized yet: we still
         # have to deal with 'extra_path', which is the hack for allowing
@@ -376,7 +425,13 @@
                       "installation scheme is incomplete")
             return
 
-        if self.home is not None:
+        if self.user:
+            if self.install_userbase is None:
+                raise DistutilsPlatformError(
+                    "User base directory is not specified")
+            self.install_base = self.install_platbase = self.install_userbase
+            self.select_scheme("unix_user")
+        elif self.home is not None:
             self.install_base = self.install_platbase = self.home
             self.select_scheme("unix_home")
         else:
@@ -401,7 +456,13 @@
 
     def finalize_other (self):          # Windows and Mac OS for now
 
-        if self.home is not None:
+        if self.user:
+            if self.install_userbase is None:
+                raise DistutilsPlatformError(
+                    "User base directory is not specified")
+            self.install_base = self.install_platbase = self.install_userbase
+            self.select_scheme(os.name + "_user")
+        elif self.home is not None:
             self.install_base = self.install_platbase = self.home
             self.select_scheme("unix_home")
         else:
@@ -431,7 +492,7 @@
         for attr in attrs:
             val = getattr(self, attr)
             if val is not None:
-                if os.name == 'posix':
+                if os.name == 'posix' or os.name == 'nt':
                     val = os.path.expanduser(val)
                 val = subst_vars(val, self.config_vars)
                 setattr(self, attr, val)
@@ -496,6 +557,16 @@
             attr = "install_" + name
             setattr(self, attr, change_root(self.root, getattr(self, attr)))
 
+    def create_home_path(self):
+        """Create directories under ~
+        """
+        if not self.user:
+            return
+        home = convert_path(os.path.expanduser("~"))
+        for name, path in self.config_vars.iteritems():
+            if path.startswith(home) and not os.path.isdir(path):
+                self.debug_print("os.makedirs('%s', 0700)" % path)
+                os.makedirs(path, 0700)
 
     # -- Command execution methods -------------------------------------
 

Modified: python/branches/tlee-ast-optimize/Lib/io.py
==============================================================================
--- python/branches/tlee-ast-optimize/Lib/io.py	(original)
+++ python/branches/tlee-ast-optimize/Lib/io.py	Wed May  7 14:56:55 2008
@@ -81,9 +81,8 @@
 
 def open(file, mode="r", buffering=None, encoding=None, errors=None,
          newline=None, closefd=True):
-    r"""
-    Open file and return a stream. If the file cannot be opened, an
-    IOError is raised.
+    r"""Open file and return a stream. If the file cannot be opened, an IOError is
+    raised.
 
     file is either a string giving the name (and the path if the file
     isn't in the current working directory) of the file to be opened or an
@@ -290,8 +289,7 @@
 
 class IOBase(object):
 
-    """
-    The abstract base class for all I/O classes, acting on streams of
+    """The abstract base class for all I/O classes, acting on streams of
     bytes. There is no public constructor.
 
     This class provides dummy implementations for many methods that
@@ -333,7 +331,7 @@
     ### Positioning ###
 
     def seek(self, pos, whence = 0):
-        """seek(pos: int, whence: int = 0) -> int.  Change stream position.
+        """Change stream position.
 
         Change the stream position to byte offset offset. offset is
         interpreted relative to the position indicated by whence.  Values
@@ -348,21 +346,21 @@
         self._unsupported("seek")
 
     def tell(self):
-        """tell() -> int.  Return current stream position."""
+        """Return current stream position."""
         return self.seek(0, 1)
 
     def truncate(self, pos = None):
-        """truncate(size: int = None) -> int. Truncate file to size bytes.
+        """Truncate file to size bytes.
 
-        Size defaults to the current IO position as reported by tell().
-        Returns the new size.
+        Size defaults to the current IO position as reported by tell().  Return
+        the new size.
         """
         self._unsupported("truncate")
 
     ### Flush and close ###
 
     def flush(self):
-        """flush() -> None.  Flushes write buffers, if applicable.
+        """Flush write buffers, if applicable.
 
         This is not implemented for read-only and non-blocking streams.
         """
@@ -371,7 +369,7 @@
     __closed = False
 
     def close(self):
-        """close() -> None.  Flushes and closes the IO object.
+        """Flush and close the IO object.
 
         This method has no effect if the file is already closed.
         """
@@ -397,7 +395,7 @@
     ### Inquiries ###
 
     def seekable(self):
-        """seekable() -> bool.  Return whether object supports random access.
+        """Return whether object supports random access.
 
         If False, seek(), tell() and truncate() will raise IOError.
         This method may need to do a test seek().
@@ -413,7 +411,7 @@
 
 
     def readable(self):
-        """readable() -> bool.  Return whether object was opened for reading.
+        """Return whether object was opened for reading.
 
         If False, read() will raise IOError.
         """
@@ -427,7 +425,7 @@
                           if msg is None else msg)
 
     def writable(self):
-        """writable() -> bool.  Return whether object was opened for writing.
+        """Return whether object was opened for writing.
 
         If False, write() and truncate() will raise IOError.
         """
@@ -471,16 +469,16 @@
     # XXX Should these be present even if unimplemented?
 
     def fileno(self):
-        """fileno() -> int.  Returns underlying file descriptor if one exists.
+        """Returns underlying file descriptor if one exists.
 
-        Raises IOError if the IO object does not use a file descriptor.
+        An IOError is raised if the IO object does not use a file descriptor.
         """
         self._unsupported("fileno")
 
     def isatty(self):
-        """isatty() -> int.  Returns whether this is an 'interactive' stream.
+        """Return whether this is an 'interactive' stream.
 
-        Returns False if we don't know.
+        Return False if it can't be determined.
         """
         self._checkClosed()
         return False
@@ -488,8 +486,7 @@
     ### Readline[s] and writelines ###
 
     def readline(self, limit = -1):
-        r"""readline(limit: int = -1) -> bytes Read and return a line from the
-        stream.
+        r"""Read and return a line from the stream.
 
         If limit is specified, at most limit bytes will be read.
 
@@ -532,7 +529,7 @@
         return line
 
     def readlines(self, hint=None):
-        """readlines(hint=None) -> list Return a list of lines from the stream.
+        """Return a list of lines from the stream.
 
         hint can be specified to control the number of lines read: no more
         lines will be read if the total size (in bytes/characters) of all
@@ -570,7 +567,7 @@
     # a subclass doesn't implement either.)
 
     def read(self, n = -1):
-        """read(n: int) -> bytes.  Read and return up to n bytes.
+        """Read and return up to n bytes.
 
         Returns an empty bytes array on EOF, or None if the object is
         set not to block and has no data to read.
@@ -585,7 +582,7 @@
         return bytes(b)
 
     def readall(self):
-        """readall() -> bytes.  Read until EOF, using multiple read() call."""
+        """Read until EOF, using multiple read() call."""
         res = bytearray()
         while True:
             data = self.read(DEFAULT_BUFFER_SIZE)
@@ -595,7 +592,7 @@
         return bytes(res)
 
     def readinto(self, b):
-        """readinto(b: bytes) -> int.  Read up to len(b) bytes into b.
+        """Read up to len(b) bytes into b.
 
         Returns number of bytes read (0 for EOF), or None if the object
         is set not to block as has no data to read.
@@ -603,7 +600,7 @@
         self._unsupported("readinto")
 
     def write(self, b):
-        """write(b: bytes) -> int.  Write the given buffer to the IO stream.
+        """Write the given buffer to the IO stream.
 
         Returns the number of bytes written, which may be less than len(b).
         """
@@ -650,7 +647,7 @@
     """
 
     def read(self, n = None):
-        """read(n: int = None) -> bytes.  Read and return up to n bytes.
+        """Read and return up to n bytes.
 
         If the argument is omitted, None, or negative, reads and
         returns all data until EOF.
@@ -670,7 +667,7 @@
         self._unsupported("read")
 
     def readinto(self, b):
-        """readinto(b: bytearray) -> int.  Read up to len(b) bytes into b.
+        """Read up to len(b) bytes into b.
 
         Like read(), this may issue multiple reads to the underlying raw
         stream, unless the latter is 'interactive'.
@@ -693,9 +690,9 @@
         return n
 
     def write(self, b):
-        """write(b: bytes) -> int.  Write the given buffer to the IO stream.
+        """Write the given buffer to the IO stream.
 
-        Returns the number of bytes written, which is never less than
+        Return the number of bytes written, which is never less than
         len(b).
 
         Raises BlockingIOError if the buffer is full and the
@@ -785,7 +782,7 @@
         self._pos = 0
 
     def getvalue(self):
-        """getvalue() -> bytes Return the bytes value (contents) of the buffer
+        """Return the bytes value (contents) of the buffer
         """
         return bytes(self._buffer)
 
@@ -800,7 +797,7 @@
         return bytes(b)
 
     def read1(self, n):
-        """In BytesIO, this is the same as read.
+        """this is the same as read.
         """
         return self.read(n)
 
@@ -939,9 +936,7 @@
 
 class BufferedWriter(_BufferedIOMixin):
 
-    """BufferedWriter(raw[, buffer_size[, max_buffer_size]])
-
-    A buffer for a writeable sequential RawIO object.
+    """A buffer for a writeable sequential RawIO object.
 
     The constructor creates a BufferedWriter for the given writeable raw
     stream. If the buffer_size is not given, it defaults to
@@ -1079,9 +1074,7 @@
 
 class BufferedRandom(BufferedWriter, BufferedReader):
 
-    """BufferedRandom(raw[, buffer_size[, max_buffer_size]])
-
-    A buffered interface to random access streams.
+    """A buffered interface to random access streams.
 
     The constructor creates a reader and writer for a seekable stream,
     raw, given in the first argument. If the buffer_size is omitted it
@@ -1144,7 +1137,7 @@
     """
 
     def read(self, n = -1):
-        """read(n: int = -1) -> unicode.  Read at most n characters from stream.
+        """Read at most n characters from stream.
 
         Read from underlying buffer until we have n characters or we hit EOF.
         If n is negative or omitted, read until EOF.
@@ -1152,11 +1145,11 @@
         self._unsupported("read")
 
     def write(self, s):
-        """write(s: unicode) -> int.  Write string s to stream."""
+        """Write string s to stream."""
         self._unsupported("write")
 
     def truncate(self, pos = None):
-        """truncate(pos: int = None) -> int.  Truncate size to pos."""
+        """Truncate size to pos."""
         self.flush()
         if pos is None:
             pos = self.tell()
@@ -1164,7 +1157,7 @@
         return self.buffer.truncate()
 
     def readline(self):
-        """readline() -> unicode.  Read until newline or EOF.
+        """Read until newline or EOF.
 
         Returns an empty string if EOF is hit immediately.
         """
@@ -1177,8 +1170,7 @@
 
     @property
     def newlines(self):
-        """newlines -> None | unicode | tuple of unicode. Line endings translated
-        so far.
+        """Line endings translated so far.
 
         Only line endings translated during reading are considered.
 
@@ -1268,9 +1260,7 @@
 
 class TextIOWrapper(TextIOBase):
 
-    r"""TextIOWrapper(buffer[, encoding[, errors[, newline[, line_buffering]]]])
-
-    Character and line based layer over a BufferedIOBase object, buffer.
+    r"""Character and line based layer over a BufferedIOBase object, buffer.
 
     encoding gives the name of the encoding that the stream will be
     decoded or encoded with. It defaults to locale.getpreferredencoding.
@@ -1727,9 +1717,7 @@
 
 class StringIO(TextIOWrapper):
 
-    """StringIO([initial_value[, encoding, [errors, [newline]]]])
-
-    An in-memory stream for text. The initial_value argument sets the
+    """An in-memory stream for text. The initial_value argument sets the
     value of object. The other arguments are like those of TextIOWrapper's
     constructor.
     """

Modified: python/branches/tlee-ast-optimize/Lib/os.py
==============================================================================
--- python/branches/tlee-ast-optimize/Lib/os.py	(original)
+++ python/branches/tlee-ast-optimize/Lib/os.py	Wed May  7 14:56:55 2008
@@ -267,8 +267,9 @@
 
     Example:
 
+    import os
     from os.path import join, getsize
-    for root, dirs, files in walk('python/Lib/email'):
+    for root, dirs, files in os.walk('python/Lib/email'):
         print root, "consumes",
         print sum([getsize(join(root, name)) for name in files]),
         print "bytes in", len(files), "non-directory files"

Modified: python/branches/tlee-ast-optimize/Lib/site.py
==============================================================================
--- python/branches/tlee-ast-optimize/Lib/site.py	(original)
+++ python/branches/tlee-ast-optimize/Lib/site.py	Wed May  7 14:56:55 2008
@@ -62,11 +62,21 @@
 import os
 import __builtin__
 
+# Prefixes for site-packages; add additional prefixes like /usr/local here
+PREFIXES = [sys.prefix, sys.exec_prefix]
+# 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
+USER_SITE = None
+USER_BASE = None
+
 
 def makepath(*paths):
     dir = os.path.abspath(os.path.join(*paths))
     return dir, os.path.normcase(dir)
 
+
 def abs__file__():
     """Set all module' __file__ attribute to an absolute path"""
     for m in sys.modules.values():
@@ -77,6 +87,7 @@
         except AttributeError:
             continue
 
+
 def removeduppaths():
     """ Remove duplicate entries from sys.path along with making them
     absolute"""
@@ -107,6 +118,7 @@
     s = os.path.join(os.path.dirname(sys.path[-1]), s)
     sys.path.append(s)
 
+
 def _init_pathinfo():
     """Return a set containing all existing directory entries from sys.path"""
     d = set()
@@ -119,6 +131,7 @@
             continue
     return d
 
+
 def addpackage(sitedir, name, known_paths):
     """Process a .pth file within the site-packages directory:
        For each line in the file, either combine it with sitedir to a path
@@ -134,11 +147,11 @@
         f = open(fullname, "rU")
     except IOError:
         return
-    try:
+    with f:
         for line in f:
             if line.startswith("#"):
                 continue
-            if line.startswith("import ") or line.startswith("import\t"):
+            if line.startswith(("import ", "import\t")):
                 exec line
                 continue
             line = line.rstrip()
@@ -146,12 +159,11 @@
             if not dircase in known_paths and os.path.exists(dir):
                 sys.path.append(dir)
                 known_paths.add(dircase)
-    finally:
-        f.close()
     if reset:
         known_paths = None
     return known_paths
 
+
 def addsitedir(sitedir, known_paths=None):
     """Add 'sitedir' argument to sys.path if missing and handle .pth files in
     'sitedir'"""
@@ -167,48 +179,115 @@
         names = os.listdir(sitedir)
     except os.error:
         return
-    names.sort()
-    for name in names:
-        if name.endswith(os.extsep + "pth"):
-            addpackage(sitedir, name, known_paths)
+    dotpth = os.extsep + "pth"
+    names = [name for name in names if name.endswith(dotpth)]
+    for name in sorted(names):
+        addpackage(sitedir, name, known_paths)
     if reset:
         known_paths = None
     return known_paths
 
+
+def check_enableusersite():
+    """Check if user site directory is safe for inclusion
+
+    The functions tests for the command line flag (including environment var),
+    process uid/gid equal to effective uid/gid.
+
+    None: Disabled for security reasons
+    False: Disabled by user (command line option)
+    True: Safe and enabled
+    """
+    if sys.flags.no_user_site:
+        return False
+
+    if hasattr(os, "getuid") and hasattr(os, "geteuid"):
+        # check process uid == effective uid
+        if os.geteuid() != os.getuid():
+            return None
+    if hasattr(os, "getgid") and hasattr(os, "getegid"):
+        # check process gid == effective gid
+        if os.getegid() != os.getgid():
+            return None
+
+    return True
+
+
+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.
+    """
+    global USER_BASE, USER_SITE, ENABLE_USER_SITE
+    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 = ''
+    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],
+                                 "site-packages")
+
+    if ENABLE_USER_SITE and os.path.isdir(USER_SITE):
+        addsitedir(USER_SITE, known_paths)
+    return known_paths
+
+
 def addsitepackages(known_paths):
     """Add site-packages (and possibly site-python) to sys.path"""
-    prefixes = [sys.prefix]
-    if sys.exec_prefix != sys.prefix:
-        prefixes.append(sys.exec_prefix)
-    for prefix in prefixes:
-        if prefix:
-            if sys.platform in ('os2emx', 'riscos'):
-                sitedirs = [os.path.join(prefix, "Lib", "site-packages")]
-            elif os.sep == '/':
-                sitedirs = [os.path.join(prefix,
-                                         "lib",
-                                         "python" + sys.version[:3],
-                                         "site-packages"),
-                            os.path.join(prefix, "lib", "site-python")]
-            else:
-                sitedirs = [prefix, os.path.join(prefix, "lib", "site-packages")]
-            if sys.platform == 'darwin':
-                # for framework builds *only* we add the standard Apple
-                # locations. Currently only per-user, but /Library and
-                # /Network/Library could be added too
-                if 'Python.framework' in prefix:
-                    home = os.environ.get('HOME')
-                    if home:
-                        sitedirs.append(
-                            os.path.join(home,
-                                         'Library',
-                                         'Python',
-                                         sys.version[:3],
-                                         'site-packages'))
-            for sitedir in sitedirs:
-                if os.path.isdir(sitedir):
-                    addsitedir(sitedir, known_paths)
-    return None
+    sitedirs = []
+    seen = []
+
+    for prefix in PREFIXES:
+        if not prefix or prefix in seen:
+            continue
+        seen.append(prefix)
+
+        if sys.platform in ('os2emx', 'riscos'):
+            sitedirs.append(os.path.join(prefix, "Lib", "site-packages"))
+        elif os.sep == '/':
+            sitedirs.append(os.path.join(prefix, "lib",
+                                        "python" + sys.version[:3],
+                                        "site-packages"))
+            sitedirs.append(os.path.join(prefix, "lib", "site-python"))
+        else:
+            sitedirs.append(prefix)
+            sitedirs.append(os.path.join(prefix, "lib", "site-packages"))
+
+        if sys.platform == "darwin":
+            # for framework builds *only* we add the standard Apple
+            # locations. Currently only per-user, but /Library and
+            # /Network/Library could be added too
+            if 'Python.framework' in prefix:
+                sitedirs.append(
+                    os.path.expanduser(
+                        os.path.join("~", "Library", "Python",
+                                     sys.version[:3], "site-packages")))
+
+    for sitedir in sitedirs:
+        if os.path.isdir(sitedir):
+            addsitedir(sitedir, known_paths)
+
+    return known_paths
 
 
 def setBEGINLIBPATH():
@@ -395,13 +474,26 @@
         pass
 
 
+def execusercustomize():
+    """Run custom user specific code, if available."""
+    try:
+        import usercustomize
+    except ImportError:
+        pass
+
+
 def main():
+    global ENABLE_USER_SITE
+
     abs__file__()
-    paths_in_sys = removeduppaths()
+    known_paths = removeduppaths()
     if (os.name == "posix" and sys.path and
         os.path.basename(sys.path[-1]) == "Modules"):
         addbuilddir()
-    paths_in_sys = addsitepackages(paths_in_sys)
+    if ENABLE_USER_SITE is None:
+        ENABLE_USER_SITE = check_enableusersite()
+    known_paths = addusersitepackages(known_paths)
+    known_paths = addsitepackages(known_paths)
     if sys.platform == 'os2emx':
         setBEGINLIBPATH()
     setquit()
@@ -410,6 +502,8 @@
     aliasmbcs()
     setencoding()
     execsitecustomize()
+    if ENABLE_USER_SITE:
+        execusercustomize()
     # Remove sys.setdefaultencoding() so that users cannot change the
     # encoding after initialization.  The test for presence is needed when
     # this module is run as a script, because this code is executed twice.
@@ -418,11 +512,54 @@
 
 main()
 
-def _test():
-    print "sys.path = ["
-    for dir in sys.path:
-        print "    %r," % (dir,)
-    print "]"
+def _script():
+    help = """\
+    %s [--user-base] [--user-site]
+
+    Without arguments print some useful information
+    With arguments print the value of USER_BASE and/or USER_SITE separated
+    by '%s'.
+
+    Exit codes with --user-base or --user-site:
+      0 - user site directory is enabled
+      1 - user site diretory is disabled by user
+      2 - uses site directory is disabled by super user
+          or for security reasons
+     >2 - unknown error
+    """
+    args = sys.argv[1:]
+    if not args:
+        print "sys.path = ["
+        for dir in sys.path:
+            print "    %r," % (dir,)
+        print "]"
+        print "USER_BASE: %r (%s)" % (USER_BASE,
+            "exists" if os.path.isdir(USER_BASE) else "doesn't exist")
+        print "USER_SITE: %r (%s)" % (USER_SITE,
+            "exists" if os.path.isdir(USER_SITE) else "doesn't exist")
+        print "ENABLE_USER_SITE: %r" %  ENABLE_USER_SITE
+        sys.exit(0)
+
+    buffer = []
+    if '--user-base' in args:
+        buffer.append(USER_BASE)
+    if '--user-site' in args:
+        buffer.append(USER_SITE)
+
+    if buffer:
+        print os.pathsep.join(buffer)
+        if ENABLE_USER_SITE:
+            sys.exit(0)
+        elif ENABLE_USER_SITE is False:
+            sys.exit(1)
+        elif ENABLE_USER_SITE is None:
+            sys.exit(2)
+        else:
+            sys.exit(3)
+    else:
+        import textwrap
+        print textwrap.dedent(help % (sys.argv[0], os.pathsep))
+        sys.exit(10)
 
 if __name__ == '__main__':
-    _test()
+    _script()

Modified: python/branches/tlee-ast-optimize/Lib/socket.py
==============================================================================
--- python/branches/tlee-ast-optimize/Lib/socket.py	(original)
+++ python/branches/tlee-ast-optimize/Lib/socket.py	Wed May  7 14:56:55 2008
@@ -312,7 +312,8 @@
 
     def read(self, size=-1):
         # Use max, disallow tiny reads in a loop as they are very inefficient.
-        # We never leave read() with any leftover data in our internal buffer.
+        # We never leave read() with any leftover data from a new recv() call
+        # in our internal buffer.
         rbufsize = max(self._rbufsize, self.default_bufsize)
         # Our use of StringIO rather than lists of string objects returned by
         # recv() minimizes memory usage and fragmentation that occurs when
@@ -342,13 +343,12 @@
             self._rbuf = StringIO()  # reset _rbuf.  we consume it via buf.
             while True:
                 left = size - buf_len
-                # Using max() here means that recv() can malloc a
-                # large amount of memory even though recv may return
-                # much less data than that.  But the returned data
-                # string is short lived in that case as we copy it
-                # into a StringIO and free it.
-                recv_size = max(rbufsize, left)
-                data = self._sock.recv(recv_size)
+                # recv() will malloc the amount of memory given as its
+                # parameter even though it often returns much less data
+                # than that.  The returned data string is short lived
+                # as we copy it into a StringIO and free it.  This avoids
+                # fragmentation issues on many platforms.
+                data = self._sock.recv(left)
                 if not data:
                     break
                 n = len(data)
@@ -359,13 +359,11 @@
                     # - Our call to recv returned exactly the
                     #   number of bytes we were asked to read.
                     return data
-                if n >= left:
-                    # avoids data copy of: buf.write(data[:left])
-                    buf.write(buffer(data, 0, left))
-                    # avoids data copy of: self._rbuf.write(data[left:])
-                    self._rbuf.write(buffer(data, left))
+                if n == left:
+                    buf.write(data)
                     del data  # explicit free
                     break
+                assert n <= left, "recv(%d) returned %d bytes" % (left, n)
                 buf.write(data)
                 buf_len += n
                 del data  # explicit free
@@ -374,8 +372,9 @@
 
     def readline(self, size=-1):
         buf = self._rbuf
-        if self._rbufsize > 1:
-            # if we're buffering, check if we already have it in our buffer
+        buf.seek(0, 2)  # seek end
+        if buf.tell() > 0:
+            # check if we already have it in our buffer
             buf.seek(0)
             bline = buf.readline(size)
             if bline.endswith('\n') or len(bline) == size:
@@ -383,13 +382,13 @@
                 self._rbuf.write(buf.read())
                 return bline
             del bline
-        buf.seek(0, 2)  # seek end
         if size < 0:
             # Read until \n or EOF, whichever comes first
             if self._rbufsize <= 1:
                 # Speed up unbuffered case
-                assert buf.tell() == 0
-                buffers = []
+                buf.seek(0)
+                buffers = [buf.read()]
+                self._rbuf = StringIO()  # reset _rbuf.  we consume it via buf.
                 data = None
                 recv = self._sock.recv
                 while data != "\n":
@@ -399,7 +398,6 @@
                     buffers.append(data)
                 return "".join(buffers)
 
-            buf = self._rbuf
             buf.seek(0, 2)  # seek end
             self._rbuf = StringIO()  # reset _rbuf.  we consume it via buf.
             while True:
@@ -417,6 +415,7 @@
             return buf.getvalue()
         else:
             # Read until size bytes or \n or EOF seen, whichever comes first
+            buf.seek(0, 2)  # seek end
             buf_len = buf.tell()
             if buf_len >= size:
                 buf.seek(0)

Modified: python/branches/tlee-ast-optimize/Lib/test/test___all__.py
==============================================================================
--- python/branches/tlee-ast-optimize/Lib/test/test___all__.py	(original)
+++ python/branches/tlee-ast-optimize/Lib/test/test___all__.py	Wed May  7 14:56:55 2008
@@ -1,27 +1,22 @@
 import unittest
-from test.test_support import run_unittest
+from test.test_support import run_unittest, catch_warning
 import sys
 import warnings
 
-warnings.filterwarnings("ignore", "the sets module is deprecated",
-                        DeprecationWarning, "<string>")
-warnings.filterwarnings("ignore", ".*popen2 module is deprecated.*",
-                        DeprecationWarning)
-warnings.filterwarnings("ignore", "the MimeWriter module is deprecated.*",
-                        DeprecationWarning)
-warnings.filterwarnings("ignore", "the mimify module is deprecated.*",
-                        DeprecationWarning)
+
 
 class AllTest(unittest.TestCase):
 
     def check_all(self, modname):
         names = {}
-        try:
-            exec "import %s" % modname in names
-        except ImportError:
-            # Silent fail here seems the best route since some modules
-            # may not be available in all environments.
-            return
+        with catch_warning():
+            warnings.filterwarnings("ignore", ".* module", DeprecationWarning)
+            try:
+                exec "import %s" % modname in names
+            except ImportError:
+                # Silent fail here seems the best route since some modules
+                # may not be available in all environments.
+                return
         self.failUnless(hasattr(sys.modules[modname], "__all__"),
                         "%s has no __all__ attribute" % modname)
         names = {}

Modified: python/branches/tlee-ast-optimize/Lib/test/test_py3kwarn.py
==============================================================================
--- python/branches/tlee-ast-optimize/Lib/test/test_py3kwarn.py	(original)
+++ python/branches/tlee-ast-optimize/Lib/test/test_py3kwarn.py	Wed May  7 14:56:55 2008
@@ -124,8 +124,42 @@
             self.assertWarning(buffer('a'), w, expected)
 
 
+class TestStdlibRemovals(unittest.TestCase):
+
+    all_platforms = ('audiodev',)
+
+    def check_removal(self, module_name):
+        """Make sure the specified module, when imported, raises a
+        DeprecationWarning and specifies itself in the message."""
+        original_module = None
+        if module_name in sys.modules:
+            original_module = sys.modules[module_name]
+            del sys.modules[module_name]
+        try:
+            with catch_warning() as w:
+                warnings.filterwarnings("error", ".+ removed",
+                                        DeprecationWarning)
+                try:
+                    __import__(module_name, level=0)
+                except DeprecationWarning as exc:
+                    self.assert_(module_name in exc.args[0])
+                else:
+                    self.fail("DeprecationWarning not raised for %s" %
+                                module_name)
+        finally:
+            if original_module:
+                sys.modules[module_name] = original_module
+
+
+    def test_platform_independent_removals(self):
+        # Make sure that the modules that are available on all platforms raise
+        # the proper DeprecationWarning.
+        for module_name in self.all_platforms:
+            self.check_removal(module_name)
+
+
 def test_main():
-    run_unittest(TestPy3KWarnings)
+    run_unittest(TestPy3KWarnings, TestStdlibRemovals)
 
 if __name__ == '__main__':
     test_main()

Modified: python/branches/tlee-ast-optimize/Lib/test/test_site.py
==============================================================================
--- python/branches/tlee-ast-optimize/Lib/test/test_site.py	(original)
+++ python/branches/tlee-ast-optimize/Lib/test/test_site.py	Wed May  7 14:56:55 2008
@@ -10,6 +10,7 @@
 import os
 import sys
 import encodings
+import subprocess
 # Need to make sure to not import 'site' if someone specified ``-S`` at the
 # command-line.  Detect this by just making sure 'site' has not been imported
 # already.
@@ -18,6 +19,11 @@
 else:
     raise TestSkipped("importation of site.py suppressed")
 
+if not os.path.isdir(site.USER_SITE):
+    # need to add user site directory for tests
+    os.makedirs(site.USER_SITE)
+    site.addsitedir(site.USER_SITE)
+
 class HelperFunctionsTests(unittest.TestCase):
     """Tests for helper functions.
 
@@ -30,7 +36,7 @@
         """Save a copy of sys.path"""
         self.sys_path = sys.path[:]
 
-    def tearDown(self):
+
         """Restore sys.path"""
         sys.path = self.sys_path
 
@@ -90,6 +96,33 @@
         finally:
             pth_file.cleanup()
 
+    def test_s_option(self):
+        usersite = site.USER_SITE
+        self.assert_(usersite in sys.path)
+
+        rc = subprocess.call([sys.executable, '-c',
+            'import sys; sys.exit("%s" in sys.path)' % usersite])
+        self.assertEqual(rc, 1)
+
+        rc = subprocess.call([sys.executable, '-s', '-c',
+            'import sys; sys.exit("%s" in sys.path)' % usersite])
+        self.assertEqual(rc, 0)
+
+        env = os.environ.copy()
+        env["PYTHONNOUSERSITE"] = "1"
+        rc = subprocess.call([sys.executable, '-c',
+            'import sys; sys.exit("%s" in sys.path)' % usersite],
+            env=env)
+        self.assertEqual(rc, 0)
+
+        env = os.environ.copy()
+        env["PYTHONUSERBASE"] = "/tmp"
+        rc = subprocess.call([sys.executable, '-c',
+            'import sys, site; sys.exit(site.USER_BASE.startswith("/tmp"))'],
+            env=env)
+        self.assertEqual(rc, 1)
+
+
 class PthFile(object):
     """Helper class for handling testing of .pth files"""
 

Modified: python/branches/tlee-ast-optimize/Lib/test/test_socket.py
==============================================================================
--- python/branches/tlee-ast-optimize/Lib/test/test_socket.py	(original)
+++ python/branches/tlee-ast-optimize/Lib/test/test_socket.py	Wed May  7 14:56:55 2008
@@ -789,6 +789,33 @@
         self.cli_file.write(MSG)
         self.cli_file.flush()
 
+    def testReadlineAfterRead(self):
+        a_baloo_is = self.serv_file.read(len("A baloo is"))
+        self.assertEqual("A baloo is", a_baloo_is)
+        _a_bear = self.serv_file.read(len(" a bear"))
+        self.assertEqual(" a bear", _a_bear)
+        line = self.serv_file.readline()
+        self.assertEqual("\n", line)
+        line = self.serv_file.readline()
+        self.assertEqual("A BALOO IS A BEAR.\n", line)
+        line = self.serv_file.readline()
+        self.assertEqual(MSG, line)
+
+    def _testReadlineAfterRead(self):
+        self.cli_file.write("A baloo is a bear\n")
+        self.cli_file.write("A BALOO IS A BEAR.\n")
+        self.cli_file.write(MSG)
+        self.cli_file.flush()
+
+    def testReadlineAfterReadNoNewline(self):
+        end_of_ = self.serv_file.read(len("End Of "))
+        self.assertEqual("End Of ", end_of_)
+        line = self.serv_file.readline()
+        self.assertEqual("Line", line)
+
+    def _testReadlineAfterReadNoNewline(self):
+        self.cli_file.write("End Of Line")
+
     def testClosedAttr(self):
         self.assert_(not self.serv_file.closed)
 

Modified: python/branches/tlee-ast-optimize/Lib/test/test_subprocess.py
==============================================================================
--- python/branches/tlee-ast-optimize/Lib/test/test_subprocess.py	(original)
+++ python/branches/tlee-ast-optimize/Lib/test/test_subprocess.py	Wed May  7 14:56:55 2008
@@ -584,7 +584,7 @@
             os.remove(fname)
             self.assertEqual(rc, 47)
 
-        def test_send_signal(self):
+        def DISABLED_test_send_signal(self):
             p = subprocess.Popen([sys.executable,
                               "-c", "input()"])
 
@@ -592,7 +592,7 @@
             p.send_signal(signal.SIGINT)
             self.assertNotEqual(p.wait(), 0)
 
-        def test_kill(self):
+        def DISABLED_test_kill(self):
             p = subprocess.Popen([sys.executable,
                             "-c", "input()"])
 
@@ -600,7 +600,7 @@
             p.kill()
             self.assertEqual(p.wait(), -signal.SIGKILL)
 
-        def test_terminate(self):
+        def DISABLED_test_terminate(self):
             p = subprocess.Popen([sys.executable,
                             "-c", "input()"])
 
@@ -678,7 +678,7 @@
                                  ' -c "import sys; sys.exit(47)"')
             self.assertEqual(rc, 47)
 
-        def test_send_signal(self):
+        def DISABLED_test_send_signal(self):
             p = subprocess.Popen([sys.executable,
                               "-c", "input()"])
 
@@ -686,7 +686,7 @@
             p.send_signal(signal.SIGTERM)
             self.assertNotEqual(p.wait(), 0)
 
-        def test_kill(self):
+        def DISABLED_test_kill(self):
             p = subprocess.Popen([sys.executable,
                             "-c", "input()"])
 
@@ -694,7 +694,7 @@
             p.kill()
             self.assertNotEqual(p.wait(), 0)
 
-        def test_terminate(self):
+        def DISABLED_test_terminate(self):
             p = subprocess.Popen([sys.executable,
                             "-c", "input()"])
 

Modified: python/branches/tlee-ast-optimize/Lib/test/test_warnings.py
==============================================================================
--- python/branches/tlee-ast-optimize/Lib/test/test_warnings.py	(original)
+++ python/branches/tlee-ast-optimize/Lib/test/test_warnings.py	Wed May  7 14:56:55 2008
@@ -225,6 +225,8 @@
                 self.assertEqual(os.path.basename(w.filename), "test_warnings.py")
                 warning_tests.outer("spam6", stacklevel=2)
                 self.assertEqual(os.path.basename(w.filename), "warning_tests.py")
+                warning_tests.outer("spam6.5", stacklevel=3)
+                self.assertEqual(os.path.basename(w.filename), "test_warnings.py")
 
                 warning_tests.inner("spam7", stacklevel=9999)
                 self.assertEqual(os.path.basename(w.filename), "sys")
@@ -386,6 +388,15 @@
                 result = stream.getvalue()
         self.failUnless(text in result)
 
+    def test_showwarning_not_callable(self):
+        self.module.filterwarnings("always", category=UserWarning)
+        old_showwarning = self.module.showwarning
+        self.module.showwarning = 23
+        try:
+            self.assertRaises(TypeError, self.module.warn, "Warning!")
+        finally:
+            self.module.showwarning = old_showwarning
+
     def test_show_warning_output(self):
         # With showarning() missing, make sure that output is okay.
         text = 'test show_warning'
@@ -461,6 +472,32 @@
     module = py_warnings
 
 
+class ShowwarningDeprecationTests(BaseTest):
+
+    """Test the deprecation of the old warnings.showwarning() API works."""
+
+    @staticmethod
+    def bad_showwarning(message, category, filename, lineno, file=None):
+        pass
+
+    def test_deprecation(self):
+        # message, category, filename, lineno[, file[, line]]
+        args = ("message", UserWarning, "file name", 42)
+        with test_support.catch_warning(self.module):
+            self.module.filterwarnings("error", category=DeprecationWarning)
+            self.module.showwarning = self.bad_showwarning
+            self.assertRaises(DeprecationWarning, self.module.warn_explicit,
+                                *args)
+
+class CShowwarningDeprecationTests(ShowwarningDeprecationTests):
+    module = c_warnings
+
+
+class PyShowwarningDeprecationTests(ShowwarningDeprecationTests):
+    module = py_warnings
+
+
+
 def test_main():
     py_warnings.onceregistry.clear()
     c_warnings.onceregistry.clear()
@@ -471,6 +508,8 @@
                                 CWCmdLineTests, PyWCmdLineTests,
                                 _WarningsTests,
                                 CWarningsDisplayTests, PyWarningsDisplayTests,
+                                CShowwarningDeprecationTests,
+                                PyShowwarningDeprecationTests,
                              )
 
 

Modified: python/branches/tlee-ast-optimize/Lib/test/test_zipfile.py
==============================================================================
--- python/branches/tlee-ast-optimize/Lib/test/test_zipfile.py	(original)
+++ python/branches/tlee-ast-optimize/Lib/test/test_zipfile.py	Wed May  7 14:56:55 2008
@@ -553,6 +553,17 @@
 
 
 class OtherTests(unittest.TestCase):
+    def testUnicodeFilenames(self):
+        zf = zipfile.ZipFile(TESTFN, "w")
+        zf.writestr(u"foo.txt", "Test for unicode filename")
+        zf.writestr(u"\xf6.txt", "Test for unicode filename")
+        self.assertTrue(isinstance(zf.infolist()[0].filename, unicode))
+        zf.close()
+        zf = zipfile.ZipFile(TESTFN, "r")
+        self.assertEqual(zf.filelist[0].filename, "foo.txt")
+        self.assertEqual(zf.filelist[1].filename, u"\xf6.txt")
+        zf.close()
+
     def testCreateNonExistentFileForAppend(self):
         if os.path.exists(TESTFN):
             os.unlink(TESTFN)

Modified: python/branches/tlee-ast-optimize/Lib/urllib2.py
==============================================================================
--- python/branches/tlee-ast-optimize/Lib/urllib2.py	(original)
+++ python/branches/tlee-ast-optimize/Lib/urllib2.py	Wed May  7 14:56:55 2008
@@ -976,6 +976,8 @@
         return base
 
     def get_algorithm_impls(self, algorithm):
+        # algorithm should be case-insensitive according to RFC2617
+        algorithm = algorithm.upper()
         # lambdas assume digest modules are imported at the top level
         if algorithm == 'MD5':
             H = lambda x: hashlib.md5(x).hexdigest()

Modified: python/branches/tlee-ast-optimize/Lib/warnings.py
==============================================================================
--- python/branches/tlee-ast-optimize/Lib/warnings.py	(original)
+++ python/branches/tlee-ast-optimize/Lib/warnings.py	Wed May  7 14:56:55 2008
@@ -21,7 +21,7 @@
             category = DeprecationWarning
         warn(message, category, stacklevel+1)
 
-def showwarning(message, category, filename, lineno, file=None, line=None):
+def _show_warning(message, category, filename, lineno, file=None, line=None):
     """Hook to write a warning to a file; replace if you like."""
     if file is None:
         file = sys.stderr
@@ -29,6 +29,9 @@
         file.write(formatwarning(message, category, filename, lineno, line))
     except IOError:
         pass # the file (probably stderr) is invalid - this warning gets lost.
+# Keep a worrking version around in case the deprecation of the old API is
+# triggered.
+showwarning = _show_warning
 
 def formatwarning(message, category, filename, lineno, line=None):
     """Function to format a warning the standard way."""
@@ -258,6 +261,26 @@
         raise RuntimeError(
               "Unrecognized action (%r) in warnings.filters:\n %s" %
               (action, item))
+    # Warn if showwarning() does not support the 'line' argument.
+    # Don't use 'inspect' as it relies on an extension module, which break the
+    # build thanks to 'warnings' being imported by setup.py.
+    fxn_code = None
+    if hasattr(showwarning, 'func_code'):
+        fxn_code = showwarning.func_code
+    elif hasattr(showwarning, '__func__'):
+        fxn_code = showwarning.__func__.func_code
+    if fxn_code:
+        args = fxn_code.co_varnames[:fxn_code.co_argcount]
+        if 'line' not in args:
+            showwarning_msg = ("functions overriding warnings.showwarning() "
+                                "must support the 'line' argument")
+            if message == showwarning_msg:
+                _show_warning(message, category, filename, lineno)
+            else:
+                warn(showwarning_msg, DeprecationWarning)
+    if not callable(showwarning):
+        raise TypeError("warnings.showwarning() must be set to a "
+                        "function or method")
     # Print message and context
     showwarning(message, category, filename, lineno)
 

Modified: python/branches/tlee-ast-optimize/Lib/zipfile.py
==============================================================================
--- python/branches/tlee-ast-optimize/Lib/zipfile.py	(original)
+++ python/branches/tlee-ast-optimize/Lib/zipfile.py	Wed May  7 14:56:55 2008
@@ -255,12 +255,28 @@
             self.extract_version = max(45, self.extract_version)
             self.create_version = max(45, self.extract_version)
 
+        filename, flag_bits = self._encodeFilenameFlags()
         header = struct.pack(structFileHeader, stringFileHeader,
-                 self.extract_version, self.reserved, self.flag_bits,
+                 self.extract_version, self.reserved, flag_bits,
                  self.compress_type, dostime, dosdate, CRC,
                  compress_size, file_size,
-                 len(self.filename), len(extra))
-        return header + self.filename + extra
+                 len(filename), len(extra))
+        return header + filename + extra
+
+    def _encodeFilenameFlags(self):
+        if isinstance(self.filename, unicode):
+            try:
+                return self.filename.encode('ascii'), self.flag_bits
+            except UnicodeEncodeError:
+                return self.filename.encode('utf-8'), self.flag_bits | 0x800
+        else:
+            return self.filename, self.flag_bits
+
+    def _decodeFilename(self):
+        if self.flag_bits & 0x800:
+            return self.filename.decode('utf-8')
+        else:
+            return self.filename
 
     def _decodeExtra(self):
         # Try to decode the extra field.
@@ -693,6 +709,7 @@
 
             x._decodeExtra()
             x.header_offset = x.header_offset + concat
+            x.filename = x._decodeFilename()
             self.filelist.append(x)
             self.NameToInfo[x.filename] = x
             if self.debug > 2:
@@ -1054,12 +1071,13 @@
                     create_version = zinfo.create_version
 
                 try:
+                    filename, flag_bits = zinfo._encodeFilenameFlags()
                     centdir = struct.pack(structCentralDir,
                      stringCentralDir, create_version,
                      zinfo.create_system, extract_version, zinfo.reserved,
-                     zinfo.flag_bits, zinfo.compress_type, dostime, dosdate,
+                     flag_bits, zinfo.compress_type, dostime, dosdate,
                      zinfo.CRC, compress_size, file_size,
-                     len(zinfo.filename), len(extra_data), len(zinfo.comment),
+                     len(filename), len(extra_data), len(zinfo.comment),
                      0, zinfo.internal_attr, zinfo.external_attr,
                      header_offset)
                 except DeprecationWarning:
@@ -1073,7 +1091,7 @@
                      header_offset)
                     raise
                 self.fp.write(centdir)
-                self.fp.write(zinfo.filename)
+                self.fp.write(filename)
                 self.fp.write(extra_data)
                 self.fp.write(zinfo.comment)
 

Modified: python/branches/tlee-ast-optimize/Misc/NEWS
==============================================================================
--- python/branches/tlee-ast-optimize/Misc/NEWS	(original)
+++ python/branches/tlee-ast-optimize/Misc/NEWS	Wed May  7 14:56:55 2008
@@ -20,6 +20,8 @@
 - Patch #2617: Reserved -J and -X arguments for Jython, IronPython and other
   implementations of Python. 
 
+- Implemented PEP 370: Per user site-packages directory
+
 Extension Modules
 -----------------
 
@@ -42,11 +44,20 @@
   machinery in such places as the parser where use of pure Python code is not
   possible.  Both the ``showarning()`` and ``formatwarning()`` gain an
   optional 'line' argument which is not called by default for
-  backwards-compatibility reasons.
+  backwards-compatibility reasons. Setting ``warnings.showwarning()`` to
+  an implementation that lacks support for the ``line`` argument will raise a
+  DeprecationWarning.
 
 Library
 -------
 
+- The audiodev module has been deprecated for removal in Python 3.0.
+
+- Issue #2750: Add the 'json' package. Based on simplejson 1.9 and contributed
+  by Bob Ippolito.
+
+- Issue #1734346: Support Unicode file names for zipfiles.
+
 - Issue #2581: distutils: Vista UAC/elevation support for bdist_wininst
 
 - Issue #2635: Fix bug in 'fix_sentence_endings' textwrap.fill option,

Modified: python/branches/tlee-ast-optimize/Modules/main.c
==============================================================================
--- python/branches/tlee-ast-optimize/Modules/main.c	(original)
+++ python/branches/tlee-ast-optimize/Modules/main.c	Wed May  7 14:56:55 2008
@@ -40,7 +40,7 @@
 static int  orig_argc;
 
 /* command line options */
-#define BASE_OPTS "3bBc:dEhiJm:OQ:StuUvVW:xX?"
+#define BASE_OPTS "3bBc:dEhiJm:OQ:sStuUvVW:xX?"
 
 #ifndef RISCOS
 #define PROGRAM_OPTS BASE_OPTS
@@ -72,6 +72,7 @@
 -O     : optimize generated bytecode slightly; also PYTHONOPTIMIZE=x\n\
 -OO    : remove doc-strings in addition to the -O optimizations\n\
 -Q arg : division options: -Qold (default), -Qwarn, -Qwarnall, -Qnew\n\
+-s     : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
 -S     : don't imply 'import site' on initialization\n\
 -t     : issue warnings about inconsistent tab usage (-tt: issue errors)\n\
 ";
@@ -359,6 +360,10 @@
 			Py_DontWriteBytecodeFlag++;
 			break;
 
+		case 's':
+			Py_NoUserSiteDirectory++;
+			break;
+
 		case 'S':
 			Py_NoSiteFlag++;
 			break;
@@ -431,6 +436,10 @@
 	    (p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0')
 		unbuffered = 1;
 
+	if (!Py_NoUserSiteDirectory &&
+	    (p = Py_GETENV("PYTHONNOUSERSITE")) && *p != '\0')
+		Py_NoUserSiteDirectory = 1;
+
 	if (command == NULL && module == NULL && _PyOS_optind < argc &&
 	    strcmp(argv[_PyOS_optind], "-") != 0)
 	{

Modified: python/branches/tlee-ast-optimize/PC/VC6/pythoncore.dsp
==============================================================================
--- python/branches/tlee-ast-optimize/PC/VC6/pythoncore.dsp	(original)
+++ python/branches/tlee-ast-optimize/PC/VC6/pythoncore.dsp	Wed May  7 14:56:55 2008
@@ -149,6 +149,10 @@
 # End Source File
 # Begin Source File
 
+SOURCE=..\..\Modules\_json.c
+# End Source File
+# Begin Source File
+
 SOURCE=..\..\Modules\_localemodule.c
 # End Source File
 # Begin Source File

Modified: python/branches/tlee-ast-optimize/PC/VS7.1/pythoncore.vcproj
==============================================================================
--- python/branches/tlee-ast-optimize/PC/VS7.1/pythoncore.vcproj	(original)
+++ python/branches/tlee-ast-optimize/PC/VS7.1/pythoncore.vcproj	Wed May  7 14:56:55 2008
@@ -380,6 +380,9 @@
 			RelativePath="..\..\Modules\_hotshot.c">
 		</File>
 		<File
+			RelativePath="..\..\Modules\json.c">
+		</File>
+		<File
 			RelativePath="..\..\Modules\_localemodule.c">
 		</File>
 		<File

Modified: python/branches/tlee-ast-optimize/PC/VS8.0/pythoncore.vcproj
==============================================================================
--- python/branches/tlee-ast-optimize/PC/VS8.0/pythoncore.vcproj	(original)
+++ python/branches/tlee-ast-optimize/PC/VS8.0/pythoncore.vcproj	Wed May  7 14:56:55 2008
@@ -1003,6 +1003,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\Modules\_json.c"
+				>
+			</File>
+			<File
 				RelativePath="..\..\Modules\_localemodule.c"
 				>
 			</File>

Modified: python/branches/tlee-ast-optimize/PC/config.c
==============================================================================
--- python/branches/tlee-ast-optimize/PC/config.c	(original)
+++ python/branches/tlee-ast-optimize/PC/config.c	Wed May  7 14:56:55 2008
@@ -54,6 +54,7 @@
 extern void initdatetime(void);
 extern void init_fileio(void);
 extern void init_functools(void);
+extern void init_json(void);
 extern void initzlib(void);
 
 extern void init_multibytecodec(void);
@@ -132,6 +133,7 @@
 	{"datetime", initdatetime},
 	{"_fileio", init_fileio},
 	{"_functools", init_functools},
+	{"_json", init_json},
 
 	{"xxsubtype", initxxsubtype},
 	{"zipimport", initzipimport},

Modified: python/branches/tlee-ast-optimize/PCbuild/pythoncore.vcproj
==============================================================================
--- python/branches/tlee-ast-optimize/PCbuild/pythoncore.vcproj	(original)
+++ python/branches/tlee-ast-optimize/PCbuild/pythoncore.vcproj	Wed May  7 14:56:55 2008
@@ -1007,6 +1007,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\Modules\_json.c"
+				>
+			</File>
+			<File
 				RelativePath="..\Modules\_localemodule.c"
 				>
 			</File>

Modified: python/branches/tlee-ast-optimize/Python/_warnings.c
==============================================================================
--- python/branches/tlee-ast-optimize/Python/_warnings.c	(original)
+++ python/branches/tlee-ast-optimize/Python/_warnings.c	Wed May  7 14:56:55 2008
@@ -229,8 +229,8 @@
 show_warning(PyObject *filename, int lineno, PyObject *text, PyObject
                 *category, PyObject *sourceline)
 {
-    PyObject *f_stderr; 
-    PyObject *name; 
+    PyObject *f_stderr;
+    PyObject *name;
     char lineno_str[128];
 
     PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno);
@@ -272,7 +272,7 @@
 }
 
 static PyObject *
-warn_explicit(PyObject *category, PyObject *message, 
+warn_explicit(PyObject *category, PyObject *message,
               PyObject *filename, int lineno,
               PyObject *module, PyObject *registry, PyObject *sourceline)
 {
@@ -347,12 +347,12 @@
                     goto cleanup;
             }
             /* _once_registry[(text, category)] = 1 */
-            rc = update_registry(registry, text, category, 0); 
+            rc = update_registry(registry, text, category, 0);
         }
         else if (strcmp(action, "module") == 0) {
             /* registry[(text, category, 0)] = 1 */
             if (registry != NULL)
-                rc = update_registry(registry, text, category, 0); 
+                rc = update_registry(registry, text, category, 0);
         }
         else if (strcmp(action, "default") != 0) {
             PyObject *to_str = PyObject_Str(item);
@@ -378,15 +378,47 @@
             show_warning(filename, lineno, text, category, sourceline);
         }
         else {
-            PyObject *res;
-            
-            res = PyObject_CallFunctionObjArgs(show_fxn, message, category,
+            const char *msg = "functions overriding warnings.showwarning() "
+                                "must support the 'line' argument";
+            const char *text_char = PyString_AS_STRING(text);
+
+            if (strcmp(msg, text_char) == 0) {
+                /* Prevent infinite recursion by using built-in implementation
+                   of showwarning(). */
+                show_warning(filename, lineno, text, category, sourceline);
+            }
+            else {
+                PyObject *check_fxn;
+                PyObject *defaults;
+                PyObject *res;
+
+                if (PyMethod_Check(show_fxn))
+                    check_fxn = PyMethod_Function(show_fxn);
+                else if (PyFunction_Check(show_fxn))
+                    check_fxn = show_fxn;
+                else {
+                    PyErr_SetString(PyExc_TypeError,
+                                    "warnings.showwarning() must be set to a "
+                                    "function or method");
+                    Py_DECREF(show_fxn);
+                    goto cleanup;
+                }
+
+                defaults = PyFunction_GetDefaults(check_fxn);
+                /* A proper implementation of warnings.showwarning() should
+                    have at least two default arguments. */
+                if ((defaults == NULL) || (PyTuple_Size(defaults) < 2)) {
+                    if (PyErr_WarnEx(PyExc_DeprecationWarning, msg, 1) < 0)
+                        goto cleanup;
+                }
+                res = PyObject_CallFunctionObjArgs(show_fxn, message, category,
                                                     filename, lineno_obj,
                                                     NULL);
-            Py_DECREF(show_fxn);
-            Py_XDECREF(res);
-            if (res == NULL)
-                goto cleanup;
+                Py_DECREF(show_fxn);
+                Py_XDECREF(res);
+                if (res == NULL)
+                    goto cleanup;
+            }
         }
     }
     else /* if (rc == -1) */
@@ -415,10 +447,8 @@
 
     /* Setup globals and lineno. */
     PyFrameObject *f = PyThreadState_GET()->frame;
-    while (--stack_level > 0 && f != NULL) {
+    while (--stack_level > 0 && f != NULL)
         f = f->f_back;
-        --stack_level;
-    }
 
     if (f == NULL) {
         globals = PyThreadState_Get()->interp->sysdict;
@@ -578,7 +608,7 @@
     PyObject *message, *category = NULL;
     Py_ssize_t stack_level = 1;
 
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|On:warn", kw_list, 
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|On:warn", kw_list,
                                      &message, &category, &stack_level))
         return NULL;
 

Modified: python/branches/tlee-ast-optimize/Python/pythonrun.c
==============================================================================
--- python/branches/tlee-ast-optimize/Python/pythonrun.c	(original)
+++ python/branches/tlee-ast-optimize/Python/pythonrun.c	Wed May  7 14:56:55 2008
@@ -84,6 +84,7 @@
   on the command line, and is used in 2.2 by ceval.c to make all "/" divisions
   true divisions (which they will be in 2.3). */
 int _Py_QnewFlag = 0;
+int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
 
 /* PyModule_GetWarningsModule is no longer necessary as of 2.6
 since _warnings is builtin.  This API should not be used. */

Modified: python/branches/tlee-ast-optimize/Python/sysmodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Python/sysmodule.c	(original)
+++ python/branches/tlee-ast-optimize/Python/sysmodule.c	Wed May  7 14:56:55 2008
@@ -1101,7 +1101,7 @@
 		shortbranch[len] = '\0';
 	}
 	else {
-		Py_FatalError("bad HeadURL");
+		Py_FatalError("bad HeadURL"); 
 		return;
 	}
 
@@ -1158,7 +1158,7 @@
 	{"interactive",		"-i"},
 	{"optimize",		"-O or -OO"},
 	{"dont_write_bytecode",	"-B"},
-	/* {"no_user_site",	"-s"}, */
+	{"no_user_site",	"-s"},
 	{"no_site",		"-S"},
 	{"ignore_environment",	"-E"},
 	{"tabcheck",		"-t or -tt"},
@@ -1178,9 +1178,9 @@
 	flags__doc__,	/* doc */
 	flags_fields,	/* fields */
 #ifdef RISCOS
-	14
+	15
 #else
-	13
+	14
 #endif
 };
 
@@ -1205,7 +1205,7 @@
 	SetFlag(Py_InteractiveFlag);
 	SetFlag(Py_OptimizeFlag);
 	SetFlag(Py_DontWriteBytecodeFlag);
-	/* SetFlag(Py_NoUserSiteDirectory); */
+	SetFlag(Py_NoUserSiteDirectory);
 	SetFlag(Py_NoSiteFlag);
 	SetFlag(Py_IgnoreEnvironmentFlag);
 	SetFlag(Py_TabcheckFlag);

Modified: python/branches/tlee-ast-optimize/setup.py
==============================================================================
--- python/branches/tlee-ast-optimize/setup.py	(original)
+++ python/branches/tlee-ast-optimize/setup.py	Wed May  7 14:56:55 2008
@@ -438,6 +438,8 @@
         exts.append( Extension("_fileio", ["_fileio.c"]) )
         # _functools
         exts.append( Extension("_functools", ["_functoolsmodule.c"]) )
+        # _json speedups
+        exts.append( Extension("_json", ["_json.c"]) )
         # Python C API test module
         exts.append( Extension('_testcapi', ['_testcapimodule.c']) )
         # profilers (_lsprof is for cProfile.py)


More information about the Python-checkins mailing list