merge
This commit is contained in:
commit
5c9a5895d4
|
@ -484,10 +484,10 @@ functions.
|
|||
.. versionadded:: 3.2
|
||||
The *pass_fds* parameter was added.
|
||||
|
||||
If *cwd* is not ``None``, the child's current directory will be changed to *cwd*
|
||||
before it is executed. Note that this directory is not considered when
|
||||
searching the executable, so you can't specify the program's path relative to
|
||||
*cwd*.
|
||||
If *cwd* is not ``None``, the function changes the working directory to
|
||||
*cwd* before executing the child. In particular, the function looks for
|
||||
*executable* (or for the first item in *args*) relative to *cwd* if the
|
||||
executable path is a relative path.
|
||||
|
||||
If *restore_signals* is True (the default) all signals that Python has set to
|
||||
SIG_IGN are restored to SIG_DFL in the child process before the exec.
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<h3>Docs for other versions</h3>
|
||||
<ul>
|
||||
<li><a href="http://docs.python.org/2.7/">Python 2.7 (stable)</a></li>
|
||||
<li><a href="http://docs.python.org/3.2/">Python 3.2 (stable)</a></li>
|
||||
<li><a href="http://docs.python.org/3.4/">Python 3.4 (in development)</a></li>
|
||||
<li><a href="http://www.python.org/doc/versions/">Old versions</a></li>
|
||||
</ul>
|
||||
|
||||
|
|
|
@ -8,6 +8,23 @@
|
|||
{% block extrahead %}
|
||||
<link rel="shortcut icon" type="image/png" href="{{ pathto('_static/py.png', 1) }}" />
|
||||
{% if not embedded %}<script type="text/javascript" src="{{ pathto('_static/copybutton.js', 1) }}"></script>{% endif %}
|
||||
{% if pagename == 'whatsnew/news' %}
|
||||
<script type="text/javascript">
|
||||
function dofilter() {
|
||||
var el = document.getElementById('searchbox');
|
||||
var string = el.value.toLowerCase();
|
||||
var litags = document.getElementsByTagName('li')
|
||||
for (var idx = 0; idx < litags.length; idx++) {
|
||||
var li = litags[idx];
|
||||
if (li.innerHTML.toLowerCase().indexOf(string) >= 0) {
|
||||
li.style.display = '';
|
||||
} else {
|
||||
li.style.display = 'none';
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{% endif %}
|
||||
{{ super() }}
|
||||
{% endblock %}
|
||||
{% block footer %}
|
||||
|
|
|
@ -145,6 +145,45 @@ class DeprecatedRemoved(Directive):
|
|||
return ret
|
||||
|
||||
|
||||
# Support for including Misc/NEWS
|
||||
|
||||
import re
|
||||
import codecs
|
||||
from docutils.statemachine import string2lines
|
||||
from sphinx.util.nodes import nested_parse_with_titles
|
||||
|
||||
issue_re = re.compile('Issue #([0-9]+)')
|
||||
|
||||
class MiscNews(Directive):
|
||||
has_content = False
|
||||
required_arguments = 1
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = False
|
||||
option_spec = {}
|
||||
|
||||
def run(self):
|
||||
fname = self.arguments[0]
|
||||
source = self.state_machine.input_lines.source(
|
||||
self.lineno - self.state_machine.input_offset - 1)
|
||||
source_dir = path.dirname(path.abspath(source))
|
||||
try:
|
||||
fp = codecs.open(path.join(source_dir, fname), encoding='utf-8')
|
||||
try:
|
||||
content = fp.read()
|
||||
finally:
|
||||
fp.close()
|
||||
except Exception:
|
||||
text = 'The NEWS file is not available.'
|
||||
node = nodes.strong(text, text)
|
||||
return [node]
|
||||
content = issue_re.sub(r'`Issue #\1 <http://bugs.python.org/\1>`__',
|
||||
content)
|
||||
# remove first 3 lines as they are the main heading
|
||||
lines = content.splitlines()[3:]
|
||||
self.state_machine.insert_input(lines, fname)
|
||||
return []
|
||||
|
||||
|
||||
# Support for building "topic help" for pydoc
|
||||
|
||||
pydoc_topic_labels = [
|
||||
|
@ -276,3 +315,4 @@ def setup(app):
|
|||
app.add_description_unit('2to3fixer', '2to3fixer', '%s (2to3 fixer)')
|
||||
app.add_directive_to_domain('py', 'decorator', PyDecoratorFunction)
|
||||
app.add_directive_to_domain('py', 'decoratormethod', PyDecoratorMethod)
|
||||
app.add_directive('miscnews', MiscNews)
|
||||
|
|
|
@ -132,6 +132,8 @@ Consult :command:`set /?` for details on this behaviour.
|
|||
Setting Environment variables, Louis J. Farrugia
|
||||
|
||||
|
||||
.. _windows-path-mod:
|
||||
|
||||
Finding the Python executable
|
||||
-----------------------------
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ see the :source:`Misc/NEWS` file.
|
|||
|
||||
.. seealso::
|
||||
|
||||
:pep:`398` - Python 3.2 Release Schedule
|
||||
:pep:`398` - Python 3.3 Release Schedule
|
||||
|
||||
|
||||
Summary -- Release highlights
|
||||
|
@ -289,6 +289,43 @@ details).
|
|||
and Martin von Löwis.
|
||||
|
||||
|
||||
.. _pep-397:
|
||||
|
||||
PEP 397: Python Launcher for Windows
|
||||
====================================
|
||||
|
||||
The Python 3.3 Windows installer now includes a ``py`` launcher application
|
||||
that can be used to launch Python applications in a version independent
|
||||
fashion.
|
||||
|
||||
This launcher is invoked implicitly when double-clicking ``*.py`` files.
|
||||
If only a single Python version is installed on the system, that version
|
||||
will be used to run the file. If multiple versions are installed, the most
|
||||
recent version is used by default, but this can be overridden by including
|
||||
a Unix-style "shebang line" in the Python script.
|
||||
|
||||
The launcher can also be used explicitly from the command line as the ``py``
|
||||
application. Running ``py`` follows the same version selection rules as
|
||||
implicitly launching scripts, but a more specific version can be selected
|
||||
by passing appropriate arguments (such as ``-3`` to request Python 3 when
|
||||
Python 2 is also installed, or ``-2.6`` to specifclly request an earlier
|
||||
Python version when a more recent version is installed).
|
||||
|
||||
In addition to the launcher, the Windows installer now includes an
|
||||
option to add the newly installed Python to the system PATH (contributed
|
||||
by Brian Curtain in :issue:`3561`).
|
||||
|
||||
.. seealso::
|
||||
|
||||
:pep:`397` - Python Launcher for Windows
|
||||
PEP written by Mark Hammond and Martin v. Löwis; implementation by
|
||||
Vinay Sajip.
|
||||
|
||||
Launcher documentation: :ref:`launcher`
|
||||
|
||||
Installer PATH modification: :ref:`windows-path-mod`
|
||||
|
||||
|
||||
.. _pep-3151:
|
||||
|
||||
PEP 3151: Reworking the OS and IO exception hierarchy
|
||||
|
@ -2102,6 +2139,22 @@ Porting Python code
|
|||
special case the standard import hooks so they are still supported even
|
||||
though they do not provide the non-standard ``iter_modules()`` method.
|
||||
|
||||
* A longstanding RFC-compliance bug (:issue:`1079`) in the parsing done by
|
||||
:func:`email.header.decode_header` has been fixed. Code that uses the
|
||||
standard idiom to convert encoded headers into unicode
|
||||
(``str(make_header(decode_header(h))``) will see no change, but code that
|
||||
looks at the individual tuples returned by decode_header will see that
|
||||
whitespace that precedes or follows ``ASCII`` sections is now included in the
|
||||
``ASCII`` section. Code that builds headers using ``make_header`` should
|
||||
also continue to work without change, since ``make_header`` continues to add
|
||||
whitespace between ``ASCII`` and non-``ASCII`` sections if it is not already
|
||||
present in the input strings.
|
||||
|
||||
* :func:`email.utils.formataddr` now does the correct content transfer
|
||||
encoding when passed non-``ASCII`` display names. Any code that depended on
|
||||
the previous buggy behavior that preserved the non-``ASCII`` unicode in the
|
||||
formatted output string will need to be changed.
|
||||
|
||||
|
||||
Porting C code
|
||||
--------------
|
||||
|
|
|
@ -23,3 +23,11 @@ anyone wishing to stay up-to-date after a new release.
|
|||
2.2.rst
|
||||
2.1.rst
|
||||
2.0.rst
|
||||
|
||||
The "Python News" is a HTML version of the file :source:`Misc/NEWS` which
|
||||
contains *all* nontrivial changes to Python.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
news.rst
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
+++++++++++
|
||||
Python News
|
||||
+++++++++++
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<p>
|
||||
Filter entries by content:
|
||||
<input type="text" value="" id="searchbox" style="width: 50%" onchange="dofilter()">
|
||||
<input type="submit" value="Filter" onclick="dofilter()">
|
||||
</p>
|
||||
|
||||
.. miscnews:: ../../Misc/NEWS
|
||||
|
81
Lib/bz2.py
81
Lib/bz2.py
|
@ -79,7 +79,8 @@ class BZ2File(io.BufferedIOBase):
|
|||
mode = "rb"
|
||||
mode_code = _MODE_READ
|
||||
self._decompressor = BZ2Decompressor()
|
||||
self._buffer = None
|
||||
self._buffer = b""
|
||||
self._buffer_offset = 0
|
||||
elif mode in ("w", "wb"):
|
||||
mode = "wb"
|
||||
mode_code = _MODE_WRITE
|
||||
|
@ -124,7 +125,8 @@ class BZ2File(io.BufferedIOBase):
|
|||
self._fp = None
|
||||
self._closefp = False
|
||||
self._mode = _MODE_CLOSED
|
||||
self._buffer = None
|
||||
self._buffer = b""
|
||||
self._buffer_offset = 0
|
||||
|
||||
@property
|
||||
def closed(self):
|
||||
|
@ -174,16 +176,13 @@ class BZ2File(io.BufferedIOBase):
|
|||
|
||||
# Fill the readahead buffer if it is empty. Returns False on EOF.
|
||||
def _fill_buffer(self):
|
||||
if self._mode == _MODE_READ_EOF:
|
||||
return False
|
||||
# Depending on the input data, our call to the decompressor may not
|
||||
# return any data. In this case, try again after reading another block.
|
||||
while True:
|
||||
if self._buffer:
|
||||
return True
|
||||
|
||||
if self._decompressor.unused_data:
|
||||
rawblock = self._decompressor.unused_data
|
||||
else:
|
||||
rawblock = self._fp.read(_BUFFER_SIZE)
|
||||
while self._buffer_offset == len(self._buffer):
|
||||
rawblock = (self._decompressor.unused_data or
|
||||
self._fp.read(_BUFFER_SIZE))
|
||||
|
||||
if not rawblock:
|
||||
if self._decompressor.eof:
|
||||
|
@ -199,30 +198,48 @@ class BZ2File(io.BufferedIOBase):
|
|||
self._decompressor = BZ2Decompressor()
|
||||
|
||||
self._buffer = self._decompressor.decompress(rawblock)
|
||||
self._buffer_offset = 0
|
||||
return True
|
||||
|
||||
# Read data until EOF.
|
||||
# If return_data is false, consume the data without returning it.
|
||||
def _read_all(self, return_data=True):
|
||||
# The loop assumes that _buffer_offset is 0. Ensure that this is true.
|
||||
self._buffer = self._buffer[self._buffer_offset:]
|
||||
self._buffer_offset = 0
|
||||
|
||||
blocks = []
|
||||
while self._fill_buffer():
|
||||
if return_data:
|
||||
blocks.append(self._buffer)
|
||||
self._pos += len(self._buffer)
|
||||
self._buffer = None
|
||||
self._buffer = b""
|
||||
if return_data:
|
||||
return b"".join(blocks)
|
||||
|
||||
# Read a block of up to n bytes.
|
||||
# If return_data is false, consume the data without returning it.
|
||||
def _read_block(self, n, return_data=True):
|
||||
# If we have enough data buffered, return immediately.
|
||||
end = self._buffer_offset + n
|
||||
if end <= len(self._buffer):
|
||||
data = self._buffer[self._buffer_offset : end]
|
||||
self._buffer_offset = end
|
||||
self._pos += len(data)
|
||||
return data if return_data else None
|
||||
|
||||
# The loop assumes that _buffer_offset is 0. Ensure that this is true.
|
||||
self._buffer = self._buffer[self._buffer_offset:]
|
||||
self._buffer_offset = 0
|
||||
|
||||
blocks = []
|
||||
while n > 0 and self._fill_buffer():
|
||||
if n < len(self._buffer):
|
||||
data = self._buffer[:n]
|
||||
self._buffer = self._buffer[n:]
|
||||
self._buffer_offset = n
|
||||
else:
|
||||
data = self._buffer
|
||||
self._buffer = None
|
||||
self._buffer = b""
|
||||
if return_data:
|
||||
blocks.append(data)
|
||||
self._pos += len(data)
|
||||
|
@ -238,9 +255,9 @@ class BZ2File(io.BufferedIOBase):
|
|||
"""
|
||||
with self._lock:
|
||||
self._check_can_read()
|
||||
if self._mode == _MODE_READ_EOF or not self._fill_buffer():
|
||||
if not self._fill_buffer():
|
||||
return b""
|
||||
return self._buffer
|
||||
return self._buffer[self._buffer_offset:]
|
||||
|
||||
def read(self, size=-1):
|
||||
"""Read up to size uncompressed bytes from the file.
|
||||
|
@ -250,7 +267,7 @@ class BZ2File(io.BufferedIOBase):
|
|||
"""
|
||||
with self._lock:
|
||||
self._check_can_read()
|
||||
if self._mode == _MODE_READ_EOF or size == 0:
|
||||
if size == 0:
|
||||
return b""
|
||||
elif size < 0:
|
||||
return self._read_all()
|
||||
|
@ -268,15 +285,19 @@ class BZ2File(io.BufferedIOBase):
|
|||
# In this case we make multiple reads, to avoid returning b"".
|
||||
with self._lock:
|
||||
self._check_can_read()
|
||||
if (size == 0 or self._mode == _MODE_READ_EOF or
|
||||
not self._fill_buffer()):
|
||||
if (size == 0 or
|
||||
# Only call _fill_buffer() if the buffer is actually empty.
|
||||
# This gives a significant speedup if *size* is small.
|
||||
(self._buffer_offset == len(self._buffer) and not self._fill_buffer())):
|
||||
return b""
|
||||
if 0 < size < len(self._buffer):
|
||||
data = self._buffer[:size]
|
||||
self._buffer = self._buffer[size:]
|
||||
if size > 0:
|
||||
data = self._buffer[self._buffer_offset :
|
||||
self._buffer_offset + size]
|
||||
self._buffer_offset += len(data)
|
||||
else:
|
||||
data = self._buffer
|
||||
self._buffer = None
|
||||
data = self._buffer[self._buffer_offset:]
|
||||
self._buffer = b""
|
||||
self._buffer_offset = 0
|
||||
self._pos += len(data)
|
||||
return data
|
||||
|
||||
|
@ -299,6 +320,14 @@ class BZ2File(io.BufferedIOBase):
|
|||
raise TypeError("Integer argument expected")
|
||||
size = size.__index__()
|
||||
with self._lock:
|
||||
# Shortcut for the common case - the whole line is in the buffer.
|
||||
if size < 0:
|
||||
end = self._buffer.find(b"\n", self._buffer_offset) + 1
|
||||
if end > 0:
|
||||
line = self._buffer[self._buffer_offset : end]
|
||||
self._buffer_offset = end
|
||||
self._pos += len(line)
|
||||
return line
|
||||
return io.BufferedIOBase.readline(self, size)
|
||||
|
||||
def readlines(self, size=-1):
|
||||
|
@ -345,7 +374,8 @@ class BZ2File(io.BufferedIOBase):
|
|||
self._mode = _MODE_READ
|
||||
self._pos = 0
|
||||
self._decompressor = BZ2Decompressor()
|
||||
self._buffer = None
|
||||
self._buffer = b""
|
||||
self._buffer_offset = 0
|
||||
|
||||
def seek(self, offset, whence=0):
|
||||
"""Change the file position.
|
||||
|
@ -385,8 +415,7 @@ class BZ2File(io.BufferedIOBase):
|
|||
offset -= self._pos
|
||||
|
||||
# Read and discard data until we reach the desired position.
|
||||
if self._mode != _MODE_READ_EOF:
|
||||
self._read_block(offset, return_data=False)
|
||||
self._read_block(offset, return_data=False)
|
||||
|
||||
return self._pos
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import unittest
|
||||
from test import script_helper
|
||||
from test import support
|
||||
import subprocess
|
||||
import sys
|
||||
|
@ -191,15 +192,101 @@ class ProcessTestCase(BaseTestCase):
|
|||
p.wait()
|
||||
self.assertEqual(p.stderr, None)
|
||||
|
||||
# For use in the test_cwd* tests below.
|
||||
def _normalize_cwd(self, cwd):
|
||||
# Normalize an expected cwd (for Tru64 support).
|
||||
# We can't use os.path.realpath since it doesn't expand Tru64 {memb}
|
||||
# strings. See bug #1063571.
|
||||
original_cwd = os.getcwd()
|
||||
os.chdir(cwd)
|
||||
cwd = os.getcwd()
|
||||
os.chdir(original_cwd)
|
||||
return cwd
|
||||
|
||||
# For use in the test_cwd* tests below.
|
||||
def _split_python_path(self):
|
||||
# Return normalized (python_dir, python_base).
|
||||
python_path = os.path.realpath(sys.executable)
|
||||
return os.path.split(python_path)
|
||||
|
||||
# For use in the test_cwd* tests below.
|
||||
def _assert_cwd(self, expected_cwd, python_arg, **kwargs):
|
||||
# Invoke Python via Popen, and assert that (1) the call succeeds,
|
||||
# and that (2) the current working directory of the child process
|
||||
# matches *expected_cwd*.
|
||||
p = subprocess.Popen([python_arg, "-c",
|
||||
"import os, sys; "
|
||||
"sys.stdout.write(os.getcwd()); "
|
||||
"sys.exit(47)"],
|
||||
stdout=subprocess.PIPE,
|
||||
**kwargs)
|
||||
self.addCleanup(p.stdout.close)
|
||||
p.wait()
|
||||
self.assertEqual(47, p.returncode)
|
||||
normcase = os.path.normcase
|
||||
self.assertEqual(normcase(expected_cwd),
|
||||
normcase(p.stdout.read().decode("utf-8")))
|
||||
|
||||
def test_cwd(self):
|
||||
# Check that cwd changes the cwd for the child process.
|
||||
temp_dir = tempfile.gettempdir()
|
||||
temp_dir = self._normalize_cwd(temp_dir)
|
||||
self._assert_cwd(temp_dir, sys.executable, cwd=temp_dir)
|
||||
|
||||
def test_cwd_with_relative_arg(self):
|
||||
# Check that Popen looks for args[0] relative to cwd if args[0]
|
||||
# is relative.
|
||||
python_dir, python_base = self._split_python_path()
|
||||
rel_python = os.path.join(os.curdir, python_base)
|
||||
with support.temp_cwd() as wrong_dir:
|
||||
# Before calling with the correct cwd, confirm that the call fails
|
||||
# without cwd and with the wrong cwd.
|
||||
self.assertRaises(FileNotFoundError, subprocess.Popen,
|
||||
[rel_python])
|
||||
self.assertRaises(FileNotFoundError, subprocess.Popen,
|
||||
[rel_python], cwd=wrong_dir)
|
||||
python_dir = self._normalize_cwd(python_dir)
|
||||
self._assert_cwd(python_dir, rel_python, cwd=python_dir)
|
||||
|
||||
def test_cwd_with_relative_executable(self):
|
||||
# Check that Popen looks for executable relative to cwd if executable
|
||||
# is relative (and that executable takes precedence over args[0]).
|
||||
python_dir, python_base = self._split_python_path()
|
||||
rel_python = os.path.join(os.curdir, python_base)
|
||||
doesntexist = "somethingyoudonthave"
|
||||
with support.temp_cwd() as wrong_dir:
|
||||
# Before calling with the correct cwd, confirm that the call fails
|
||||
# without cwd and with the wrong cwd.
|
||||
self.assertRaises(FileNotFoundError, subprocess.Popen,
|
||||
[doesntexist], executable=rel_python)
|
||||
self.assertRaises(FileNotFoundError, subprocess.Popen,
|
||||
[doesntexist], executable=rel_python,
|
||||
cwd=wrong_dir)
|
||||
python_dir = self._normalize_cwd(python_dir)
|
||||
self._assert_cwd(python_dir, doesntexist, executable=rel_python,
|
||||
cwd=python_dir)
|
||||
|
||||
def test_cwd_with_absolute_arg(self):
|
||||
# Check that Popen can find the executable when the cwd is wrong
|
||||
# if args[0] is an absolute path.
|
||||
python_dir, python_base = self._split_python_path()
|
||||
abs_python = os.path.join(python_dir, python_base)
|
||||
rel_python = os.path.join(os.curdir, python_base)
|
||||
with script_helper.temp_dir() as wrong_dir:
|
||||
# Before calling with an absolute path, confirm that using a
|
||||
# relative path fails.
|
||||
self.assertRaises(FileNotFoundError, subprocess.Popen,
|
||||
[rel_python], cwd=wrong_dir)
|
||||
wrong_dir = self._normalize_cwd(wrong_dir)
|
||||
self._assert_cwd(wrong_dir, abs_python, cwd=wrong_dir)
|
||||
|
||||
@unittest.skipIf(sys.base_prefix != sys.prefix,
|
||||
'Test is not venv-compatible')
|
||||
def test_executable_with_cwd(self):
|
||||
python_dir = os.path.dirname(os.path.realpath(sys.executable))
|
||||
p = subprocess.Popen(["somethingyoudonthave", "-c",
|
||||
"import sys; sys.exit(47)"],
|
||||
executable=sys.executable, cwd=python_dir)
|
||||
p.wait()
|
||||
self.assertEqual(p.returncode, 47)
|
||||
python_dir, python_base = self._split_python_path()
|
||||
python_dir = self._normalize_cwd(python_dir)
|
||||
self._assert_cwd(python_dir, "somethingyoudonthave",
|
||||
executable=sys.executable, cwd=python_dir)
|
||||
|
||||
@unittest.skipIf(sys.base_prefix != sys.prefix,
|
||||
'Test is not venv-compatible')
|
||||
|
@ -208,11 +295,7 @@ class ProcessTestCase(BaseTestCase):
|
|||
def test_executable_without_cwd(self):
|
||||
# For a normal installation, it should work without 'cwd'
|
||||
# argument. For test runs in the build directory, see #7774.
|
||||
p = subprocess.Popen(["somethingyoudonthave", "-c",
|
||||
"import sys; sys.exit(47)"],
|
||||
executable=sys.executable)
|
||||
p.wait()
|
||||
self.assertEqual(p.returncode, 47)
|
||||
self._assert_cwd('', "somethingyoudonthave", executable=sys.executable)
|
||||
|
||||
def test_stdin_pipe(self):
|
||||
# stdin redirection
|
||||
|
@ -369,24 +452,6 @@ class ProcessTestCase(BaseTestCase):
|
|||
p.wait()
|
||||
self.assertEqual(p.stdin, None)
|
||||
|
||||
def test_cwd(self):
|
||||
tmpdir = tempfile.gettempdir()
|
||||
# We cannot use os.path.realpath to canonicalize the path,
|
||||
# since it doesn't expand Tru64 {memb} strings. See bug 1063571.
|
||||
cwd = os.getcwd()
|
||||
os.chdir(tmpdir)
|
||||
tmpdir = os.getcwd()
|
||||
os.chdir(cwd)
|
||||
p = subprocess.Popen([sys.executable, "-c",
|
||||
'import sys,os;'
|
||||
'sys.stdout.write(os.getcwd())'],
|
||||
stdout=subprocess.PIPE,
|
||||
cwd=tmpdir)
|
||||
self.addCleanup(p.stdout.close)
|
||||
normcase = os.path.normcase
|
||||
self.assertEqual(normcase(p.stdout.read().decode("utf-8")),
|
||||
normcase(tmpdir))
|
||||
|
||||
def test_env(self):
|
||||
newenv = os.environ.copy()
|
||||
newenv["FRUIT"] = "orange"
|
||||
|
|
111
Misc/NEWS
111
Misc/NEWS
|
@ -10,13 +10,117 @@ What's New in Python 3.3.1?
|
|||
Core and Builtins
|
||||
-----------------
|
||||
|
||||
- Issue #15379: Fix passing of non-BMP characters as integers for the charmap
|
||||
decoder (already working as unicode strings). Patch by Serhiy Storchaka.
|
||||
|
||||
- Issue #15144: Fix possible integer overflow when handling pointers as
|
||||
integer values, by using Py_uintptr_t instead of size_t. Patch by
|
||||
Serhiy Storchaka.
|
||||
|
||||
- Issue #15965: Explicitly cast AT_FDCWD as (int). Required on Solaris 10
|
||||
(which defines AT_FDCWD as 0xffd19553), harmless on other platforms.
|
||||
|
||||
- Issue #15839: Convert SystemErrors in super() to RuntimeErrors.
|
||||
|
||||
- Issue #15846: Fix SystemError which happened when using ast.parse in an
|
||||
exception handler on code with syntax errors.
|
||||
|
||||
- Issue #15801: Make sure mappings passed to '%' formatting are actually
|
||||
subscriptable.
|
||||
|
||||
|
||||
Library
|
||||
-------
|
||||
|
||||
- Issue #16034: Fix performance regressions in the new BZ2File implementation.
|
||||
Initial patch by Serhiy Storchaka.
|
||||
|
||||
- Issue #15756: subprocess.poll() now properly handles errno.ECHILD to
|
||||
return a returncode of 0 when the child has already exited or cannot
|
||||
be waited on.
|
||||
|
||||
- Issue #15323: improve failure message of Mock.assert_called_once_with
|
||||
|
||||
- Issue #16064: unittest -m claims executable is "python", not "python3"
|
||||
|
||||
- Issue #12376: Pass on parameters in TextTestResult.__init__ super call
|
||||
|
||||
- Issue #15222: Insert blank line after each message in mbox mailboxes
|
||||
|
||||
- Issue #16013: Fix CSV Reader parsing issue with ending quote characters.
|
||||
Patch by Serhiy Storchaka.
|
||||
|
||||
- Issue #15421: Fix an OverflowError in Calendar.itermonthdates() after
|
||||
datetime.MAXYEAR. Patch by Cédric Krier.
|
||||
|
||||
- Issue #15970: xml.etree.ElementTree now serializes correctly the empty HTML
|
||||
elements 'meta' and 'param'.
|
||||
|
||||
- Issue #15842: The SocketIO.{readable,writable,seekable} methods now
|
||||
raise ValueError when the file-like object is closed. Patch by Alessandro
|
||||
Moura.
|
||||
|
||||
- Issue #15876: Fix a refleak in the curses module: window.encoding.
|
||||
|
||||
- Issue #15881: Fixed atexit hook in multiprocessing. Original patch
|
||||
by Chris McDonough.
|
||||
|
||||
- Issue #15841: The readable(), writable() and seekable() methods of BytesIO
|
||||
and StringIO objects now raise ValueError when the object has been closed.
|
||||
Patch by Alessandro Moura.
|
||||
|
||||
- Issue #15447: Use subprocess.DEVNULL in webbrowser, instead of opening
|
||||
os.devnull explicitly and leaving it open.
|
||||
|
||||
- Issue #15509: webbrowser.UnixBrowser no longer passes empty arguments to
|
||||
Popen when %action substitutions produce empty strings.
|
||||
|
||||
- Issues #12776, #11839: call argparse type function (specified by add_argument)
|
||||
only once. Before, the type function was called twice in the case where the
|
||||
default was specified and the argument was given as well. This was especially
|
||||
problematic for the FileType type, as a default file would always be opened,
|
||||
even if a file argument was specified on the command line.
|
||||
|
||||
- Issue #15906: Fix a regression in argparse caused by the preceding change,
|
||||
when action='append', type='str' and default=[].
|
||||
|
||||
Tests
|
||||
-----
|
||||
|
||||
- Issue #15304: Fix warning message when os.chdir() fails inside
|
||||
test.support.temp_cwd(). Patch by Chris Jerdonek.
|
||||
|
||||
- Issue #15802: Fix test logic in TestMaildir.test_create_tmp. Patch
|
||||
by Serhiy Storchaka.
|
||||
|
||||
- Issue #15557: Added a test suite for the webbrowser module, thanks
|
||||
to Anton Barkovsky.
|
||||
|
||||
Build
|
||||
-----
|
||||
|
||||
- Issue #15819: Make sure we can build Python out-of-tree from a readonly
|
||||
source directory. (Somewhat related to Issue #9860.)
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
- Issue #15533: Clarify docs and add tests for subprocess.Popen()'s cwd
|
||||
argument.
|
||||
|
||||
- Issue #16036: Improve documentation of built-in int()'s signature and
|
||||
arguments.
|
||||
|
||||
- Issue #15935: Clarification of argparse docs, re: add_argument() type and
|
||||
default arguments. Patch contributed by Chris Jerdonek.
|
||||
|
||||
- Issue #11964: Document a change in v3.2 to the behavior of the indent
|
||||
parameter of json encoding operations.
|
||||
|
||||
Tools/Demos
|
||||
-----------
|
||||
|
||||
|
||||
|
||||
What's New in Python 3.3.0?
|
||||
===========================
|
||||
|
@ -560,9 +664,10 @@ Tools/Demos
|
|||
- Issue #12605: The gdb hooks for debugging CPython (within Tools/gdb) have been
|
||||
enhanced to show information on more C frames relevant to CPython within the
|
||||
"py-bt" and "py-bt-full" commands:
|
||||
* C frames that are waiting on the GIL
|
||||
* C frames that are garbage-collecting
|
||||
* C frames that are due to the invocation of a PyCFunction
|
||||
|
||||
* C frames that are waiting on the GIL
|
||||
* C frames that are garbage-collecting
|
||||
* C frames that are due to the invocation of a PyCFunction
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
|
|
@ -18,8 +18,13 @@ except ImportError:
|
|||
C = import_fresh_module('decimal', fresh=['_decimal'])
|
||||
P = import_fresh_module('decimal', blocked=['_decimal'])
|
||||
|
||||
|
||||
# Pi function from the decimal.py documentation
|
||||
#
|
||||
# NOTE: This is the pi function from the decimal documentation, modified
|
||||
# for benchmarking purposes. Since floats do not have a context, the higher
|
||||
# intermediate precision from the original is NOT used, so the modified
|
||||
# algorithm only gives an approximation to the correctly rounded result.
|
||||
# For serious use, refer to the documentation or the appropriate literature.
|
||||
#
|
||||
def pi_float():
|
||||
"""native float"""
|
||||
lasts, t, s, n, na, d, da = 0, 3.0, 3, 1, 0, 0, 24
|
||||
|
|
Loading…
Reference in New Issue