mirror of
https://github.com/python/cpython.git
synced 2024-11-23 18:04:37 +08:00
Branch merge
This commit is contained in:
commit
0f4ee93b06
@ -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
|
||||
|
@ -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
|
||||
======================
|
||||
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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("""\
|
||||
|
@ -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')
|
||||
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():
|
||||
|
@ -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():
|
||||
|
@ -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
|
||||
|
@ -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}
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
||||
|
@ -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())
|
||||
|
Loading…
Reference in New Issue
Block a user