summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/library/sys.rst34
-rw-r--r--Doc/whatsnew/3.3.rst20
-rw-r--r--Include/unicodeobject.h2
-rw-r--r--Lib/packaging/run.py5
-rw-r--r--Lib/packaging/tests/test_uninstall.py78
-rw-r--r--Lib/packaging/tests/test_version.py20
-rw-r--r--Lib/packaging/version.py2
-rw-r--r--Lib/sysconfig.cfg2
-rwxr-xr-xLib/test/regrtest.py24
-rw-r--r--Lib/test/support.py3
-rw-r--r--Lib/test/test_minidom.py2
-rw-r--r--Misc/NEWS2
12 files changed, 119 insertions, 75 deletions
diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst
index 43f65e2..0a8ac8b 100644
--- a/Doc/library/sys.rst
+++ b/Doc/library/sys.rst
@@ -121,6 +121,15 @@ always available.
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 @@ always available.
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 @@ always available.
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 @@ always available.
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 @@ always available.
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
index c2cf524..a3abc11 100644
--- 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 Add list of changes introduced by :pep:`393` here:
XXX mention new and deprecated functions and macros
+
Other Language Changes
======================
diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h
index 3c691c1..75dec86 100644
--- a/Include/unicodeobject.h
+++ b/Include/unicodeobject.h
@@ -206,7 +206,7 @@ extern "C" {
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
index 5affb17..59ad6ee 100644
--- a/Lib/packaging/run.py
+++ b/Lib/packaging/run.py
@@ -283,10 +283,11 @@ def _run(dispatcher, args, **kw):
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
index c7702de..8f094f4 100644
--- 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 @@ class UninstallTestCase(support.TempdirManager,
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 @@ class UninstallTestCase(support.TempdirManager,
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')
-
- def test_remove_issue(self):
+ 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_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
index f94c800..2c86111 100644
--- a/Lib/packaging/tests/test_version.py
+++ b/Lib/packaging/tests/test_version.py
@@ -101,7 +101,17 @@ class VersionTestCase(unittest.TestCase):
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 @@ class VersionTestCase(unittest.TestCase):
... < 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 @@ class VersionWhiteBoxTestCase(unittest.TestCase):
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
index 0eaf80b..7d812bb 100644
--- a/Lib/packaging/version.py
+++ b/Lib/packaging/version.py
@@ -253,7 +253,7 @@ def suggest_normalized_version(s):
# 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
index 573b12e..565c0eb 100644
--- a/Lib/sysconfig.cfg
+++ b/Lib/sysconfig.cfg
@@ -31,7 +31,7 @@ man = {datadir}/man
# 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
index e46f935..59bdb01 100755
--- a/Lib/test/regrtest.py
+++ b/Lib/test/regrtest.py
@@ -173,6 +173,7 @@ import io
import json
import logging
import os
+import packaging.database
import platform
import random
import re
@@ -967,6 +968,7 @@ class saved_test_environment:
'sys.warnoptions', 'threading._dangling',
'multiprocessing.process._dangling',
'sysconfig._CONFIG_VARS', 'sysconfig._SCHEMES',
+ 'packaging.database_caches',
)
def get_sys_argv(self):
@@ -1054,6 +1056,28 @@ class saved_test_environment:
# 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
index 619bf4c..556e82f4 100644
--- a/Lib/test/support.py
+++ b/Lib/test/support.py
@@ -187,8 +187,7 @@ def get_attribute(obj, name):
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
index 0a60136..2621f72 100644
--- a/Lib/test/test_minidom.py
+++ b/Lib/test/test_minidom.py
@@ -467,7 +467,7 @@ class MinidomTest(unittest.TestCase):
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
index 46e7f14..ef0edc3 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -1261,6 +1261,8 @@ Library
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).