[Python-checkins] cpython (merge default -> default): Branch merge

eric.araujo python-checkins at python.org
Thu Oct 6 13:24:17 CEST 2011


http://hg.python.org/cpython/rev/4001211484e1
changeset:   72745:4001211484e1
parent:      72721:3636a39fa557
parent:      72743:ab125793243f
user:        Éric Araujo <merwok at netwok.org>
date:        Thu Oct 06 13:22:21 2011 +0200
summary:
  Branch merge

files:
  Doc/library/sys.rst                   |  34 +++---
  Doc/whatsnew/3.3.rst                  |  20 +-
  Include/unicodeobject.h               |   2 +-
  Lib/packaging/run.py                  |   5 +-
  Lib/packaging/tests/test_uninstall.py |  76 ++++++++------
  Lib/packaging/tests/test_version.py   |  20 +++-
  Lib/packaging/version.py              |   2 +-
  Lib/sysconfig.cfg                     |   2 +-
  Lib/test/regrtest.py                  |  24 ++++
  Lib/test/support.py                   |   3 +-
  Lib/test/test_minidom.py              |   2 +-
  Misc/NEWS                             |   2 +
  12 files changed, 118 insertions(+), 74 deletions(-)


diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst
--- a/Doc/library/sys.rst
+++ b/Doc/library/sys.rst
@@ -121,6 +121,15 @@
       Use ``'backslashreplace'`` error handler on :exc:`UnicodeEncodeError`.
 
 
+.. data:: dont_write_bytecode
+
+   If this is true, Python won't try to write ``.pyc`` or ``.pyo`` files on the
+   import of source modules.  This value is initially set to ``True`` or
+   ``False`` depending on the :option:`-B` command line option and the
+   :envvar:`PYTHONDONTWRITEBYTECODE` environment variable, but you can set it
+   yourself to control bytecode file generation.
+
+
 .. function:: excepthook(type, value, traceback)
 
    This function prints out a given traceback and exception to ``sys.stderr``.
@@ -185,10 +194,10 @@
    Python files are installed; by default, this is also ``'/usr/local'``.  This can
    be set at build time with the ``--exec-prefix`` argument to the
    :program:`configure` script.  Specifically, all configuration files (e.g. the
-   :file:`pyconfig.h` header file) are installed in the directory ``exec_prefix +
-   '/lib/pythonversion/config'``, and shared library modules are installed in
-   ``exec_prefix + '/lib/pythonversion/lib-dynload'``, where *version* is equal to
-   ``version[:3]``.
+   :file:`pyconfig.h` header file) are installed in the directory
+   :file:`{exec_prefix}/lib/python{X.Y}/config', and shared library modules are
+   installed in :file:`{exec_prefix}/lib/python{X.Y}/lib-dynload`, where *X.Y*
+   is the version number of Python, for example ``3.2``.
 
 
 .. data:: executable
@@ -629,7 +638,7 @@
    i.e. ``1114111`` (``0x10FFFF`` in hexadecimal).
 
    .. versionchanged:: 3.3
-      Before :pep:`393`, :data:`sys.maxunicode` used to return either ``0xFFFF``
+      Before :pep:`393`, ``sys.maxunicode`` used to be either ``0xFFFF``
       or ``0x10FFFF``, depending on the configuration option that specified
       whether Unicode characters were stored as UCS-2 or UCS-4.
 
@@ -750,10 +759,10 @@
    independent Python files are installed; by default, this is the string
    ``'/usr/local'``.  This can be set at build time with the ``--prefix``
    argument to the :program:`configure` script.  The main collection of Python
-   library modules is installed in the directory ``prefix + '/lib/pythonversion'``
+   library modules is installed in the directory :file:`{prefix}/lib/python{X.Y}``
    while the platform independent header files (all except :file:`pyconfig.h`) are
-   stored in ``prefix + '/include/pythonversion'``, where *version* is equal to
-   ``version[:3]``.
+   stored in :file:`{prefix}/include/python{X.Y}``, where *X.Y* is the version
+   number of Python, for example ``3.2``.
 
 
 .. data:: ps1
@@ -771,15 +780,6 @@
    implement a dynamic prompt.
 
 
-.. data:: dont_write_bytecode
-
-   If this is true, Python won't try to write ``.pyc`` or ``.pyo`` files on the
-   import of source modules.  This value is initially set to ``True`` or ``False``
-   depending on the ``-B`` command line option and the ``PYTHONDONTWRITEBYTECODE``
-   environment variable, but you can set it yourself to control bytecode file
-   generation.
-
-
 .. function:: setcheckinterval(interval)
 
    Set the interpreter's "check interval".  This integer value determines how often
diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst
--- a/Doc/whatsnew/3.3.rst
+++ b/Doc/whatsnew/3.3.rst
@@ -6,8 +6,7 @@
 :Release: |release|
 :Date: |today|
 
-.. $Id$
-   Rules for maintenance:
+.. Rules for maintenance:
 
    * Anyone can add text to this document.  Do not spend very much time
    on the wording of your changes, because your text will probably
@@ -40,25 +39,25 @@
 
    * It's helpful to add the bug/patch number as a comment:
 
-   % Patch 12345
    XXX Describe the transmogrify() function added to the socket
    module.
-   (Contributed by P.Y. Developer.)
+   (Contributed by P.Y. Developer in :issue:`12345`.)
 
-   This saves the maintainer the effort of going through the SVN log
+   This saves the maintainer the effort of going through the Mercurial log
    when researching a change.
 
 This article explains the new features in Python 3.3, compared to 3.2.
 
 
-PEP XXX: Stub
-=============
-
-
 PEP 393: Flexible String Representation
 =======================================
 
-XXX Give a short introduction about :pep:`393`.
+[Abstract copied from the PEP: The Unicode string type is changed to support
+multiple internal representations, depending on the character with the largest
+Unicode ordinal (1, 2, or 4 bytes).  This allows a space-efficient
+representation in common cases, but gives access to full UCS-4 on all systems.
+For compatibility with existing APIs, several representations may exist in
+parallel; over time, this compatibility should be phased out.]
 
 PEP 393 is fully backward compatible. The legacy API should remain
 available at least five years. Applications using the legacy API will not
@@ -109,6 +108,7 @@
 
 XXX mention new and deprecated functions and macros
 
+
 Other Language Changes
 ======================
 
diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h
--- a/Include/unicodeobject.h
+++ b/Include/unicodeobject.h
@@ -206,7 +206,7 @@
    immediately follow the structure. utf8_length and wstr_length can be found
    in the length field; the utf8 pointer is equal to the data pointer. */
 typedef struct {
-    /* There a 4 forms of Unicode strings:
+    /* There are 4 forms of Unicode strings:
 
        - compact ascii:
 
diff --git a/Lib/packaging/run.py b/Lib/packaging/run.py
--- a/Lib/packaging/run.py
+++ b/Lib/packaging/run.py
@@ -283,10 +283,11 @@
     dist.parse_config_files()
 
     for cmd in dispatcher.commands:
+        # FIXME need to catch MetadataMissingError here (from the check command
+        # e.g.)--or catch any exception, print an error message and exit with 1
         dist.run_command(cmd, dispatcher.command_options[cmd])
 
-    # XXX this is crappy
-    return dist
+    return 0
 
 
 @action_help("""\
diff --git a/Lib/packaging/tests/test_uninstall.py b/Lib/packaging/tests/test_uninstall.py
--- a/Lib/packaging/tests/test_uninstall.py
+++ b/Lib/packaging/tests/test_uninstall.py
@@ -1,15 +1,12 @@
-"""Tests for the uninstall command."""
+"""Tests for the packaging.uninstall module."""
 import os
 import sys
-from io import StringIO
-import stat
+import logging
 import packaging.util
 
-from packaging.database import disable_cache, enable_cache
-from packaging.run import main
 from packaging.errors import PackagingError
 from packaging.install import remove
-from packaging.command.install_dist import install_dist
+from packaging.database import disable_cache, enable_cache
 
 from packaging.tests import unittest, support
 
@@ -47,16 +44,12 @@
         packaging.util._path_created.clear()
         super(UninstallTestCase, self).tearDown()
 
-    def run_setup(self, *args):
-        # run setup with args
-        args = ['run'] + list(args)
-        dist = main(args)
-        return dist
-
     def get_path(self, dist, name):
-        cmd = install_dist(dist)
-        cmd.prefix = self.root_dir
-        cmd.finalize_options()
+        # the dist argument must contain an install_dist command correctly
+        # initialized with a prefix option and finalized befored this method
+        # can be called successfully; practically, this means that you should
+        # call self.install_dist before self.get_path
+        cmd = dist.get_command_obj('install_dist')
         return getattr(cmd, 'install_' + name)
 
     def make_dist(self, name='Foo', **kw):
@@ -83,43 +76,56 @@
         if not dirname:
             dirname = self.make_dist(name, **kw)
         os.chdir(dirname)
-        old_out = sys.stderr
-        sys.stderr = StringIO()
-        dist = self.run_setup('install_dist', '--prefix=' + self.root_dir)
-        install_lib = self.get_path(dist, 'purelib')
-        return dist, install_lib
 
-    def test_uninstall_unknow_distribution(self):
+        dist = support.TestDistribution()
+        # for some unfathomable reason, the tests will fail horribly if the
+        # parse_config_files method is not called, even if it doesn't do
+        # anything useful; trying to build and use a command object manually
+        # also fails
+        dist.parse_config_files()
+        dist.finalize_options()
+        dist.run_command('install_dist',
+                         {'prefix': ('command line', self.root_dir)})
+
+        site_packages = self.get_path(dist, 'purelib')
+        return dist, site_packages
+
+    def test_uninstall_unknown_distribution(self):
+        dist, site_packages = self.install_dist('Foospam')
         self.assertRaises(PackagingError, remove, 'Foo',
-                          paths=[self.root_dir])
+                          paths=[site_packages])
 
     def test_uninstall(self):
-        dist, install_lib = self.install_dist()
-        self.assertIsFile(install_lib, 'foo', '__init__.py')
-        self.assertIsFile(install_lib, 'foo', 'sub', '__init__.py')
-        self.assertIsFile(install_lib, 'Foo-0.1.dist-info', 'RECORD')
-        self.assertTrue(remove('Foo', paths=[install_lib]))
-        self.assertIsNotFile(install_lib, 'foo', 'sub', '__init__.py')
-        self.assertIsNotFile(install_lib, 'Foo-0.1.dist-info', 'RECORD')
+        dist, site_packages = self.install_dist()
+        self.assertIsFile(site_packages, 'foo', '__init__.py')
+        self.assertIsFile(site_packages, 'foo', 'sub', '__init__.py')
+        self.assertIsFile(site_packages, 'Foo-0.1.dist-info', 'RECORD')
+        self.assertTrue(remove('Foo', paths=[site_packages]))
+        self.assertIsNotFile(site_packages, 'foo', 'sub', '__init__.py')
+        self.assertIsNotFile(site_packages, 'Foo-0.1.dist-info', 'RECORD')
 
-    def test_remove_issue(self):
+    def test_uninstall_error_handling(self):
         # makes sure if there are OSErrors (like permission denied)
-        # remove() stops and display a clean error
-        dist, install_lib = self.install_dist('Meh')
+        # remove() stops and displays a clean error
+        dist, site_packages = self.install_dist('Meh')
 
         # breaking os.rename
         old = os.rename
 
         def _rename(source, target):
-            raise OSError
+            raise OSError(42, 'impossible operation')
 
         os.rename = _rename
         try:
-            self.assertFalse(remove('Meh', paths=[install_lib]))
+            self.assertFalse(remove('Meh', paths=[site_packages]))
         finally:
             os.rename = old
 
-        self.assertTrue(remove('Meh', paths=[install_lib]))
+        logs = [log for log in self.get_logs(logging.INFO)
+                if log.startswith('Error:')]
+        self.assertEqual(logs, ['Error: [Errno 42] impossible operation'])
+
+        self.assertTrue(remove('Meh', paths=[site_packages]))
 
 
 def test_suite():
diff --git a/Lib/packaging/tests/test_version.py b/Lib/packaging/tests/test_version.py
--- a/Lib/packaging/tests/test_version.py
+++ b/Lib/packaging/tests/test_version.py
@@ -101,7 +101,17 @@
         True
         >>> V('1.2.0') >= V('1.2.3')
         False
-        >>> (V('1.0') > V('1.0b2'))
+        >>> V('1.2.0rc1') >= V('1.2.0')
+        False
+        >>> V('1.0') > V('1.0b2')
+        True
+        >>> V('1.0') > V('1.0c2')
+        True
+        >>> V('1.0') > V('1.0rc2')
+        True
+        >>> V('1.0rc2') > V('1.0rc1')
+        True
+        >>> V('1.0c4') > V('1.0c1')
         True
         >>> (V('1.0') > V('1.0c2') > V('1.0c1') > V('1.0b2') > V('1.0b1')
         ...  > V('1.0a2') > V('1.0a1'))
@@ -129,6 +139,8 @@
         ...  < V('1.0.dev18')
         ...  < V('1.0.dev456')
         ...  < V('1.0.dev1234')
+        ...  < V('1.0rc1')
+        ...  < V('1.0rc2')
         ...  < V('1.0')
         ...  < V('1.0.post456.dev623')  # development version of a post release
         ...  < V('1.0.post456'))
@@ -236,9 +248,9 @@
     def test_parse_numdots(self):
         # For code coverage completeness, as pad_zeros_length can't be set or
         # influenced from the public interface
-        self.assertEqual(V('1.0')._parse_numdots('1.0', '1.0',
-                                                  pad_zeros_length=3),
-                          [1, 0, 0])
+        self.assertEqual(
+            V('1.0')._parse_numdots('1.0', '1.0', pad_zeros_length=3),
+            [1, 0, 0])
 
 
 def test_suite():
diff --git a/Lib/packaging/version.py b/Lib/packaging/version.py
--- a/Lib/packaging/version.py
+++ b/Lib/packaging/version.py
@@ -253,7 +253,7 @@
     # if we have something like "b-2" or "a.2" at the end of the
     # version, that is pobably beta, alpha, etc
     # let's remove the dash or dot
-    rs = re.sub(r"([abc|rc])[\-\.](\d+)$", r"\1\2", rs)
+    rs = re.sub(r"([abc]|rc)[\-\.](\d+)$", r"\1\2", rs)
 
     # 1.0-dev-r371 -> 1.0.dev371
     # 0.1-dev-r79 -> 0.1.dev79
diff --git a/Lib/sysconfig.cfg b/Lib/sysconfig.cfg
--- a/Lib/sysconfig.cfg
+++ b/Lib/sysconfig.cfg
@@ -31,7 +31,7 @@
 # be used directly in [resource_locations].
 confdir = /etc
 datadir = /usr/share
-libdir = /usr/lib  ; or /usr/lib64 on a multilib system
+libdir = /usr/lib
 statedir = /var
 # User resource directory
 local = ~/.local/{distribution.name}
diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py
--- a/Lib/test/regrtest.py
+++ b/Lib/test/regrtest.py
@@ -173,6 +173,7 @@
 import json
 import logging
 import os
+import packaging.database
 import platform
 import random
 import re
@@ -967,6 +968,7 @@
                  'sys.warnoptions', 'threading._dangling',
                  'multiprocessing.process._dangling',
                  'sysconfig._CONFIG_VARS', 'sysconfig._SCHEMES',
+                 'packaging.database_caches',
                 )
 
     def get_sys_argv(self):
@@ -1054,6 +1056,28 @@
         # Can't easily revert the logging state
         pass
 
+    def get_packaging_database_caches(self):
+        # caching system used by the PEP 376 implementation
+        # we have one boolean and four dictionaries, initially empty
+        switch = packaging.database._cache_enabled
+        saved = []
+        for name in ('_cache_name', '_cache_name_egg',
+                     '_cache_path', '_cache_path_egg'):
+            cache = getattr(packaging.database, name)
+            saved.append((id(cache), cache, cache.copy()))
+        return switch, saved
+    def restore_packaging_database_caches(self, saved):
+        switch, saved_caches = saved
+        packaging.database._cache_enabled = switch
+        for offset, name in enumerate(('_cache_name', '_cache_name_egg',
+                                       '_cache_path', '_cache_path_egg')):
+            _, cache, items = saved_caches[offset]
+            # put back the same object in place
+            setattr(packaging.database, name, cache)
+            # now restore its items
+            cache.clear()
+            cache.update(items)
+
     def get_sys_warnoptions(self):
         return id(sys.warnoptions), sys.warnoptions, sys.warnoptions[:]
     def restore_sys_warnoptions(self, saved_options):
diff --git a/Lib/test/support.py b/Lib/test/support.py
--- a/Lib/test/support.py
+++ b/Lib/test/support.py
@@ -187,8 +187,7 @@
     try:
         attribute = getattr(obj, name)
     except AttributeError:
-        raise unittest.SkipTest("module %s has no attribute %s" % (
-            repr(obj), name))
+        raise unittest.SkipTest("object %r has no attribute %r" % (obj, name))
     else:
         return attribute
 
diff --git a/Lib/test/test_minidom.py b/Lib/test/test_minidom.py
--- a/Lib/test/test_minidom.py
+++ b/Lib/test/test_minidom.py
@@ -467,7 +467,7 @@
         dom.unlink()
         self.confirm(domstr == str.replace("\n", "\r\n"))
 
-    def test_toPrettyXML_perserves_content_of_text_node(self):
+    def test_toprettyxml_preserves_content_of_text_node(self):
         str = '<A>B</A>'
         dom = parseString(str)
         dom2 = parseString(dom.toprettyxml())
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -1261,6 +1261,8 @@
 Build
 -----
 
+- PEP 393: the configure option --with-wide-unicode is removed.
+
 - Issue #12852: Set _XOPEN_SOURCE to 700, instead of 600, to get POSIX 2008
   functions on OpenBSD (e.g. fdopendir).
 

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list