Mailing List Archive

cpython (merge default -> default): Merge
http://hg.python.org/cpython/rev/65ac469d30e6
changeset: 74251:65ac469d30e6
parent: 74249:ace54f5e75d7
parent: 74247:4c243c8ecd10
user: Antoine Pitrou <solipsis@pitrou.net>
date: Tue Jan 03 22:50:16 2012 +0100
summary:
Merge

files:
Doc/library/socketserver.rst | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)


diff --git a/Doc/library/socketserver.rst b/Doc/library/socketserver.rst
--- a/Doc/library/socketserver.rst
+++ b/Doc/library/socketserver.rst
@@ -153,8 +153,8 @@

.. method:: BaseServer.serve_forever(poll_interval=0.5)

- Handle requests until an explicit :meth:`shutdown` request. Polls for
- shutdown every *poll_interval* seconds. It also calls
+ Handle requests until an explicit :meth:`shutdown` request.
+ Poll for shutdown every *poll_interval* seconds. Ignores :attr:`self.timeout`. It also calls
:meth:`service_actions` which may be used by a subclass or Mixin to provide
various cleanup actions. For e.g. ForkingMixin class uses
:meth:`service_actions` to cleanup the zombie child processes.
@@ -172,7 +172,7 @@

.. method:: BaseServer.shutdown()

- Tells the :meth:`serve_forever` loop to stop and waits until it does.
+ Tell the :meth:`serve_forever` loop to stop and waits until it does.


.. attribute:: BaseServer.address_family

--
Repository URL: http://hg.python.org/cpython
cpython (merge default -> default): Merge [ In reply to ]
http://hg.python.org/cpython/rev/ec95169055ab
changeset: 74375:ec95169055ab
parent: 74374:e6b0d9d209f2
parent: 74371:e2f11c6305ae
user: Terry Jan Reedy <tjreedy@udel.edu>
date: Fri Jan 13 23:47:41 2012 -0500
summary:
Merge

files:
Doc/library/exceptions.rst | 3 +++
Doc/reference/expressions.rst | 5 ++++-
Doc/reference/simple_stmts.rst | 5 ++++-
Doc/whatsnew/3.3.rst | 1 +
4 files changed, 12 insertions(+), 2 deletions(-)


diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst
--- a/Doc/library/exceptions.rst
+++ b/Doc/library/exceptions.rst
@@ -261,6 +261,9 @@
raised, and the value returned by the function is used as the
:attr:`value` parameter to the constructor of the exception.

+ .. versionchanged:: 3.3
+ Added ``value`` attribute and the ability for generator functions to
+ use it to return a value.

.. exception:: SyntaxError

diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst
--- a/Doc/reference/expressions.rst
+++ b/Doc/reference/expressions.rst
@@ -355,7 +355,7 @@
garbage collected), the generator-iterator's :meth:`close` method will be
called, allowing any pending :keyword:`finally` clauses to execute.

-When ``yield from expression`` is used, it treats the supplied expression as
+When ``yield from <expr>`` is used, it treats the supplied expression as
a subiterator. All values produced by that subiterator are passed directly
to the caller of the current generator's methods. Any values passed in with
:meth:`send` and any exceptions passed in with :meth:`throw` are passed to
@@ -369,6 +369,9 @@
:exc:`StopIteration`, or automatically when the sub-iterator is a generator
(by returning a value from the sub-generator).

+ .. versionchanged:: 3.3
+ Added ``yield from <expr>`` to delegate control flow to a subiterator
+
The parentheses can be omitted when the :keyword:`yield` expression is the
sole expression on the right hand side of an assignment statement.

diff --git a/Doc/reference/simple_stmts.rst b/Doc/reference/simple_stmts.rst
--- a/Doc/reference/simple_stmts.rst
+++ b/Doc/reference/simple_stmts.rst
@@ -470,10 +470,13 @@
garbage collected), the generator-iterator's :meth:`close` method will be
called, allowing any pending :keyword:`finally` clauses to execute.

-When ``yield from expression`` is used, it treats the supplied expression as
+When ``yield from <expr>`` is used, it treats the supplied expression as
a subiterator, producing values from it until the underlying iterator is
exhausted.

+ .. versionchanged:: 3.3
+ Added ``yield from <expr>`` to delegate control flow to a subiterator
+
For full details of :keyword:`yield` semantics, refer to the :ref:`yieldexpr`
section.

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
@@ -224,6 +224,7 @@
how they might be accessible from the global scope.

Example with (non-bound) methods::
+
>>> class C:
... def meth(self):
... pass

--
Repository URL: http://hg.python.org/cpython
cpython (merge default -> default): Merge [ In reply to ]
http://hg.python.org/cpython/rev/12de1ad1cee8
changeset: 74478:12de1ad1cee8
parent: 74477:26b6732ecb87
parent: 74476:1de276420470
user: Antoine Pitrou <solipsis@pitrou.net>
date: Wed Jan 18 02:05:38 2012 +0100
summary:
Merge

files:
Doc/library/time.rst | 12 ++++++
Doc/library/webbrowser.rst | 7 ++-
Doc/whatsnew/3.3.rst | 12 +++--
Lib/bz2.py | 8 +++-
Lib/test/test_bz2.py | 7 +++
Lib/test/test_time.py | 7 +++
Misc/NEWS | 5 ++
Modules/timemodule.c | 47 ++++++++++++++++++++++++++
8 files changed, 96 insertions(+), 9 deletions(-)


diff --git a/Doc/library/time.rst b/Doc/library/time.rst
--- a/Doc/library/time.rst
+++ b/Doc/library/time.rst
@@ -183,6 +183,18 @@

.. versionadded:: 3.3

+.. function:: wallclock()
+
+ .. index::
+ single: Wallclock
+ single: benchmarking
+
+ Return the current time in fractions of a second to the system's best ability.
+ Use this when the most accurate representation of wall-clock is required, i.e.
+ when "processor time" is inappropriate. The reference point of the returned
+ value is undefined so only the difference of consecutive calls is valid.
+
+ .. versionadded: 3.3

.. function:: ctime([secs])

diff --git a/Doc/library/webbrowser.rst b/Doc/library/webbrowser.rst
--- a/Doc/library/webbrowser.rst
+++ b/Doc/library/webbrowser.rst
@@ -164,12 +164,15 @@
(4)
Only on Mac OS X platform.

+.. versionadded:: 3.3
+ Support for Chrome/Chromium has been added.
+
Here are some simple examples::

- url = 'http://www.python.org/'
+ url = 'http://docs.python.org/'

# Open URL in a new tab, if a browser window is already open.
- webbrowser.open_new_tab(url + 'doc/')
+ webbrowser.open_new_tab(url)

# Open URL in new window, raising the window if possible.
webbrowser.open_new(url)
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
@@ -396,12 +396,14 @@
time
----

-* The :mod:`time` module has new :func:`~time.clock_getres` and
- :func:`~time.clock_gettime` functions and ``CLOCK_xxx`` constants.
- :func:`~time.clock_gettime` can be used with :data:`time.CLOCK_MONOTONIC` to
- get a monotonic clock.
+The :mod:`time` module has new functions:

- (Contributed by Victor Stinner in :issue:`10278`)
+* :func:`~time.clock_getres` and :func:`~time.clock_gettime` functions and
+ ``CLOCK_xxx`` constants. :func:`~time.clock_gettime` can be used with
+ :data:`time.CLOCK_MONOTONIC` to get a monotonic clock.
+* :func:`~time.wallclock`: monotonic clock.
+
+(Contributed by Victor Stinner in :issue:`10278`)


ftplib
diff --git a/Lib/bz2.py b/Lib/bz2.py
--- a/Lib/bz2.py
+++ b/Lib/bz2.py
@@ -10,9 +10,13 @@
__author__ = "Nadeem Vawda <nadeem.vawda@gmail.com>"

import io
-import threading
import warnings

+try:
+ from threading import RLock
+except ImportError:
+ from dummy_threading import RLock
+
from _bz2 import BZ2Compressor, BZ2Decompressor


@@ -53,7 +57,7 @@
"""
# This lock must be recursive, so that BufferedIOBase's
# readline(), readlines() and writelines() don't deadlock.
- self._lock = threading.RLock()
+ self._lock = RLock()
self._fp = None
self._closefp = False
self._mode = _MODE_CLOSED
diff --git a/Lib/test/test_bz2.py b/Lib/test/test_bz2.py
--- a/Lib/test/test_bz2.py
+++ b/Lib/test/test_bz2.py
@@ -463,6 +463,13 @@
for t in threads:
t.join()

+ def testWithoutThreading(self):
+ bz2 = support.import_fresh_module("bz2", blocked=("threading",))
+ with bz2.BZ2File(self.filename, "wb") as f:
+ f.write(b"abc")
+ with bz2.BZ2File(self.filename, "rb") as f:
+ self.assertEqual(f.read(), b"abc")
+
def testMixedIterationAndReads(self):
self.createTempFile()
linelen = len(self.TEXT_LINES[0])
diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py
--- a/Lib/test/test_time.py
+++ b/Lib/test/test_time.py
@@ -332,6 +332,13 @@
self.assertEqual(time.strftime('%Z', tt), tzname)


+ def test_wallclock(self):
+ t0 = time.wallclock()
+ time.sleep(0.1)
+ t1 = time.wallclock()
+ t = t1 - t0
+ self.assertAlmostEqual(t, 0.1, places=2)
+
class TestLocale(unittest.TestCase):
def setUp(self):
self.oldloc = locale.setlocale(locale.LC_ALL)
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -447,6 +447,11 @@
Library
-------

+- Issue #10278: Add time.wallclock() function, monotonic clock.
+
+- Issue #13809: Fix regression where bz2 module wouldn't work when threads are
+ disabled. Original patch by Amaury Forgeot d'Arc.
+
- Issue #13589: Fix some serialization primitives in the aifc module.
Patch by Oleg Plakhotnyuk.

diff --git a/Modules/timemodule.c b/Modules/timemodule.c
--- a/Modules/timemodule.c
+++ b/Modules/timemodule.c
@@ -737,6 +737,52 @@
should not be relied on.");
#endif /* HAVE_WORKING_TZSET */

+static PyObject *
+time_wallclock(PyObject *self, PyObject *unused)
+{
+#if defined(MS_WINDOWS) && !defined(__BORLANDC__)
+ return time_clock(self, NULL);
+#elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
+ static int clk_index = 0;
+ clockid_t clk_ids[] = {
+#ifdef CLOCK_MONOTONIC_RAW
+ CLOCK_MONOTONIC_RAW,
+#endif
+ CLOCK_MONOTONIC
+#ifdef CLOCK_REALTIME
+ /* On Linux, CLOCK_REALTIME uses the same clock than gettimeofday(),
+ but clock_gettime() has a nanosecond resolution. */
+ , CLOCK_REALTIME
+#endif
+ };
+ int ret;
+ struct timespec tp;
+
+ while (0 <= clk_index) {
+ clockid_t clk_id = clk_ids[clk_index];
+ ret = clock_gettime(clk_id, &tp);
+ if (ret == 0)
+ return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9);
+
+ clk_index++;
+ if (Py_ARRAY_LENGTH(clk_ids) <= clk_index)
+ clk_index = -1;
+ }
+ return time_time(self, NULL);
+#else
+ return time_time(self, NULL);
+#endif
+}
+
+PyDoc_STRVAR(wallclock_doc,
+"wallclock() -> float\n\
+\n\
+Return the current time in fractions of a second to the system's best\n\
+ability. Use this when the most accurate representation of wall-clock is\n\
+required, i.e. when \"processor time\" is inappropriate. The reference point\n\
+of the returned value is undefined so only the difference of consecutive\n\
+calls is valid.");
+
static void
PyInit_timezone(PyObject *m) {
/* This code moved from PyInit_time wholesale to allow calling it from
@@ -872,6 +918,7 @@
#ifdef HAVE_WORKING_TZSET
{"tzset", time_tzset, METH_NOARGS, tzset_doc},
#endif
+ {"wallclock", time_wallclock, METH_NOARGS, wallclock_doc},
{NULL, NULL} /* sentinel */
};


--
Repository URL: http://hg.python.org/cpython
cpython (merge default -> default): Merge [ In reply to ]
http://hg.python.org/cpython/rev/93075fb1360a
changeset: 74631:93075fb1360a
parent: 74629:d2cf8a34ddf9
parent: 74630:7d8f016784cd
user: Brett Cannon <brett@python.org>
date: Thu Jan 26 08:58:19 2012 -0500
summary:
Merge

files:
Lib/importlib/__init__.py | 43 ++-------
Lib/importlib/_bootstrap.py | 39 ++++++++-
Lib/importlib/abc.py | 4 +-
Lib/importlib/test/source/test_abc_loader.py | 8 +-
4 files changed, 52 insertions(+), 42 deletions(-)


diff --git a/Lib/importlib/__init__.py b/Lib/importlib/__init__.py
--- a/Lib/importlib/__init__.py
+++ b/Lib/importlib/__init__.py
@@ -26,8 +26,15 @@
import re
import tokenize

+# To simplify imports in test code
+_w_long = _bootstrap._w_long
+_r_long = _bootstrap._r_long
+
+
# Bootstrap help #####################################################

+# TODO: Expose from import.c, else handle encode/decode as _os.environ returns
+# bytes.
def _case_ok(directory, check):
"""Check if the directory contains something matching 'check'.

@@ -36,37 +43,13 @@
"""
if 'PYTHONCASEOK' in os.environ:
return True
- elif check in os.listdir(directory if directory else os.getcwd()):
+ if not directory:
+ directory = os.getcwd()
+ if check in os.listdir(directory):
return True
return False

-
-def _w_long(x):
- """Convert a 32-bit integer to little-endian.
-
- XXX Temporary until marshal's long functions are exposed.
-
- """
- x = int(x)
- int_bytes = []
- int_bytes.append(x & 0xFF)
- int_bytes.append((x >> 8) & 0xFF)
- int_bytes.append((x >> 16) & 0xFF)
- int_bytes.append((x >> 24) & 0xFF)
- return bytearray(int_bytes)
-
-
-def _r_long(int_bytes):
- """Convert 4 bytes in little-endian to an integer.
-
- XXX Temporary until marshal's long function are exposed.
-
- """
- x = int_bytes[0]
- x |= int_bytes[1] << 8
- x |= int_bytes[2] << 16
- x |= int_bytes[3] << 24
- return x
+_bootstrap._case_ok = _case_ok


# Required built-in modules.
@@ -94,10 +77,6 @@
# For os.path.join replacement; pull from Include/osdefs.h:SEP .
_bootstrap.path_sep = sep

-_bootstrap._case_ok = _case_ok
-marshal._w_long = _w_long
-marshal._r_long = _r_long
-

# Public API #########################################################

diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py
--- a/Lib/importlib/_bootstrap.py
+++ b/Lib/importlib/_bootstrap.py
@@ -18,6 +18,37 @@

# Bootstrap-related code ######################################################

+# TODO: Expose from marshal
+def _w_long(x):
+ """Convert a 32-bit integer to little-endian.
+
+ XXX Temporary until marshal's long functions are exposed.
+
+ """
+ x = int(x)
+ int_bytes = []
+ int_bytes.append(x & 0xFF)
+ int_bytes.append((x >> 8) & 0xFF)
+ int_bytes.append((x >> 16) & 0xFF)
+ int_bytes.append((x >> 24) & 0xFF)
+ return bytearray(int_bytes)
+
+
+# TODO: Expose from marshal
+def _r_long(int_bytes):
+ """Convert 4 bytes in little-endian to an integer.
+
+ XXX Temporary until marshal's long function are exposed.
+
+ """
+ x = int_bytes[0]
+ x |= int_bytes[1] << 8
+ x |= int_bytes[2] << 16
+ x |= int_bytes[3] << 24
+ return x
+
+
+
# XXX Could also expose Modules/getpath.c:joinpath()
def _path_join(*args):
"""Replacement for os.path.join."""
@@ -353,14 +384,14 @@
except KeyError:
pass
else:
- if marshal._r_long(raw_timestamp) != source_mtime:
+ if _r_long(raw_timestamp) != source_mtime:
raise ImportError("bytecode is stale for {}".format(fullname))
try:
source_size = source_stats['size'] & 0xFFFFFFFF
except KeyError:
pass
else:
- if marshal._r_long(raw_size) != source_size:
+ if _r_long(raw_size) != source_size:
raise ImportError("bytecode is stale for {}".format(fullname))
# Can't return the code object as errors from marshal loading need to
# propagate even when source is available.
@@ -472,8 +503,8 @@
# their own cached file format, this block of code will most likely
# throw an exception.
data = bytearray(imp.get_magic())
- data.extend(marshal._w_long(source_mtime))
- data.extend(marshal._w_long(len(source_bytes)))
+ data.extend(_w_long(source_mtime))
+ data.extend(_w_long(len(source_bytes)))
data.extend(marshal.dumps(code_object))
try:
self.set_data(bytecode_path, data)
diff --git a/Lib/importlib/abc.py b/Lib/importlib/abc.py
--- a/Lib/importlib/abc.py
+++ b/Lib/importlib/abc.py
@@ -260,7 +260,7 @@
raw_timestamp = data[4:8]
if len(raw_timestamp) < 4:
raise EOFError("bad timestamp in {}".format(fullname))
- pyc_timestamp = marshal._r_long(raw_timestamp)
+ pyc_timestamp = _bootstrap._r_long(raw_timestamp)
bytecode = data[8:]
# Verify that the magic number is valid.
if imp.get_magic() != magic:
@@ -292,7 +292,7 @@
# Generate bytecode and write it out.
if not sys.dont_write_bytecode:
data = bytearray(imp.get_magic())
- data.extend(marshal._w_long(source_timestamp))
+ data.extend(_bootstrap._w_long(source_timestamp))
data.extend(marshal.dumps(code_object))
self.write_bytecode(fullname, data)
return code_object
diff --git a/Lib/importlib/test/source/test_abc_loader.py b/Lib/importlib/test/source/test_abc_loader.py
--- a/Lib/importlib/test/source/test_abc_loader.py
+++ b/Lib/importlib/test/source/test_abc_loader.py
@@ -42,8 +42,8 @@
self.bytecode_path = imp.cache_from_source(self.path)
self.source_size = len(self.source)
data = bytearray(magic)
- data.extend(marshal._w_long(self.source_mtime))
- data.extend(marshal._w_long(self.source_size))
+ data.extend(importlib._w_long(self.source_mtime))
+ data.extend(importlib._w_long(self.source_size))
code_object = compile(self.source, self.path, 'exec',
dont_inherit=True)
data.extend(marshal.dumps(code_object))
@@ -658,8 +658,8 @@
if bytecode_written:
self.assertIn(self.cached, self.loader.written)
data = bytearray(imp.get_magic())
- data.extend(marshal._w_long(self.loader.source_mtime))
- data.extend(marshal._w_long(self.loader.source_size))
+ data.extend(importlib._w_long(self.loader.source_mtime))
+ data.extend(importlib._w_long(self.loader.source_size))
data.extend(marshal.dumps(code_object))
self.assertEqual(self.loader.written[self.cached], bytes(data))


--
Repository URL: http://hg.python.org/cpython
cpython (merge default -> default): Merge [ In reply to ]
http://hg.python.org/cpython/rev/dc3de15b43db
changeset: 74638:dc3de15b43db
parent: 74636:0f00010c88f0
parent: 74634:9ee4a104e33d
user: Brett Cannon <brett@python.org>
date: Thu Jan 26 18:34:34 2012 -0500
summary:
Merge

files:
Doc/library/ctypes.rst | 4 -
Lib/collections/__init__.py | 2 +-
Lib/test/test_time.py | 15 +++
Misc/NEWS | 7 +
Modules/_ctypes/_ctypes.c | 2 +-
Modules/timemodule.c | 114 +++++++++++++----------
Python/import.c | 6 -
7 files changed, 86 insertions(+), 64 deletions(-)


diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst
--- a/Doc/library/ctypes.rst
+++ b/Doc/library/ctypes.rst
@@ -1823,8 +1823,6 @@
termination character. An integer can be passed as second argument which allows
to specify the size of the array if the length of the bytes should not be used.

- If the first parameter is a string, it is converted into a bytes object
- according to ctypes conversion rules.


.. function:: create_unicode_buffer(init_or_size, size=None)
@@ -1841,8 +1839,6 @@
allows to specify the size of the array if the length of the string should not
be used.

- If the first parameter is a bytes object, it is converted into an unicode string
- according to ctypes conversion rules.


.. function:: DllCanUnloadNow()
diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py
--- a/Lib/collections/__init__.py
+++ b/Lib/collections/__init__.py
@@ -34,7 +34,7 @@
# The circular doubly linked list starts and ends with a sentinel element.
# The sentinel element never gets deleted (this simplifies the algorithm).
# The sentinel is in self.__hardroot with a weakref proxy in self.__root.
- # The prev/next links are weakref proxies (to prevent circular references).
+ # The prev links are weakref proxies (to prevent circular references).
# Individual links are kept alive by the hard reference in self.__map.
# Those hard references disappear when a key is deleted from an OrderedDict.

diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py
--- a/Lib/test/test_time.py
+++ b/Lib/test/test_time.py
@@ -343,6 +343,21 @@
dt = t2 - t1
self.assertAlmostEqual(dt, 0.1, delta=0.2)

+ def test_localtime_failure(self):
+ # Issue #13847: check for localtime() failure
+ invalid_time_t = 2**60
+ try:
+ time.localtime(invalid_time_t)
+ except ValueError as err:
+ if str(err) == "timestamp out of range for platform time_t":
+ self.skipTest("need 64-bit time_t")
+ else:
+ raise
+ except OSError:
+ pass
+ self.assertRaises(OSError, time.localtime, invalid_time_t)
+ self.assertRaises(OSError, time.gmtime, invalid_time_t)
+ self.assertRaises(OSError, time.ctime, invalid_time_t)

class TestLocale(unittest.TestCase):
def setUp(self):
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -461,6 +461,10 @@
Library
-------

+- Issue #13847: time.localtime() and time.gmtime() now raise an OSError instead
+ of ValueError on failure. time.ctime() and time.asctime() now raises an
+ OSError if localtime() failed.
+
- Issue #13862: Fix spurious failure in test_zlib due to runtime/compile time
minor versions not matching.

@@ -1837,6 +1841,9 @@
Extension Modules
-----------------

+- Issue #13840: The error message produced by ctypes.create_string_buffer
+ when given a Unicode string has been fixed.
+
- Issue #9975: socket: Fix incorrect use of flowinfo and scope_id. Patch by
Vilmos Nebehaj.

diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -1096,7 +1096,7 @@

if (!PyBytes_Check(value)) {
PyErr_Format(PyExc_TypeError,
- "str/bytes expected instead of %s instance",
+ "bytes expected instead of %s instance",
Py_TYPE(value)->tp_name);
return -1;
} else
diff --git a/Modules/timemodule.c b/Modules/timemodule.c
--- a/Modules/timemodule.c
+++ b/Modules/timemodule.c
@@ -247,55 +247,53 @@
return v;
}

-static PyObject *
-time_convert(double when, struct tm * (*function)(const time_t *))
-{
- struct tm *p;
- time_t whent = _PyTime_DoubleToTimet(when);
-
- if (whent == (time_t)-1 && PyErr_Occurred())
- return NULL;
- errno = 0;
- p = function(&whent);
- if (p == NULL) {
-#ifdef EINVAL
- if (errno == 0)
- errno = EINVAL;
-#endif
- return PyErr_SetFromErrno(PyExc_ValueError);
- }
- return tmtotuple(p);
-}
-
/* Parse arg tuple that can contain an optional float-or-None value;
format needs to be "|O:name".
Returns non-zero on success (parallels PyArg_ParseTuple).
*/
static int
-parse_time_double_args(PyObject *args, char *format, double *pwhen)
+parse_time_t_args(PyObject *args, char *format, time_t *pwhen)
{
PyObject *ot = NULL;
+ time_t whent;

if (!PyArg_ParseTuple(args, format, &ot))
return 0;
- if (ot == NULL || ot == Py_None)
- *pwhen = floattime();
+ if (ot == NULL || ot == Py_None) {
+ whent = time(NULL);
+ }
else {
- double when = PyFloat_AsDouble(ot);
+ double d = PyFloat_AsDouble(ot);
if (PyErr_Occurred())
return 0;
- *pwhen = when;
+ whent = _PyTime_DoubleToTimet(d);
+ if (whent == (time_t)-1 && PyErr_Occurred())
+ return 0;
}
+ *pwhen = whent;
return 1;
}

static PyObject *
time_gmtime(PyObject *self, PyObject *args)
{
- double when;
- if (!parse_time_double_args(args, "|O:gmtime", &when))
+ time_t when;
+ struct tm buf, *local;
+
+ if (!parse_time_t_args(args, "|O:gmtime", &when))
return NULL;
- return time_convert(when, gmtime);
+
+ errno = 0;
+ local = gmtime(&when);
+ if (local == NULL) {
+#ifdef EINVAL
+ if (errno == 0)
+ errno = EINVAL;
+#endif
+ return PyErr_SetFromErrno(PyExc_OSError);
+ }
+ buf = *local;
+ return tmtotuple(&buf);
}

PyDoc_STRVAR(gmtime_doc,
@@ -305,13 +303,37 @@
Convert seconds since the Epoch to a time tuple expressing UTC (a.k.a.\n\
GMT). When 'seconds' is not passed in, convert the current time instead.");

+static int
+pylocaltime(time_t *timep, struct tm *result)
+{
+ struct tm *local;
+
+ assert (timep != NULL);
+ local = localtime(timep);
+ if (local == NULL) {
+ /* unconvertible time */
+#ifdef EINVAL
+ if (errno == 0)
+ errno = EINVAL;
+#endif
+ PyErr_SetFromErrno(PyExc_OSError);
+ return -1;
+ }
+ *result = *local;
+ return 0;
+}
+
static PyObject *
time_localtime(PyObject *self, PyObject *args)
{
- double when;
- if (!parse_time_double_args(args, "|O:localtime", &when))
+ time_t when;
+ struct tm buf;
+
+ if (!parse_time_t_args(args, "|O:localtime", &when))
return NULL;
- return time_convert(when, localtime);
+ if (pylocaltime(&when, &buf) == 1)
+ return NULL;
+ return tmtotuple(&buf);
}

PyDoc_STRVAR(localtime_doc,
@@ -462,7 +484,8 @@

if (tup == NULL) {
time_t tt = time(NULL);
- buf = *localtime(&tt);
+ if (pylocaltime(&tt, &buf) == -1)
+ return NULL;
}
else if (!gettmarg(tup, &buf) || !checktm(&buf))
return NULL;
@@ -627,7 +650,9 @@
return NULL;
if (tup == NULL) {
time_t tt = time(NULL);
- buf = *localtime(&tt);
+ if (pylocaltime(&tt, &buf) == -1)
+ return NULL;
+
} else if (!gettmarg(tup, &buf) || !checktm(&buf))
return NULL;
return _asctime(&buf);
@@ -643,28 +668,13 @@
static PyObject *
time_ctime(PyObject *self, PyObject *args)
{
- PyObject *ot = NULL;
time_t tt;
- struct tm *timeptr;
-
- if (!PyArg_UnpackTuple(args, "ctime", 0, 1, &ot))
+ struct tm buf;
+ if (!parse_time_t_args(args, "|O:ctime", &tt))
return NULL;
- if (ot == NULL || ot == Py_None)
- tt = time(NULL);
- else {
- double dt = PyFloat_AsDouble(ot);
- if (PyErr_Occurred())
- return NULL;
- tt = _PyTime_DoubleToTimet(dt);
- if (tt == (time_t)-1 && PyErr_Occurred())
- return NULL;
- }
- timeptr = localtime(&tt);
- if (timeptr == NULL) {
- PyErr_SetString(PyExc_ValueError, "unconvertible time");
+ if (pylocaltime(&tt, &buf) == -1)
return NULL;
- }
- return _asctime(timeptr);
+ return _asctime(&buf);
}

PyDoc_STRVAR(ctime_doc,
diff --git a/Python/import.c b/Python/import.c
--- a/Python/import.c
+++ b/Python/import.c
@@ -2052,12 +2052,6 @@
if (p_loader != NULL)
*p_loader = NULL;

- if (PyUnicode_GET_LENGTH(name) > MAXPATHLEN) {
- PyErr_SetString(PyExc_OverflowError,
- "module name is too long");
- return NULL;
- }
-
/* sys.meta_path import hook */
if (p_loader != NULL) {
_Py_IDENTIFIER(find_module);

--
Repository URL: http://hg.python.org/cpython
cpython (merge default -> default): Merge [ In reply to ]
http://hg.python.org/cpython/rev/082eea3fc9bc
changeset: 74644:082eea3fc9bc
parent: 74643:ecf4a7bb8807
parent: 74642:856f0864437a
user: Brett Cannon <brett@python.org>
date: Thu Jan 26 19:09:44 2012 -0500
summary:
Merge

files:
Lib/test/test_time.py | 27 +++++++++++++--------
Misc/NEWS | 3 +-
Modules/timemodule.c | 38 ++++++++++++++++++++++--------
3 files changed, 45 insertions(+), 23 deletions(-)


diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py
--- a/Lib/test/test_time.py
+++ b/Lib/test/test_time.py
@@ -309,7 +309,7 @@
for t in (-2, -1, 0, 1):
try:
tt = time.localtime(t)
- except (OverflowError, ValueError):
+ except (OverflowError, OSError):
pass
else:
self.assertEqual(time.mktime(tt), t)
@@ -345,16 +345,21 @@

def test_localtime_failure(self):
# Issue #13847: check for localtime() failure
- invalid_time_t = 2**60
- try:
- time.localtime(invalid_time_t)
- except ValueError as err:
- if str(err) == "timestamp out of range for platform time_t":
- self.skipTest("need 64-bit time_t")
- else:
- raise
- except OSError:
- pass
+ invalid_time_t = None
+ for time_t in (-1, 2**30, 2**33, 2**60):
+ try:
+ time.localtime(time_t)
+ except ValueError as err:
+ if str(err) == "timestamp out of range for platform time_t":
+ self.skipTest("need 64-bit time_t")
+ else:
+ raise
+ except OSError:
+ invalid_time_t = time_t
+ break
+ if invalid_time_t is None:
+ self.skipTest("unable to find an invalid time_t value")
+
self.assertRaises(OSError, time.localtime, invalid_time_t)
self.assertRaises(OSError, time.gmtime, invalid_time_t)
self.assertRaises(OSError, time.ctime, invalid_time_t)
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -463,7 +463,8 @@

- Issue #13847: time.localtime() and time.gmtime() now raise an OSError instead
of ValueError on failure. time.ctime() and time.asctime() now raises an
- OSError if localtime() failed.
+ OSError if localtime() failed. time.clock() now raises a RuntimeError if the
+ processor time used is not available or its value cannot be represented

- Issue #13862: Fix spurious failure in test_zlib due to runtime/compile time
minor versions not matching.
diff --git a/Modules/timemodule.c b/Modules/timemodule.c
--- a/Modules/timemodule.c
+++ b/Modules/timemodule.c
@@ -62,6 +62,31 @@
Return the current time in seconds since the Epoch.\n\
Fractions of a second may be present if the system clock provides them.");

+#if defined(HAVE_CLOCK)
+
+#ifndef CLOCKS_PER_SEC
+#ifdef CLK_TCK
+#define CLOCKS_PER_SEC CLK_TCK
+#else
+#define CLOCKS_PER_SEC 1000000
+#endif
+#endif
+
+static PyObject *
+pyclock(void)
+{
+ clock_t value;
+ value = clock();
+ if (value == (clock_t)-1) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "the processor time used is not available "
+ "or its value cannot be represented");
+ return NULL;
+ }
+ return PyFloat_FromDouble((double)value / CLOCKS_PER_SEC);
+}
+#endif /* HAVE_CLOCK */
+
#if defined(MS_WINDOWS) && !defined(__BORLANDC__)
/* Win32 has better clock replacement; we have our own version, due to Mark
Hammond and Tim Peters */
@@ -79,8 +104,7 @@
if (!QueryPerformanceFrequency(&freq) || freq.QuadPart == 0) {
/* Unlikely to happen - this works on all intel
machines at least! Revert to clock() */
- return PyFloat_FromDouble(((double)clock()) /
- CLOCKS_PER_SEC);
+ return pyclock();
}
divisor = (double)freq.QuadPart;
}
@@ -91,18 +115,10 @@

#elif defined(HAVE_CLOCK)

-#ifndef CLOCKS_PER_SEC
-#ifdef CLK_TCK
-#define CLOCKS_PER_SEC CLK_TCK
-#else
-#define CLOCKS_PER_SEC 1000000
-#endif
-#endif
-
static PyObject *
time_clock(PyObject *self, PyObject *unused)
{
- return PyFloat_FromDouble(((double)clock()) / CLOCKS_PER_SEC);
+ return pyclock();
}
#endif /* HAVE_CLOCK */


--
Repository URL: http://hg.python.org/cpython
cpython (merge default -> default): Merge [ In reply to ]
http://hg.python.org/cpython/rev/06d47538af89
changeset: 74700:06d47538af89
parent: 74699:2d0ff4d82b14
parent: 74697:bf31815548c9
user: Brett Cannon <brett@python.org>
date: Tue Jan 31 14:58:07 2012 -0500
summary:
Merge

files:
Lib/idlelib/PyShell.py | 19 +++++++++++++------
Lib/idlelib/ScriptBinding.py | 5 ++---
Misc/ACKS | 1 +
Misc/NEWS | 3 +++
Modules/zipimport.c | 9 +++++----
5 files changed, 24 insertions(+), 13 deletions(-)


diff --git a/Lib/idlelib/PyShell.py b/Lib/idlelib/PyShell.py
--- a/Lib/idlelib/PyShell.py
+++ b/Lib/idlelib/PyShell.py
@@ -411,11 +411,11 @@
self.rpcclt.register("flist", self.tkconsole.flist)
self.rpcclt.register("linecache", linecache)
self.rpcclt.register("interp", self)
- self.transfer_path()
+ self.transfer_path(with_cwd=True)
self.poll_subprocess()
return self.rpcclt

- def restart_subprocess(self):
+ def restart_subprocess(self, with_cwd=False):
if self.restarting:
return self.rpcclt
self.restarting = True
@@ -439,7 +439,7 @@
except socket.timeout as err:
self.display_no_subprocess_error()
return None
- self.transfer_path()
+ self.transfer_path(with_cwd=with_cwd)
# annotate restart in shell window and mark it
console.text.delete("iomark", "end-1c")
if was_executing:
@@ -492,12 +492,18 @@
except OSError:
return

- def transfer_path(self):
+ def transfer_path(self, with_cwd=False):
+ if with_cwd: # Issue 13506
+ path = [''] # include Current Working Directory
+ path.extend(sys.path)
+ else:
+ path = sys.path
+
self.runcommand("""if 1:
import sys as _sys
_sys.path = %r
del _sys
- \n""" % (sys.path,))
+ \n""" % (path,))

active_seq = None

@@ -1191,7 +1197,8 @@
self.text.see("restart")

def restart_shell(self, event=None):
- self.interp.restart_subprocess()
+ "Callback for Run/Restart Shell Cntl-F6"
+ self.interp.restart_subprocess(with_cwd=True)

def showprompt(self):
self.resetoutput()
diff --git a/Lib/idlelib/ScriptBinding.py b/Lib/idlelib/ScriptBinding.py
--- a/Lib/idlelib/ScriptBinding.py
+++ b/Lib/idlelib/ScriptBinding.py
@@ -144,10 +144,9 @@
return 'break'
if not self.tabnanny(filename):
return 'break'
- shell = self.shell
- interp = shell.interp
+ interp = self.shell.interp
if PyShell.use_subprocess:
- shell.restart_shell()
+ interp.restart_subprocess(with_cwd=False)
dirname = os.path.dirname(filename)
# XXX Too often this discards arguments the user just set...
interp.runcommand("""if 1:
diff --git a/Misc/ACKS b/Misc/ACKS
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -880,6 +880,7 @@
Ty Sarna
Ben Sayer
sbt
+Marco Scataglini
Andrew Schaaf
Michael Scharf
Andreas Schawo
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -463,6 +463,9 @@
Library
-------

+- Issue #13506: Add '' to path for IDLE Shell when started and restarted with Restart Shell.
+ Original patches by Marco Scataglini and Roger Serwy.
+
- Issue #8828: Add new function os.replace(), for cross-platform renaming
with overwriting.

diff --git a/Modules/zipimport.c b/Modules/zipimport.c
--- a/Modules/zipimport.c
+++ b/Modules/zipimport.c
@@ -728,14 +728,15 @@
PyObject *files = NULL;
FILE *fp;
unsigned short flags;
- long compress, crc, data_size, file_size, file_offset, date, time;
- long header_offset, name_size, header_size, header_position;
+ short compress, time, date, name_size;
+ long crc, data_size, file_size, header_size;
+ Py_ssize_t file_offset, header_position, header_offset;
long l, count;
Py_ssize_t i;
char name[MAXPATHLEN + 5];
PyObject *nameobj = NULL;
char *p, endof_central_dir[22];
- long arc_offset; /* offset from beginning of file to start of zip-archive */
+ Py_ssize_t arc_offset; /* Absolute offset to start of the zip-archive. */
PyObject *path;
const char *charset;
int bootstrap;
@@ -835,7 +836,7 @@
path = PyUnicode_FromFormat("%U%c%U", archive, SEP, nameobj);
if (path == NULL)
goto error;
- t = Py_BuildValue("Niiiiiii", path, compress, data_size,
+ t = Py_BuildValue("Nhllnhhl", path, compress, data_size,
file_size, file_offset, time, date, crc);
if (t == NULL)
goto error;

--
Repository URL: http://hg.python.org/cpython
cpython (merge default -> default): Merge [ In reply to ]
http://hg.python.org/cpython/rev/bf24b2e1be24
changeset: 74743:bf24b2e1be24
parent: 74742:404c0c345321
parent: 74741:aa3680d2c24d
user: Brett Cannon <brett@python.org>
date: Fri Feb 03 12:08:32 2012 -0500
summary:
Merge

files:
Doc/library/socket.rst | 8 ++
Misc/ACKS | 1 +
Misc/NEWS | 3 +
Modules/socketmodule.c | 107 +++++++++++++++++++++++++++++
Modules/socketmodule.h | 10 ++
configure | 6 +-
configure.in | 6 +-
pyconfig.h.in | 6 +
8 files changed, 141 insertions(+), 6 deletions(-)


diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst
--- a/Doc/library/socket.rst
+++ b/Doc/library/socket.rst
@@ -99,6 +99,14 @@
``'can0'``. The network interface name ``''`` can be used to receive packets
from all network interfaces of this family.

+- A string or a tuple ``(id, unit)`` is used for the :const:`SYSPROTO_CONTROL`
+ protocol of the :const:`PF_SYSTEM` family. The string is the name of a
+ kernel control using a dynamically-assigned ID. The tuple can be used if ID
+ and unit number of the kernel control are known or if a registered ID is
+ used.
+
+ .. versionadded:: 3.3
+
- Certain other address families (:const:`AF_BLUETOOTH`, :const:`AF_PACKET`)
support specific representations.

diff --git a/Misc/ACKS b/Misc/ACKS
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -366,6 +366,7 @@
Johannes Gijsbers
Michael Gilfix
Yannick Gingras
+Michael Goderbauer
Christoph Gohlke
Tim Golden
Tiago Gonçalves
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@
Core and Builtins
-----------------

+- Issue #13777: Add PF_SYSTEM sockets on OS X.
+ Patch by Michael Goderbauer.
+
- Issue #13908: Ready types returned from PyType_FromSpec.

- Issue #11235: Fix OverflowError when trying to import a source file whose
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -218,6 +218,11 @@
# include <ioctl.h>
#endif

+#ifdef __APPLE__
+# include <sys/ioctl.h>
+#endif
+
+
#if defined(PYOS_OS2)
# define INCL_DOS
# define INCL_DOSERRORS
@@ -1239,6 +1244,23 @@
}
#endif

+#ifdef PF_SYSTEM
+ case PF_SYSTEM:
+ switch(proto) {
+#ifdef SYSPROTO_CONTROL
+ case SYSPROTO_CONTROL:
+ {
+ struct sockaddr_ctl *a = (struct sockaddr_ctl *)addr;
+ return Py_BuildValue("(II)", a->sc_id, a->sc_unit);
+ }
+#endif
+ default:
+ PyErr_SetString(PyExc_ValueError,
+ "Invalid address type");
+ return 0;
+ }
+#endif
+
/* More cases here... */

default:
@@ -1677,6 +1699,64 @@
return 0;
}
#endif
+
+#ifdef PF_SYSTEM
+ case PF_SYSTEM:
+ switch (s->sock_proto) {
+#ifdef SYSPROTO_CONTROL
+ case SYSPROTO_CONTROL:
+ {
+ struct sockaddr_ctl *addr;
+
+ addr = (struct sockaddr_ctl *)addr_ret;
+ addr->sc_family = AF_SYSTEM;
+ addr->ss_sysaddr = AF_SYS_CONTROL;
+
+ if (PyUnicode_Check(args)) {
+ struct ctl_info info;
+ PyObject *ctl_name;
+
+ if (!PyArg_Parse(args, "O&",
+ PyUnicode_FSConverter, &ctl_name)) {
+ return 0;
+ }
+
+ if (PyBytes_GET_SIZE(ctl_name) > sizeof(info.ctl_name)) {
+ PyErr_SetString(PyExc_ValueError,
+ "provided string is too long");
+ Py_DECREF(ctl_name);
+ return 0;
+ }
+ strncpy(info.ctl_name, PyBytes_AS_STRING(ctl_name),
+ sizeof(info.ctl_name));
+ Py_DECREF(ctl_name);
+
+ if (ioctl(s->sock_fd, CTLIOCGINFO, &info)) {
+ PyErr_SetString(PyExc_OSError,
+ "cannot find kernel control with provided name");
+ return 0;
+ }
+
+ addr->sc_id = info.ctl_id;
+ addr->sc_unit = 0;
+ } else if (!PyArg_ParseTuple(args, "II",
+ &(addr->sc_id), &(addr->sc_unit))) {
+ PyErr_SetString(PyExc_TypeError, "getsockaddrarg: "
+ "expected str or tuple of two ints");
+
+ return 0;
+ }
+
+ *len_ret = sizeof(*addr);
+ return 1;
+ }
+#endif
+ default:
+ PyErr_SetString(PyExc_OSError,
+ "getsockaddrarg: unsupported PF_SYSTEM protocol");
+ return 0;
+ }
+#endif

/* More cases here... */

@@ -1783,6 +1863,21 @@
return 1;
}
#endif
+
+#ifdef PF_SYSTEM
+ case PF_SYSTEM:
+ switch(s->sock_proto) {
+#ifdef SYSPROTO_CONTROL
+ case SYSPROTO_CONTROL:
+ *len_ret = sizeof (struct sockaddr_ctl);
+ return 1;
+#endif
+ default:
+ PyErr_SetString(PyExc_OSError, "getsockaddrlen: "
+ "unknown PF_SYSTEM protocol");
+ return 0;
+ }
+#endif

/* More cases here... */

@@ -5660,6 +5755,14 @@
PyModule_AddIntConstant(m, "PF_RDS", PF_RDS);
#endif

+/* Kernel event messages */
+#ifdef PF_SYSTEM
+ PyModule_AddIntConstant(m, "PF_SYSTEM", PF_SYSTEM);
+#endif
+#ifdef AF_SYSTEM
+ PyModule_AddIntConstant(m, "AF_SYSTEM", AF_SYSTEM);
+#endif
+
#ifdef AF_PACKET
PyModule_AddIntMacro(m, AF_PACKET);
#endif
@@ -6096,6 +6199,10 @@
PyModule_AddIntConstant(m, "IPPROTO_MAX", IPPROTO_MAX);
#endif

+#ifdef SYSPROTO_CONTROL
+ PyModule_AddIntConstant(m, "SYSPROTO_CONTROL", SYSPROTO_CONTROL);
+#endif
+
/* Some port configuration */
#ifdef IPPORT_RESERVED
PyModule_AddIntConstant(m, "IPPORT_RESERVED", IPPORT_RESERVED);
diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h
--- a/Modules/socketmodule.h
+++ b/Modules/socketmodule.h
@@ -80,6 +80,13 @@
#include <linux/can/raw.h>
#endif

+#ifdef HAVE_SYS_SYS_DOMAIN_H
+#include <sys/sys_domain.h>
+#endif
+#ifdef HAVE_SYS_KERN_CONTROL_H
+#include <sys/kern_control.h>
+#endif
+
#ifndef Py__SOCKET_H
#define Py__SOCKET_H
#ifdef __cplusplus
@@ -138,6 +145,9 @@
#ifdef HAVE_LINUX_CAN_H
struct sockaddr_can can;
#endif
+#ifdef HAVE_SYS_KERN_CONTROL_H
+ struct sockaddr_ctl ctl;
+#endif
} sock_addr_t;

/* The object holding a socket. It holds some extra information,
diff --git a/configure b/configure
--- a/configure
+++ b/configure
@@ -6144,10 +6144,10 @@
sched.h shadow.h signal.h stdint.h stropts.h termios.h \
unistd.h utime.h \
poll.h sys/devpoll.h sys/epoll.h sys/poll.h \
-sys/audioio.h sys/xattr.h sys/bsdtty.h sys/event.h sys/file.h sys/loadavg.h \
-sys/lock.h sys/mkdev.h sys/modem.h \
+sys/audioio.h sys/xattr.h sys/bsdtty.h sys/event.h sys/file.h \
+sys/kern_control.h sys/loadavg.h sys/lock.h sys/mkdev.h sys/modem.h \
sys/param.h sys/select.h sys/sendfile.h sys/socket.h sys/statvfs.h \
-sys/stat.h sys/syscall.h sys/termio.h sys/time.h \
+sys/stat.h sys/syscall.h sys/sys_domain.h sys/termio.h sys/time.h \
sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \
libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \
bluetooth/bluetooth.h linux/tipc.h spawn.h util.h
diff --git a/configure.in b/configure.in
--- a/configure.in
+++ b/configure.in
@@ -1334,10 +1334,10 @@
sched.h shadow.h signal.h stdint.h stropts.h termios.h \
unistd.h utime.h \
poll.h sys/devpoll.h sys/epoll.h sys/poll.h \
-sys/audioio.h sys/xattr.h sys/bsdtty.h sys/event.h sys/file.h sys/loadavg.h \
-sys/lock.h sys/mkdev.h sys/modem.h \
+sys/audioio.h sys/xattr.h sys/bsdtty.h sys/event.h sys/file.h \
+sys/kern_control.h sys/loadavg.h sys/lock.h sys/mkdev.h sys/modem.h \
sys/param.h sys/select.h sys/sendfile.h sys/socket.h sys/statvfs.h \
-sys/stat.h sys/syscall.h sys/termio.h sys/time.h \
+sys/stat.h sys/syscall.h sys/sys_domain.h sys/termio.h sys/time.h \
sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \
libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \
bluetooth/bluetooth.h linux/tipc.h spawn.h util.h)
diff --git a/pyconfig.h.in b/pyconfig.h.in
--- a/pyconfig.h.in
+++ b/pyconfig.h.in
@@ -908,6 +908,9 @@
/* Define to 1 if you have the <sys/file.h> header file. */
#undef HAVE_SYS_FILE_H

+/* Define to 1 if you have the <sys/kern_control.h> header file. */
+#undef HAVE_SYS_KERN_CONTROL_H
+
/* Define to 1 if you have the <sys/loadavg.h> header file. */
#undef HAVE_SYS_LOADAVG_H

@@ -951,6 +954,9 @@
/* Define to 1 if you have the <sys/syscall.h> header file. */
#undef HAVE_SYS_SYSCALL_H

+/* Define to 1 if you have the <sys/sys_domain.h> header file. */
+#undef HAVE_SYS_SYS_DOMAIN_H
+
/* Define to 1 if you have the <sys/termio.h> header file. */
#undef HAVE_SYS_TERMIO_H


--
Repository URL: http://hg.python.org/cpython
cpython (merge default -> default): Merge [ In reply to ]
http://hg.python.org/cpython/rev/62b183035ed6
changeset: 74817:62b183035ed6
parent: 74816:7d4525a96cf2
parent: 74815:140f7de4d2a5
user: Brett Cannon <brett@python.org>
date: Tue Feb 07 09:20:20 2012 -0500
summary:
Merge

files:
Doc/library/os.rst | 2 +-
Doc/whatsnew/3.3.rst | 2 +-
Lib/os.py | 2 +-
Lib/test/test_os.py | 4 ++--
Lib/test/test_posix.py | 8 ++++----
Misc/NEWS | 5 ++++-
Modules/posixmodule.c | 10 +++++-----
7 files changed, 18 insertions(+), 15 deletions(-)


diff --git a/Doc/library/os.rst b/Doc/library/os.rst
--- a/Doc/library/os.rst
+++ b/Doc/library/os.rst
@@ -769,7 +769,7 @@
.. versionadded:: 3.3


-.. function:: fdlistdir(fd)
+.. function:: flistdir(fd)

Like :func:`listdir`, but uses a file descriptor instead and always returns
strings.
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
@@ -571,7 +571,7 @@

* Other new functions:

- * :func:`~os.fdlistdir` (:issue:`10755`)
+ * :func:`~os.flistdir` (:issue:`10755`)
* :func:`~os.getgrouplist` (:issue:`9344`)


diff --git a/Lib/os.py b/Lib/os.py
--- a/Lib/os.py
+++ b/Lib/os.py
@@ -357,7 +357,7 @@
# whether to follow symlinks
flag = 0 if followlinks else AT_SYMLINK_NOFOLLOW

- names = fdlistdir(topfd)
+ names = flistdir(topfd)
dirs, nondirs = [], []
for name in names:
# Here, we don't use AT_SYMLINK_NOFOLLOW to be consistent with
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -611,8 +611,8 @@
for root, dirs, files, rootfd in os.fwalk(*args):
# check that the FD is valid
os.fstat(rootfd)
- # check that fdlistdir() returns consistent information
- self.assertEqual(set(os.fdlistdir(rootfd)), set(dirs) | set(files))
+ # check that flistdir() returns consistent information
+ self.assertEqual(set(os.flistdir(rootfd)), set(dirs) | set(files))

def test_fd_leak(self):
# Since we're opening a lot of FDs, we must be careful to avoid leaks:
diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py
--- a/Lib/test/test_posix.py
+++ b/Lib/test/test_posix.py
@@ -451,18 +451,18 @@
if hasattr(posix, 'listdir'):
self.assertTrue(support.TESTFN in posix.listdir())

- @unittest.skipUnless(hasattr(posix, 'fdlistdir'), "test needs posix.fdlistdir()")
- def test_fdlistdir(self):
+ @unittest.skipUnless(hasattr(posix, 'flistdir'), "test needs posix.flistdir()")
+ def test_flistdir(self):
f = posix.open(posix.getcwd(), posix.O_RDONLY)
self.addCleanup(posix.close, f)
self.assertEqual(
sorted(posix.listdir('.')),
- sorted(posix.fdlistdir(f))
+ sorted(posix.flistdir(f))
)
# Check that the fd offset was reset (issue #13739)
self.assertEqual(
sorted(posix.listdir('.')),
- sorted(posix.fdlistdir(f))
+ sorted(posix.flistdir(f))
)

def test_access(self):
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -466,6 +466,9 @@
Library
-------

+- Issue #10811: Fix recursive usage of cursors. Instead of crashing,
+ raise a ProgrammingError now.
+
- Issue #10881: Fix test_site failure with OS X framework builds.

- Issue #964437 Make IDLE help window non-modal.
@@ -1745,7 +1748,7 @@

- Issue #11297: Add collections.ChainMap().

-- Issue #10755: Add the posix.fdlistdir() function. Patch by Ross Lagerwall.
+- Issue #10755: Add the posix.flistdir() function. Patch by Ross Lagerwall.

- Issue #4761: Add the *at() family of functions (openat(), etc.) to the posix
module. Patch by Ross Lagerwall.
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -2867,12 +2867,12 @@
} /* end of posix_listdir */

#ifdef HAVE_FDOPENDIR
-PyDoc_STRVAR(posix_fdlistdir__doc__,
-"fdlistdir(fd) -> list_of_strings\n\n\
+PyDoc_STRVAR(posix_flistdir__doc__,
+"flistdir(fd) -> list_of_strings\n\n\
Like listdir(), but uses a file descriptor instead.");

static PyObject *
-posix_fdlistdir(PyObject *self, PyObject *args)
+posix_flistdir(PyObject *self, PyObject *args)
{
PyObject *d, *v;
DIR *dirp;
@@ -2880,7 +2880,7 @@
int fd;

errno = 0;
- if (!PyArg_ParseTuple(args, "i:fdlistdir", &fd))
+ if (!PyArg_ParseTuple(args, "i:flistdir", &fd))
return NULL;
/* closedir() closes the FD, so we duplicate it */
fd = dup(fd);
@@ -10555,7 +10555,7 @@
#endif /* HAVE_LINK */
{"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
#ifdef HAVE_FDOPENDIR
- {"fdlistdir", posix_fdlistdir, METH_VARARGS, posix_fdlistdir__doc__},
+ {"flistdir", posix_flistdir, METH_VARARGS, posix_flistdir__doc__},
#endif
{"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
{"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},

--
Repository URL: http://hg.python.org/cpython
cpython (merge default -> default): Merge [ In reply to ]
http://hg.python.org/cpython/rev/e9d01c5c92ed
changeset: 74966:e9d01c5c92ed
parent: 74964:9ab501b3e22d
parent: 74962:170a224ce01e
user: Antoine Pitrou <solipsis@pitrou.net>
date: Wed Feb 15 22:30:29 2012 +0100
summary:
Merge

files:
Lib/test/test_pep3120.py | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)


diff --git a/Lib/test/test_pep3120.py b/Lib/test/test_pep3120.py
--- a/Lib/test/test_pep3120.py
+++ b/Lib/test/test_pep3120.py
@@ -19,8 +19,8 @@
try:
import test.badsyntax_pep3120
except SyntaxError as msg:
- msg = str(msg).lower()
- self.assertTrue('utf-8' in msg or 'utf8' in msg)
+ msg = str(msg)
+ self.assertTrue('Non-UTF-8 code starting with' in msg)
else:
self.fail("expected exception didn't occur")


--
Repository URL: http://hg.python.org/cpython
cpython (merge default -> default): Merge [ In reply to ]
http://hg.python.org/cpython/rev/83e833f70977
changeset: 74993:83e833f70977
parent: 74992:45a2bbf6c752
parent: 74991:cdc9e0238b1d
user: Brett Cannon <brett@python.org>
date: Thu Feb 16 18:03:47 2012 -0500
summary:
Merge

files:
Doc/includes/sqlite3/shortcut_methods.py | 3 +-
Doc/library/sqlite3.rst | 11 ++--
Lib/test/test_sched.py | 28 ++++++-----
Lib/test/test_xml_etree.py | 8 +---
Lib/test/test_xml_etree_c.py | 5 +-
Lib/xml/etree/ElementTree.py | 2 +
Misc/NEWS | 4 +-
7 files changed, 30 insertions(+), 31 deletions(-)


diff --git a/Doc/includes/sqlite3/shortcut_methods.py b/Doc/includes/sqlite3/shortcut_methods.py
--- a/Doc/includes/sqlite3/shortcut_methods.py
+++ b/Doc/includes/sqlite3/shortcut_methods.py
@@ -17,5 +17,4 @@
for row in con.execute("select firstname, lastname from person"):
print(row)

-# Using a dummy WHERE clause to not let SQLite take the shortcut table deletes.
-print("I just deleted", con.execute("delete from person where 1=1").rowcount, "rows")
+print("I just deleted", con.execute("delete from person").rowcount, "rows")
diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst
--- a/Doc/library/sqlite3.rst
+++ b/Doc/library/sqlite3.rst
@@ -555,18 +555,17 @@
attribute, the database engine's own support for the determination of "rows
affected"/"rows selected" is quirky.

- For ``DELETE`` statements, SQLite reports :attr:`rowcount` as 0 if you make a
- ``DELETE FROM table`` without any condition.
-
For :meth:`executemany` statements, the number of modifications are summed up
into :attr:`rowcount`.

As required by the Python DB API Spec, the :attr:`rowcount` attribute "is -1 in
case no ``executeXX()`` has been performed on the cursor or the rowcount of the
- last operation is not determinable by the interface".
+ last operation is not determinable by the interface". This includes ``SELECT``
+ statements because we cannot determine the number of rows a query produced
+ until all rows were fetched.

- This includes ``SELECT`` statements because we cannot determine the number of
- rows a query produced until all rows were fetched.
+ With SQLite versions before 3.6.5, :attr:`rowcount` is set to 0 if
+ you make a ``DELETE FROM table`` without any condition.

.. attribute:: Cursor.lastrowid

diff --git a/Lib/test/test_sched.py b/Lib/test/test_sched.py
--- a/Lib/test/test_sched.py
+++ b/Lib/test/test_sched.py
@@ -12,10 +12,10 @@
l = []
fun = lambda x: l.append(x)
scheduler = sched.scheduler(time.time, time.sleep)
- for x in [0.05, 0.04, 0.03, 0.02, 0.01]:
+ for x in [0.5, 0.4, 0.3, 0.2, 0.1]:
z = scheduler.enter(x, 1, fun, (x,))
scheduler.run()
- self.assertEqual(l, [0.01, 0.02, 0.03, 0.04, 0.05])
+ self.assertEqual(l, [0.1, 0.2, 0.3, 0.4, 0.5])

def test_enterabs(self):
l = []
@@ -31,7 +31,7 @@
fun = lambda x: l.append(x)
scheduler = sched.scheduler(time.time, time.sleep)
for priority in [1, 2, 3, 4, 5]:
- z = scheduler.enter(0.01, priority, fun, (priority,))
+ z = scheduler.enterabs(0.01, priority, fun, (priority,))
scheduler.run()
self.assertEqual(l, [1, 2, 3, 4, 5])

@@ -39,11 +39,12 @@
l = []
fun = lambda x: l.append(x)
scheduler = sched.scheduler(time.time, time.sleep)
- event1 = scheduler.enter(0.01, 1, fun, (0.01,))
- event2 = scheduler.enter(0.02, 1, fun, (0.02,))
- event3 = scheduler.enter(0.03, 1, fun, (0.03,))
- event4 = scheduler.enter(0.04, 1, fun, (0.04,))
- event5 = scheduler.enter(0.05, 1, fun, (0.05,))
+ now = time.time()
+ event1 = scheduler.enterabs(now + 0.01, 1, fun, (0.01,))
+ event2 = scheduler.enterabs(now + 0.02, 1, fun, (0.02,))
+ event3 = scheduler.enterabs(now + 0.03, 1, fun, (0.03,))
+ event4 = scheduler.enterabs(now + 0.04, 1, fun, (0.04,))
+ event5 = scheduler.enterabs(now + 0.05, 1, fun, (0.05,))
scheduler.cancel(event1)
scheduler.cancel(event5)
scheduler.run()
@@ -64,11 +65,12 @@
l = []
fun = lambda x: l.append(x)
scheduler = sched.scheduler(time.time, time.sleep)
- e5 = scheduler.enter(0.05, 1, fun)
- e1 = scheduler.enter(0.01, 1, fun)
- e2 = scheduler.enter(0.02, 1, fun)
- e4 = scheduler.enter(0.04, 1, fun)
- e3 = scheduler.enter(0.03, 1, fun)
+ now = time.time()
+ e5 = scheduler.enterabs(now + 0.05, 1, fun)
+ e1 = scheduler.enterabs(now + 0.01, 1, fun)
+ e2 = scheduler.enterabs(now + 0.02, 1, fun)
+ e4 = scheduler.enterabs(now + 0.04, 1, fun)
+ e3 = scheduler.enterabs(now + 0.03, 1, fun)
# queue property is supposed to return an order list of
# upcoming events
self.assertEqual(list(scheduler.queue), [e1, e2, e3, e4, e5])
diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py
--- a/Lib/test/test_xml_etree.py
+++ b/Lib/test/test_xml_etree.py
@@ -1352,7 +1352,6 @@
r"""
Basic inclusion example (XInclude C.1)

- >>> from xml.etree import ElementTree as ET
>>> from xml.etree import ElementInclude

>>> document = xinclude_loader("C1.xml")
@@ -1882,12 +1881,7 @@

def __enter__(self):
from xml.etree import ElementPath
- if hasattr(ET, '_namespace_map'):
- self._nsmap = ET._namespace_map
- else:
- # when testing the cElementTree alias
- from xml.etree.ElementTree import _namespace_map
- self._nsmap = _namespace_map
+ self._nsmap = ET.register_namespace._namespace_map
# Copy the default namespace mapping
self._nsmap_copy = self._nsmap.copy()
# Copy the path cache (should be empty)
diff --git a/Lib/test/test_xml_etree_c.py b/Lib/test/test_xml_etree_c.py
--- a/Lib/test/test_xml_etree_c.py
+++ b/Lib/test/test_xml_etree_c.py
@@ -5,7 +5,7 @@
import unittest

cET = import_fresh_module('xml.etree.ElementTree', fresh=['_elementtree'])
-cET_alias = import_fresh_module('xml.etree.cElementTree', fresh=['_elementtree'])
+cET_alias = import_fresh_module('xml.etree.cElementTree', fresh=['_elementtree', 'xml.etree'])


# cElementTree specific tests
@@ -52,6 +52,9 @@
def test_correct_import_cET(self):
self.assertEqual(cET.Element.__module__, '_elementtree')

+ def test_correct_import_cET_alias(self):
+ self.assertEqual(cET_alias.Element.__module__, '_elementtree')
+

def test_main():
from test import test_xml_etree, test_xml_etree_c
diff --git a/Lib/xml/etree/ElementTree.py b/Lib/xml/etree/ElementTree.py
--- a/Lib/xml/etree/ElementTree.py
+++ b/Lib/xml/etree/ElementTree.py
@@ -1086,6 +1086,8 @@
# dublin core
"http://purl.org/dc/elements/1.1/": "dc",
}
+# For tests and troubleshooting
+register_namespace._namespace_map = _namespace_map

def _raise_serialization_error(text):
raise TypeError(
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -2261,8 +2261,8 @@
Documentation
-------------

-- Issue #13491: Fix many errors in sqlite3 documentation. Initial
- patch by Johannes Vogel.
+- Issues #13491 and #13995: Fix many errors in sqlite3 documentation.
+ Initial patch for #13491 by Johannes Vogel.

- Issue #13402: Document absoluteness of sys.executable.


--
Repository URL: http://hg.python.org/cpython
cpython (merge default -> default): Merge [ In reply to ]
http://hg.python.org/cpython/rev/dee36bfa3f8f
changeset: 75049:dee36bfa3f8f
parent: 75048:bbaab666e6c7
parent: 75047:efd299a3eb7d
user: Antoine Pitrou <solipsis@pitrou.net>
date: Mon Feb 20 01:52:17 2012 +0100
summary:
Merge

files:
Doc/library/argparse.rst | 31 ++++++++++++++-------------
1 files changed, 16 insertions(+), 15 deletions(-)


diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst
--- a/Doc/library/argparse.rst
+++ b/Doc/library/argparse.rst
@@ -739,7 +739,7 @@

* ``'version'`` - This expects a ``version=`` keyword argument in the
:meth:`~ArgumentParser.add_argument` call, and prints version information
- and exits when invoked.
+ and exits when invoked::

>>> import argparse
>>> parser = argparse.ArgumentParser(prog='PROG')
@@ -791,8 +791,8 @@
different number of command-line arguments with a single action. The supported
values are:

-* ``N`` (an integer). ``N`` arguments from the command line will be gathered together into a
- list. For example::
+* ``N`` (an integer). ``N`` arguments from the command line will be gathered
+ together into a list. For example::

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', nargs=2)
@@ -861,7 +861,7 @@

* ``argparse.REMAINDER``. All the remaining command-line arguments are gathered
into a list. This is commonly useful for command line utilities that dispatch
- to other command line utilities.
+ to other command line utilities::

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo')
@@ -884,7 +884,8 @@

* When :meth:`~ArgumentParser.add_argument` is called with
``action='store_const'`` or ``action='append_const'``. These actions add the
- ``const`` value to one of the attributes of the object returned by :meth:`~ArgumentParser.parse_args`. See the action_ description for examples.
+ ``const`` value to one of the attributes of the object returned by
+ :meth:`~ArgumentParser.parse_args`. See the action_ description for examples.

* When :meth:`~ArgumentParser.add_argument` is called with option strings
(like ``-f`` or ``--foo``) and ``nargs='?'``. This creates an optional
@@ -1595,21 +1596,21 @@
The :class:`FileType` factory creates objects that can be passed to the type
argument of :meth:`ArgumentParser.add_argument`. Arguments that have
:class:`FileType` objects as their type will open command-line arguments as files
- with the requested modes and buffer sizes:
+ with the requested modes and buffer sizes::

- >>> parser = argparse.ArgumentParser()
- >>> parser.add_argument('--output', type=argparse.FileType('wb', 0))
- >>> parser.parse_args(['--output', 'out'])
- Namespace(output=<_io.BufferedWriter name='out'>)
+ >>> parser = argparse.ArgumentParser()
+ >>> parser.add_argument('--output', type=argparse.FileType('wb', 0))
+ >>> parser.parse_args(['--output', 'out'])
+ Namespace(output=<_io.BufferedWriter name='out'>)

FileType objects understand the pseudo-argument ``'-'`` and automatically
convert this into ``sys.stdin`` for readable :class:`FileType` objects and
- ``sys.stdout`` for writable :class:`FileType` objects:
+ ``sys.stdout`` for writable :class:`FileType` objects::

- >>> parser = argparse.ArgumentParser()
- >>> parser.add_argument('infile', type=argparse.FileType('r'))
- >>> parser.parse_args(['-'])
- Namespace(infile=<_io.TextIOWrapper name='<stdin>' encoding='UTF-8'>)
+ >>> parser = argparse.ArgumentParser()
+ >>> parser.add_argument('infile', type=argparse.FileType('r'))
+ >>> parser.parse_args(['-'])
+ Namespace(infile=<_io.TextIOWrapper name='<stdin>' encoding='UTF-8'>)


Argument groups

--
Repository URL: http://hg.python.org/cpython
cpython (merge default -> default): Merge [ In reply to ]
http://hg.python.org/cpython/rev/6f578f73d14a
changeset: 75194:6f578f73d14a
parent: 75193:f95faebf5dea
parent: 75192:8c9638f0587a
user: Brett Cannon <brett@python.org>
date: Thu Feb 23 10:17:56 2012 -0500
summary:
Merge

files:
Lib/test/test_zlib.py | 36 ++++++------------------------
1 files changed, 7 insertions(+), 29 deletions(-)


diff --git a/Lib/test/test_zlib.py b/Lib/test/test_zlib.py
--- a/Lib/test/test_zlib.py
+++ b/Lib/test/test_zlib.py
@@ -7,11 +7,6 @@

zlib = support.import_module('zlib')

-try:
- import mmap
-except ImportError:
- mmap = None
-

class VersionTestCase(unittest.TestCase):

@@ -77,24 +72,11 @@
# Issue #10276 - check that inputs >=4GB are handled correctly.
class ChecksumBigBufferTestCase(unittest.TestCase):

- def setUp(self):
- with open(support.TESTFN, "wb+") as f:
- f.seek(_4G)
- f.write(b"asdf")
- f.flush()
- self.mapping = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
-
- def tearDown(self):
- self.mapping.close()
- support.unlink(support.TESTFN)
-
- @unittest.skipUnless(mmap, "mmap() is not available.")
- @unittest.skipUnless(sys.maxsize > _4G, "Can't run on a 32-bit system.")
- @unittest.skipUnless(support.is_resource_enabled("largefile"),
- "May use lots of disk space.")
- def test_big_buffer(self):
- self.assertEqual(zlib.crc32(self.mapping), 3058686908)
- self.assertEqual(zlib.adler32(self.mapping), 82837919)
+ @bigmemtest(size=_4G + 4, memuse=1, dry_run=False)
+ def test_big_buffer(self, size):
+ data = b"nyan" * (_1G + 1)
+ self.assertEqual(zlib.crc32(data), 1044521549)
+ self.assertEqual(zlib.adler32(data), 2256789997)


class ExceptionTestCase(unittest.TestCase):
@@ -197,10 +179,8 @@
def test_big_decompress_buffer(self, size):
self.check_big_decompress_buffer(size, zlib.decompress)

- @bigmemtest(size=_4G + 100, memuse=1)
+ @bigmemtest(size=_4G + 100, memuse=1, dry_run=False)
def test_length_overflow(self, size):
- if size < _4G + 100:
- self.skipTest("not enough free memory, need at least 4 GB")
data = b'x' * size
try:
self.assertRaises(OverflowError, zlib.compress, data, 1)
@@ -554,10 +534,8 @@
decompress = lambda s: d.decompress(s) + d.flush()
self.check_big_decompress_buffer(size, decompress)

- @bigmemtest(size=_4G + 100, memuse=1)
+ @bigmemtest(size=_4G + 100, memuse=1, dry_run=False)
def test_length_overflow(self, size):
- if size < _4G + 100:
- self.skipTest("not enough free memory, need at least 4 GB")
data = b'x' * size
c = zlib.compressobj(1)
d = zlib.decompressobj()

--
Repository URL: http://hg.python.org/cpython
cpython (merge default -> default): merge [ In reply to ]
http://hg.python.org/cpython/rev/548a023c8230
changeset: 75230:548a023c8230
parent: 75229:8d1040fdac60
parent: 75227:50b1f2d07011
user: Brett Cannon <brett@python.org>
date: Thu Feb 23 18:30:04 2012 -0500
summary:
merge

files:
.hgtags | 1 +
Doc/library/subprocess.rst | 2 +-
Doc/library/sys.rst | 5 +-
Doc/library/time.rst | 5 +-
Lib/logging/__init__.py | 28 ++++++++----
Lib/logging/handlers.py | 53 +++++++++++++++++--------
6 files changed, 62 insertions(+), 32 deletions(-)


diff --git a/.hgtags b/.hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -77,6 +77,7 @@
a4f75773c0060cee38b0bb651a7aba6f56b0e996 v3.1.3
32fcb9e94985cb19ce37ba9543f091c0dbe9d7dd v3.1.4rc1
c918ec9f3a76d6afedfbb5d455004de880443a3d v3.1.4
+ee26aca3219cf4bb0b93352e83edcc9cb28c7802 v3.1.5rc1
b37b7834757492d009b99cf0ca4d42d2153d7fac v3.2a1
56d4373cecb73c8b45126ba7b045b3c7b3f94b0b v3.2a2
da012d9a2c23d144e399d2e01a55b8a83ad94573 v3.2a3
diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst
--- a/Doc/library/subprocess.rst
+++ b/Doc/library/subprocess.rst
@@ -240,7 +240,7 @@
When *stdout* or *stderr* are pipes and *universal_newlines* is
:const:`True` then the output data is assumed to be encoded as UTF-8 and
will automatically be decoded to text. All line endings will be converted
- to ``'\n'`` as described for the universal newlines `'U'`` mode argument
+ to ``'\n'`` as described for the universal newlines ``'U'`` mode argument
to :func:`open`.

If *shell* is :const:`True`, the specified command will be executed through
diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst
--- a/Doc/library/sys.rst
+++ b/Doc/library/sys.rst
@@ -195,7 +195,7 @@
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
- :file:`{exec_prefix}/lib/python{X.Y}/config', and shared library modules are
+ :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``.

@@ -756,6 +756,7 @@
always use the ``startswith`` idiom presented above.

.. seealso::
+
:attr:`os.name` has a coarser granularity. :func:`os.uname` gives
system-dependent version information.

@@ -771,7 +772,7 @@
argument to the :program:`configure` script. The main collection of Python
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 :file:`{prefix}/include/python{X.Y}``, where *X.Y* is the version
+ stored in :file:`{prefix}/include/python{X.Y}`, where *X.Y* is the version
number of Python, for example ``3.2``.


diff --git a/Doc/library/time.rst b/Doc/library/time.rst
--- a/Doc/library/time.rst
+++ b/Doc/library/time.rst
@@ -228,8 +228,9 @@

.. function:: monotonic()

- Monotonic clock. The reference point of the returned value is undefined so
- only the difference of consecutive calls is valid.
+ Monotonic non-decreasing clock. The clock is not related to the system clock
+ and cannot go backward. The reference point of the returned
+ value is undefined so only the difference of consecutive calls is valid.

.. versionadded:: 3.3

diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py
--- a/Lib/logging/__init__.py
+++ b/Lib/logging/__init__.py
@@ -16,9 +16,9 @@

"""
Logging package for Python. Based on PEP 282 and comments thereto in
-comp.lang.python, and influenced by Apache's log4j system.
+comp.lang.python.

-Copyright (C) 2001-2011 Vinay Sajip. All Rights Reserved.
+Copyright (C) 2001-2012 Vinay Sajip. All Rights Reserved.

To use, simply 'import logging' and log away!
"""
@@ -914,8 +914,12 @@
"""
Flushes the stream.
"""
- if self.stream and hasattr(self.stream, "flush"):
- self.stream.flush()
+ self.acquire()
+ try:
+ if self.stream and hasattr(self.stream, "flush"):
+ self.stream.flush()
+ finally:
+ self.release()

def emit(self, record):
"""
@@ -964,12 +968,16 @@
"""
Closes the stream.
"""
- if self.stream:
- self.flush()
- if hasattr(self.stream, "close"):
- self.stream.close()
- StreamHandler.close(self)
- self.stream = None
+ self.acquire()
+ try:
+ if self.stream:
+ self.flush()
+ if hasattr(self.stream, "close"):
+ self.stream.close()
+ StreamHandler.close(self)
+ self.stream = None
+ finally:
+ self.release()

def _open(self):
"""
diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py
--- a/Lib/logging/handlers.py
+++ b/Lib/logging/handlers.py
@@ -1,4 +1,4 @@
-# Copyright 2001-2010 by Vinay Sajip. All Rights Reserved.
+# Copyright 2001-2012 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
@@ -16,10 +16,9 @@

"""
Additional handlers for the logging package for Python. The core package is
-based on PEP 282 and comments thereto in comp.lang.python, and influenced by
-Apache's log4j system.
+based on PEP 282 and comments thereto in comp.lang.python.

-Copyright (C) 2001-2010 Vinay Sajip. All Rights Reserved.
+Copyright (C) 2001-2012 Vinay Sajip. All Rights Reserved.

To use, simply 'import logging.handlers' and log away!
"""
@@ -594,10 +593,14 @@
"""
Closes the socket.
"""
- if self.sock:
- self.sock.close()
- self.sock = None
- logging.Handler.close(self)
+ self.acquire()
+ try:
+ if self.sock:
+ self.sock.close()
+ self.sock = None
+ logging.Handler.close(self)
+ finally:
+ self.release()

class DatagramHandler(SocketHandler):
"""
@@ -792,8 +795,12 @@
"""
Closes the socket.
"""
- self.socket.close()
- logging.Handler.close(self)
+ self.acquire()
+ try:
+ self.socket.close()
+ logging.Handler.close(self)
+ finally:
+ self.release()

def mapPriority(self, levelName):
"""
@@ -1137,7 +1144,11 @@

This version just zaps the buffer to empty.
"""
- self.buffer = []
+ self.acquire()
+ try:
+ self.buffer = []
+ finally:
+ self.release()

def close(self):
"""
@@ -1187,18 +1198,26 @@

The record buffer is also cleared by this operation.
"""
- if self.target:
- for record in self.buffer:
- self.target.handle(record)
- self.buffer = []
+ self.acquire()
+ try:
+ if self.target:
+ for record in self.buffer:
+ self.target.handle(record)
+ self.buffer = []
+ finally:
+ self.release()

def close(self):
"""
Flush, set the target to None and lose the buffer.
"""
self.flush()
- self.target = None
- BufferingHandler.close(self)
+ self.acquire()
+ try:
+ self.target = None
+ BufferingHandler.close(self)
+ finally:
+ self.release()


class QueueHandler(logging.Handler):

--
Repository URL: http://hg.python.org/cpython
cpython (merge default -> default): merge [ In reply to ]
http://hg.python.org/cpython/rev/e394e62473ee
changeset: 75233:e394e62473ee
parent: 75232:2e7a042a4760
parent: 75231:f89e2f4cda88
user: Brett Cannon <brett@python.org>
date: Thu Feb 23 19:34:55 2012 -0500
summary:
merge

files:
Include/unicodeobject.h | 18 +--
Lib/test/test_format.py | 15 ++
Objects/stringlib/asciilib.h | 3 -
Objects/stringlib/localeutil.h | 71 +++------
Objects/stringlib/stringdefs.h | 2 -
Objects/stringlib/ucs1lib.h | 3 -
Objects/stringlib/ucs2lib.h | 3 -
Objects/stringlib/ucs4lib.h | 3 -
Objects/stringlib/undef.h | 2 +-
Objects/stringlib/unicodedefs.h | 2 -
Objects/unicodeobject.c | 77 ++++++++--
Python/formatter_unicode.c | 142 ++++++++++++-------
12 files changed, 189 insertions(+), 152 deletions(-)


diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h
--- a/Include/unicodeobject.h
+++ b/Include/unicodeobject.h
@@ -1936,32 +1936,20 @@
);
#endif

-/* Using the current locale, insert the thousands grouping
- into the string pointed to by buffer. For the argument descriptions,
- see Objects/stringlib/localeutil.h */
-
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(Py_ssize_t) _PyUnicode_InsertThousandsGroupingLocale(Py_UNICODE *buffer,
- Py_ssize_t n_buffer,
- Py_UNICODE *digits,
- Py_ssize_t n_digits,
- Py_ssize_t min_width);
-#endif
-
/* Using explicit passed-in values, insert the thousands grouping
into the string pointed to by buffer. For the argument descriptions,
see Objects/stringlib/localeutil.h */
#ifndef Py_LIMITED_API
PyAPI_FUNC(Py_ssize_t) _PyUnicode_InsertThousandsGrouping(
PyObject *unicode,
- int kind,
- void *buffer,
+ Py_ssize_t index,
Py_ssize_t n_buffer,
void *digits,
Py_ssize_t n_digits,
Py_ssize_t min_width,
const char *grouping,
- const char *thousands_sep);
+ PyObject *thousands_sep,
+ Py_UCS4 *maxchar);
#endif
/* === Characters Type APIs =============================================== */

diff --git a/Lib/test/test_format.py b/Lib/test/test_format.py
--- a/Lib/test/test_format.py
+++ b/Lib/test/test_format.py
@@ -1,4 +1,5 @@
from test.support import verbose, TestFailed
+import locale
import sys
import test.support as support
import unittest
@@ -282,6 +283,20 @@
self.assertEqual(format(1+2j, "\u2007^8"), "\u2007(1+2j)\u2007")
self.assertEqual(format(0j, "\u2007^4"), "\u20070j\u2007")

+ def test_locale(self):
+ try:
+ oldloc = locale.setlocale(locale.LC_ALL, '')
+ except locale.Error as err:
+ self.skipTest("Cannot set locale: {}".format(err))
+ try:
+ sep = locale.localeconv()['thousands_sep']
+ text = format(123456789, "n")
+ self.assertIn(sep, text)
+ self.assertEqual(text.replace(sep, ''), '123456789')
+ finally:
+ locale.setlocale(locale.LC_ALL, oldloc)
+
+

def test_main():
support.run_unittest(FormatTest)
diff --git a/Objects/stringlib/asciilib.h b/Objects/stringlib/asciilib.h
--- a/Objects/stringlib/asciilib.h
+++ b/Objects/stringlib/asciilib.h
@@ -21,12 +21,9 @@
#define STRINGLIB_RESIZE not_supported
#define STRINGLIB_CHECK PyUnicode_Check
#define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact
-#define STRINGLIB_GROUPING _PyUnicode_InsertThousandsGrouping
-#define STRINGLIB_GROUPING_LOCALE _PyUnicode_InsertThousandsGroupingLocale

#define STRINGLIB_TOSTR PyObject_Str
#define STRINGLIB_TOASCII PyObject_ASCII

#define _Py_InsertThousandsGrouping _PyUnicode_ascii_InsertThousandsGrouping
-#define _Py_InsertThousandsGroupingLocale _PyUnicode_ascii_InsertThousandsGroupingLocale

diff --git a/Objects/stringlib/localeutil.h b/Objects/stringlib/localeutil.h
--- a/Objects/stringlib/localeutil.h
+++ b/Objects/stringlib/localeutil.h
@@ -2,8 +2,9 @@

#include <locale.h>

-#define MAX(x, y) ((x) < (y) ? (y) : (x))
-#define MIN(x, y) ((x) < (y) ? (x) : (y))
+#ifndef STRINGLIB_IS_UNICODE
+# error "localeutil is specific to Unicode"
+#endif

typedef struct {
const char *grouping;
@@ -46,7 +47,7 @@
are optional, depending on when we're called. */
static void
STRINGLIB(fill)(STRINGLIB_CHAR **digits_end, STRINGLIB_CHAR **buffer_end,
- Py_ssize_t n_chars, Py_ssize_t n_zeros, const char* thousands_sep,
+ Py_ssize_t n_chars, Py_ssize_t n_zeros, STRINGLIB_CHAR* thousands_sep,
Py_ssize_t thousands_sep_len)
{
Py_ssize_t i;
@@ -55,15 +56,8 @@
*buffer_end -= thousands_sep_len;

/* Copy the thousands_sep chars into the buffer. */
-#if STRINGLIB_IS_UNICODE
- /* Convert from the char's of the thousands_sep from
- the locale into unicode. */
- for (i = 0; i < thousands_sep_len; ++i)
- (*buffer_end)[i] = thousands_sep[i];
-#else
- /* No conversion, just memcpy the thousands_sep. */
- memcpy(*buffer_end, thousands_sep, thousands_sep_len);
-#endif
+ memcpy(*buffer_end, thousands_sep,
+ thousands_sep_len * STRINGLIB_SIZEOF_CHAR);
}

*buffer_end -= n_chars;
@@ -76,7 +70,7 @@
}

/**
- * _Py_InsertThousandsGrouping:
+ * InsertThousandsGrouping:
* @buffer: A pointer to the start of a string.
* @n_buffer: Number of characters in @buffer.
* @digits: A pointer to the digits we're reading from. If count
@@ -106,13 +100,15 @@
_insert_thousands_sep().
**/
Py_ssize_t
-_Py_InsertThousandsGrouping(STRINGLIB_CHAR *buffer,
- Py_ssize_t n_buffer,
- STRINGLIB_CHAR *digits,
- Py_ssize_t n_digits,
- Py_ssize_t min_width,
- const char *grouping,
- const char *thousands_sep)
+STRINGLIB(InsertThousandsGrouping)(
+ STRINGLIB_CHAR *buffer,
+ Py_ssize_t n_buffer,
+ STRINGLIB_CHAR *digits,
+ Py_ssize_t n_digits,
+ Py_ssize_t min_width,
+ const char *grouping,
+ STRINGLIB_CHAR *thousands_sep,
+ Py_ssize_t thousands_sep_len)
{
Py_ssize_t count = 0;
Py_ssize_t n_zeros;
@@ -124,7 +120,6 @@
STRINGLIB_CHAR *digits_end = NULL;
Py_ssize_t l;
Py_ssize_t n_chars;
- Py_ssize_t thousands_sep_len = strlen(thousands_sep);
Py_ssize_t remaining = n_digits; /* Number of chars remaining to
be looked at */
/* A generator that returns all of the grouping widths, until it
@@ -138,9 +133,9 @@
}

while ((l = STRINGLIB(GroupGenerator_next)(&groupgen)) > 0) {
- l = MIN(l, MAX(MAX(remaining, min_width), 1));
- n_zeros = MAX(0, l - remaining);
- n_chars = MAX(0, MIN(remaining, l));
+ l = Py_MIN(l, Py_MAX(Py_MAX(remaining, min_width), 1));
+ n_zeros = Py_MAX(0, l - remaining);
+ n_chars = Py_MAX(0, Py_MIN(remaining, l));

/* Use n_zero zero's and n_chars chars */

@@ -168,9 +163,9 @@
if (!loop_broken) {
/* We left the loop without using a break statement. */

- l = MAX(MAX(remaining, min_width), 1);
- n_zeros = MAX(0, l - remaining);
- n_chars = MAX(0, MIN(remaining, l));
+ l = Py_MAX(Py_MAX(remaining, min_width), 1);
+ n_zeros = Py_MAX(0, l - remaining);
+ n_chars = Py_MAX(0, Py_MIN(remaining, l));

/* Use n_zero zero's and n_chars chars */
count += (use_separator ? thousands_sep_len : 0) + n_zeros + n_chars;
@@ -183,25 +178,3 @@
return count;
}

-/**
- * _Py_InsertThousandsGroupingLocale:
- * @buffer: A pointer to the start of a string.
- * @n_digits: The number of digits in the string, in which we want
- * to put the grouping chars.
- *
- * Reads thee current locale and calls _Py_InsertThousandsGrouping().
- **/
-Py_ssize_t
-_Py_InsertThousandsGroupingLocale(STRINGLIB_CHAR *buffer,
- Py_ssize_t n_buffer,
- STRINGLIB_CHAR *digits,
- Py_ssize_t n_digits,
- Py_ssize_t min_width)
-{
- struct lconv *locale_data = localeconv();
- const char *grouping = locale_data->grouping;
- const char *thousands_sep = locale_data->thousands_sep;
-
- return _Py_InsertThousandsGrouping(buffer, n_buffer, digits, n_digits,
- min_width, grouping, thousands_sep);
-}
diff --git a/Objects/stringlib/stringdefs.h b/Objects/stringlib/stringdefs.h
--- a/Objects/stringlib/stringdefs.h
+++ b/Objects/stringlib/stringdefs.h
@@ -25,7 +25,5 @@
#define STRINGLIB_CHECK PyBytes_Check
#define STRINGLIB_CHECK_EXACT PyBytes_CheckExact
#define STRINGLIB_TOSTR PyObject_Str
-#define STRINGLIB_GROUPING _PyBytes_InsertThousandsGrouping
-#define STRINGLIB_GROUPING_LOCALE _PyBytes_InsertThousandsGroupingLocale
#define STRINGLIB_TOASCII PyObject_Repr
#endif /* !STRINGLIB_STRINGDEFS_H */
diff --git a/Objects/stringlib/ucs1lib.h b/Objects/stringlib/ucs1lib.h
--- a/Objects/stringlib/ucs1lib.h
+++ b/Objects/stringlib/ucs1lib.h
@@ -21,13 +21,10 @@
#define STRINGLIB_RESIZE not_supported
#define STRINGLIB_CHECK PyUnicode_Check
#define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact
-#define STRINGLIB_GROUPING _PyUnicode_InsertThousandsGrouping
-#define STRINGLIB_GROUPING_LOCALE _PyUnicode_InsertThousandsGroupingLocale

#define STRINGLIB_TOSTR PyObject_Str
#define STRINGLIB_TOASCII PyObject_ASCII

#define _Py_InsertThousandsGrouping _PyUnicode_ucs1_InsertThousandsGrouping
-#define _Py_InsertThousandsGroupingLocale _PyUnicode_ucs1_InsertThousandsGroupingLocale


diff --git a/Objects/stringlib/ucs2lib.h b/Objects/stringlib/ucs2lib.h
--- a/Objects/stringlib/ucs2lib.h
+++ b/Objects/stringlib/ucs2lib.h
@@ -21,12 +21,9 @@
#define STRINGLIB_RESIZE not_supported
#define STRINGLIB_CHECK PyUnicode_Check
#define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact
-#define STRINGLIB_GROUPING _PyUnicode_InsertThousandsGrouping
-#define STRINGLIB_GROUPING_LOCALE _PyUnicode_InsertThousandsGroupingLocale

#define STRINGLIB_TOSTR PyObject_Str
#define STRINGLIB_TOASCII PyObject_ASCII

#define _Py_InsertThousandsGrouping _PyUnicode_ucs2_InsertThousandsGrouping
-#define _Py_InsertThousandsGroupingLocale _PyUnicode_ucs2_InsertThousandsGroupingLocale

diff --git a/Objects/stringlib/ucs4lib.h b/Objects/stringlib/ucs4lib.h
--- a/Objects/stringlib/ucs4lib.h
+++ b/Objects/stringlib/ucs4lib.h
@@ -21,12 +21,9 @@
#define STRINGLIB_RESIZE not_supported
#define STRINGLIB_CHECK PyUnicode_Check
#define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact
-#define STRINGLIB_GROUPING _PyUnicode_InsertThousandsGrouping
-#define STRINGLIB_GROUPING_LOCALE _PyUnicode_InsertThousandsGroupingLocale

#define STRINGLIB_TOSTR PyObject_Str
#define STRINGLIB_TOASCII PyObject_ASCII

#define _Py_InsertThousandsGrouping _PyUnicode_ucs4_InsertThousandsGrouping
-#define _Py_InsertThousandsGroupingLocale _PyUnicode_ucs4_InsertThousandsGroupingLocale

diff --git a/Objects/stringlib/undef.h b/Objects/stringlib/undef.h
--- a/Objects/stringlib/undef.h
+++ b/Objects/stringlib/undef.h
@@ -7,5 +7,5 @@
#undef STRINGLIB_NEW
#undef STRINGLIB_RESIZE
#undef _Py_InsertThousandsGrouping
-#undef _Py_InsertThousandsGroupingLocale
+#undef STRINGLIB_IS_UNICODE

diff --git a/Objects/stringlib/unicodedefs.h b/Objects/stringlib/unicodedefs.h
--- a/Objects/stringlib/unicodedefs.h
+++ b/Objects/stringlib/unicodedefs.h
@@ -24,8 +24,6 @@
#define STRINGLIB_RESIZE PyUnicode_Resize
#define STRINGLIB_CHECK PyUnicode_Check
#define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact
-#define STRINGLIB_GROUPING _PyUnicode_InsertThousandsGrouping
-#define STRINGLIB_GROUPING_LOCALE _PyUnicode_InsertThousandsGroupingLocale

#if PY_VERSION_HEX < 0x03000000
#define STRINGLIB_TOSTR PyObject_Unicode
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -9151,34 +9151,75 @@
}

Py_ssize_t
-_PyUnicode_InsertThousandsGrouping(PyObject *unicode, int kind, void *data,
- Py_ssize_t n_buffer,
- void *digits, Py_ssize_t n_digits,
- Py_ssize_t min_width,
- const char *grouping,
- const char *thousands_sep)
-{
+_PyUnicode_InsertThousandsGrouping(
+ PyObject *unicode, Py_ssize_t index,
+ Py_ssize_t n_buffer,
+ void *digits, Py_ssize_t n_digits,
+ Py_ssize_t min_width,
+ const char *grouping, PyObject *thousands_sep,
+ Py_UCS4 *maxchar)
+{
+ unsigned int kind, thousands_sep_kind;
+ void *data, *thousands_sep_data;
+ Py_ssize_t thousands_sep_len;
+ Py_ssize_t len;
+
+ if (unicode != NULL) {
+ kind = PyUnicode_KIND(unicode);
+ data = PyUnicode_DATA(unicode) + index * kind;
+ }
+ else {
+ kind = PyUnicode_1BYTE_KIND;
+ data = NULL;
+ }
+ thousands_sep_kind = PyUnicode_KIND(thousands_sep);
+ thousands_sep_data = PyUnicode_DATA(thousands_sep);
+ thousands_sep_len = PyUnicode_GET_LENGTH(thousands_sep);
+ if (unicode != NULL && thousands_sep_kind != kind) {
+ thousands_sep_data = _PyUnicode_AsKind(thousands_sep, kind);
+ if (!thousands_sep_data)
+ return -1;
+ }
+
switch (kind) {
case PyUnicode_1BYTE_KIND:
if (unicode != NULL && PyUnicode_IS_ASCII(unicode))
- return _PyUnicode_ascii_InsertThousandsGrouping(
+ len = asciilib_InsertThousandsGrouping(
(Py_UCS1*)data, n_buffer, (Py_UCS1*)digits, n_digits,
- min_width, grouping, thousands_sep);
+ min_width, grouping,
+ thousands_sep_data, thousands_sep_len);
else
- return _PyUnicode_ucs1_InsertThousandsGrouping(
+ len = ucs1lib_InsertThousandsGrouping(
(Py_UCS1*)data, n_buffer, (Py_UCS1*)digits, n_digits,
- min_width, grouping, thousands_sep);
+ min_width, grouping,
+ thousands_sep_data, thousands_sep_len);
+ break;
case PyUnicode_2BYTE_KIND:
- return _PyUnicode_ucs2_InsertThousandsGrouping(
+ len = ucs2lib_InsertThousandsGrouping(
(Py_UCS2*)data, n_buffer, (Py_UCS2*)digits, n_digits,
- min_width, grouping, thousands_sep);
+ min_width, grouping,
+ thousands_sep_data, thousands_sep_len);
+ break;
case PyUnicode_4BYTE_KIND:
- return _PyUnicode_ucs4_InsertThousandsGrouping(
+ len = ucs4lib_InsertThousandsGrouping(
(Py_UCS4*)data, n_buffer, (Py_UCS4*)digits, n_digits,
- min_width, grouping, thousands_sep);
- }
- assert(0);
- return -1;
+ min_width, grouping,
+ thousands_sep_data, thousands_sep_len);
+ break;
+ default:
+ assert(0);
+ return -1;
+ }
+ if (unicode != NULL && thousands_sep_kind != kind)
+ PyMem_Free(thousands_sep_data);
+ if (unicode == NULL) {
+ *maxchar = 127;
+ if (len != n_digits) {
+ *maxchar = Py_MAX(*maxchar,
+ PyUnicode_MAX_CHAR_VALUE(thousands_sep));
+ }
+ }
+ return len;
}


diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c
--- a/Python/formatter_unicode.c
+++ b/Python/formatter_unicode.c
@@ -346,11 +346,13 @@
before and including the decimal. Note that locales only support
8-bit chars, not unicode. */
typedef struct {
- char *decimal_point;
- char *thousands_sep;
- char *grouping;
+ PyObject *decimal_point;
+ PyObject *thousands_sep;
+ const char *grouping;
} LocaleInfo;

+#define STATIC_LOCALE_INFO_INIT {0, 0, 0}
+
/* describes the layout for an integer, see the comment in
calc_number_widths() for details */
typedef struct {
@@ -415,7 +417,7 @@
Py_UCS4 sign_char, PyObject *number, Py_ssize_t n_start,
Py_ssize_t n_end, Py_ssize_t n_remainder,
int has_decimal, const LocaleInfo *locale,
- const InternalFormatSpec *format)
+ const InternalFormatSpec *format, Py_UCS4 *maxchar)
{
Py_ssize_t n_non_digit_non_padding;
Py_ssize_t n_padding;
@@ -423,7 +425,7 @@
spec->n_digits = n_end - n_start - n_remainder - (has_decimal?1:0);
spec->n_lpadding = 0;
spec->n_prefix = n_prefix;
- spec->n_decimal = has_decimal ? strlen(locale->decimal_point) : 0;
+ spec->n_decimal = has_decimal ? PyUnicode_GET_LENGTH(locale->decimal_point) : 0;
spec->n_remainder = n_remainder;
spec->n_spadding = 0;
spec->n_rpadding = 0;
@@ -484,11 +486,15 @@
to special case it because the grouping code always wants
to have at least one character. */
spec->n_grouped_digits = 0;
- else
+ else {
+ Py_UCS4 grouping_maxchar;
spec->n_grouped_digits = _PyUnicode_InsertThousandsGrouping(
- NULL, PyUnicode_1BYTE_KIND, NULL, 0, NULL,
+ NULL, 0,
+ 0, NULL,
spec->n_digits, spec->n_min_width,
- locale->grouping, locale->thousands_sep);
+ locale->grouping, locale->thousands_sep, &grouping_maxchar);
+ *maxchar = Py_MAX(*maxchar, grouping_maxchar);
+ }

/* Given the desired width and the total of digit and non-digit
space we consume, see if we need any padding. format->width can
@@ -519,6 +525,10 @@
break;
}
}
+
+ if (spec->n_lpadding || spec->n_spadding || spec->n_rpadding)
+ *maxchar = Py_MAX(*maxchar, format->fill_char);
+
return spec->n_lpadding + spec->n_sign + spec->n_prefix +
spec->n_spadding + spec->n_grouped_digits + spec->n_decimal +
spec->n_remainder + spec->n_rpadding;
@@ -587,12 +597,11 @@
r =
#endif
_PyUnicode_InsertThousandsGrouping(
- out, kind,
- (char*)data + kind * pos,
+ out, pos,
spec->n_grouped_digits,
pdigits + kind * d_pos,
spec->n_digits, spec->n_min_width,
- locale->grouping, locale->thousands_sep);
+ locale->grouping, locale->thousands_sep, NULL);
#ifndef NDEBUG
assert(r == spec->n_grouped_digits);
#endif
@@ -615,10 +624,8 @@
pos += spec->n_grouped_digits;

if (spec->n_decimal) {
- Py_ssize_t t;
- for (t = 0; t < spec->n_decimal; ++t)
- PyUnicode_WRITE(kind, data, pos + t,
- locale->decimal_point[t]);
+ if (PyUnicode_CopyCharacters(out, pos, locale->decimal_point, 0, spec->n_decimal) < 0)
+ return -1;
pos += spec->n_decimal;
d_pos += 1;
}
@@ -643,32 +650,60 @@
grouping description, either for the current locale if type is
LT_CURRENT_LOCALE, a hard-coded locale if LT_DEFAULT_LOCALE, or
none if LT_NO_LOCALE. */
-static void
+static int
get_locale_info(int type, LocaleInfo *locale_info)
{
switch (type) {
case LT_CURRENT_LOCALE: {
struct lconv *locale_data = localeconv();
- locale_info->decimal_point = locale_data->decimal_point;
- locale_info->thousands_sep = locale_data->thousands_sep;
+ locale_info->decimal_point = PyUnicode_DecodeLocale(
+ locale_data->decimal_point,
+ NULL);
+ if (locale_info->decimal_point == NULL)
+ return -1;
+ locale_info->thousands_sep = PyUnicode_DecodeLocale(
+ locale_data->thousands_sep,
+ NULL);
+ if (locale_info->thousands_sep == NULL) {
+ Py_DECREF(locale_info->decimal_point);
+ return -1;
+ }
locale_info->grouping = locale_data->grouping;
break;
}
case LT_DEFAULT_LOCALE:
- locale_info->decimal_point = ".";
- locale_info->thousands_sep = ",";
+ locale_info->decimal_point = PyUnicode_FromOrdinal('.');
+ locale_info->thousands_sep = PyUnicode_FromOrdinal(',');
+ if (!locale_info->decimal_point || !locale_info->thousands_sep) {
+ Py_XDECREF(locale_info->decimal_point);
+ Py_XDECREF(locale_info->thousands_sep);
+ return -1;
+ }
locale_info->grouping = "\3"; /* Group every 3 characters. The
(implicit) trailing 0 means repeat
infinitely. */
break;
case LT_NO_LOCALE:
- locale_info->decimal_point = ".";
- locale_info->thousands_sep = "";
+ locale_info->decimal_point = PyUnicode_FromOrdinal('.');
+ locale_info->thousands_sep = PyUnicode_New(0, 0);
+ if (!locale_info->decimal_point || !locale_info->thousands_sep) {
+ Py_XDECREF(locale_info->decimal_point);
+ Py_XDECREF(locale_info->thousands_sep);
+ return -1;
+ }
locale_info->grouping = no_grouping;
break;
default:
assert(0);
}
+ return 0;
+}
+
+static void
+free_locale_info(LocaleInfo *locale_info)
+{
+ Py_XDECREF(locale_info->decimal_point);
+ Py_XDECREF(locale_info->thousands_sep);
}

/************************************************************************/
@@ -769,7 +804,7 @@

/* Locale settings, either from the actual locale or
from a hard-code pseudo-locale */
- LocaleInfo locale;
+ LocaleInfo locale = STATIC_LOCALE_INFO_INIT;

/* no precision allowed on integers */
if (format->precision != -1) {
@@ -868,18 +903,17 @@
}

/* Determine the grouping, separator, and decimal point, if any. */
- get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
- (format->thousands_separators ?
- LT_DEFAULT_LOCALE :
- LT_NO_LOCALE),
- &locale);
+ if (get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
+ (format->thousands_separators ?
+ LT_DEFAULT_LOCALE :
+ LT_NO_LOCALE),
+ &locale) == -1)
+ goto done;

/* Calculate how much memory we'll need. */
n_total = calc_number_widths(&spec, n_prefix, sign_char, tmp, inumeric_chars,
- inumeric_chars + n_digits, n_remainder, 0, &locale, format);
-
- if (spec.n_lpadding || spec.n_spadding || spec.n_rpadding)
- maxchar = Py_MAX(maxchar, format->fill_char);
+ inumeric_chars + n_digits, n_remainder, 0,
+ &locale, format, &maxchar);

/* Allocate the memory. */
result = PyUnicode_New(n_total, maxchar);
@@ -897,6 +931,7 @@

done:
Py_XDECREF(tmp);
+ free_locale_info(&locale);
assert(!result || _PyUnicode_CheckConsistency(result, 1));
return result;
}
@@ -938,7 +973,7 @@

/* Locale settings, either from the actual locale or
from a hard-code pseudo-locale */
- LocaleInfo locale;
+ LocaleInfo locale = STATIC_LOCALE_INFO_INIT;

if (format->alternate)
flags |= Py_DTSF_ALT;
@@ -1009,19 +1044,17 @@
parse_number(unicode_tmp, index, index + n_digits, &n_remainder, &has_decimal);

/* Determine the grouping, separator, and decimal point, if any. */
- get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
- (format->thousands_separators ?
- LT_DEFAULT_LOCALE :
- LT_NO_LOCALE),
- &locale);
+ if (get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
+ (format->thousands_separators ?
+ LT_DEFAULT_LOCALE :
+ LT_NO_LOCALE),
+ &locale) == -1)
+ goto done;

/* Calculate how much memory we'll need. */
n_total = calc_number_widths(&spec, 0, sign_char, unicode_tmp, index,
index + n_digits, n_remainder, has_decimal,
- &locale, format);
-
- if (spec.n_lpadding || spec.n_spadding || spec.n_rpadding)
- maxchar = Py_MAX(maxchar, format->fill_char);
+ &locale, format, &maxchar);

/* Allocate the memory. */
result = PyUnicode_New(n_total, maxchar);
@@ -1040,6 +1073,7 @@
done:
PyMem_Free(buf);
Py_DECREF(unicode_tmp);
+ free_locale_info(&locale);
assert(!result || _PyUnicode_CheckConsistency(result, 1));
return result;
}
@@ -1094,7 +1128,7 @@

/* Locale settings, either from the actual locale or
from a hard-code pseudo-locale */
- LocaleInfo locale;
+ LocaleInfo locale = STATIC_LOCALE_INFO_INIT;

/* Zero padding is not allowed. */
if (format->fill_char == '0') {
@@ -1190,11 +1224,12 @@
&n_im_remainder, &im_has_decimal);

/* Determine the grouping, separator, and decimal point, if any. */
- get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
- (format->thousands_separators ?
- LT_DEFAULT_LOCALE :
- LT_NO_LOCALE),
- &locale);
+ if (get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
+ (format->thousands_separators ?
+ LT_DEFAULT_LOCALE :
+ LT_NO_LOCALE),
+ &locale) == -1)
+ goto done;

/* Turn off any padding. We'll do it later after we've composed
the numbers without padding. */
@@ -1205,7 +1240,8 @@
/* Calculate how much memory we'll need. */
n_re_total = calc_number_widths(&re_spec, 0, re_sign_char, re_unicode_tmp,
i_re, i_re + n_re_digits, n_re_remainder,
- re_has_decimal, &locale, &tmp_format);
+ re_has_decimal, &locale, &tmp_format,
+ &maxchar);

/* Same formatting, but always include a sign, unless the real part is
* going to be omitted, in which case we use whatever sign convention was
@@ -1214,7 +1250,8 @@
tmp_format.sign = '+';
n_im_total = calc_number_widths(&im_spec, 0, im_sign_char, im_unicode_tmp,
i_im, i_im + n_im_digits, n_im_remainder,
- im_has_decimal, &locale, &tmp_format);
+ im_has_decimal, &locale, &tmp_format,
+ &maxchar);

if (skip_re)
n_re_total = 0;
@@ -1223,9 +1260,7 @@
calc_padding(n_re_total + n_im_total + 1 + add_parens * 2,
format->width, format->align, &lpad, &rpad, &total);

- if (re_spec.n_lpadding || re_spec.n_spadding || re_spec.n_rpadding
- || im_spec.n_lpadding || im_spec.n_spadding || im_spec.n_rpadding
- || lpad || rpad)
+ if (lpad || rpad)
maxchar = Py_MAX(maxchar, format->fill_char);

result = PyUnicode_New(total, maxchar);
@@ -1275,6 +1310,7 @@
PyMem_Free(im_buf);
Py_XDECREF(re_unicode_tmp);
Py_XDECREF(im_unicode_tmp);
+ free_locale_info(&locale);
assert(!result || _PyUnicode_CheckConsistency(result, 1));
return result;
}

--
Repository URL: http://hg.python.org/cpython
cpython (merge default -> default): merge [ In reply to ]
http://hg.python.org/cpython/rev/aceedef02c63
changeset: 75236:aceedef02c63
parent: 75235:3670df23081d
parent: 75234:a29d20fa85b4
user: Brett Cannon <brett@python.org>
date: Thu Feb 23 20:48:13 2012 -0500
summary:
merge

files:
Lib/test/test_format.py | 10 +++++++++-
Objects/unicodeobject.c | 21 ++++++++++++++++-----
Python/formatter_unicode.c | 15 ++++++---------
3 files changed, 31 insertions(+), 15 deletions(-)


diff --git a/Lib/test/test_format.py b/Lib/test/test_format.py
--- a/Lib/test/test_format.py
+++ b/Lib/test/test_format.py
@@ -289,10 +289,18 @@
except locale.Error as err:
self.skipTest("Cannot set locale: {}".format(err))
try:
- sep = locale.localeconv()['thousands_sep']
+ localeconv = locale.localeconv()
+ sep = localeconv['thousands_sep']
+ point = localeconv['decimal_point']
+
text = format(123456789, "n")
self.assertIn(sep, text)
self.assertEqual(text.replace(sep, ''), '123456789')
+
+ text = format(1234.5, "n")
+ self.assertIn(sep, text)
+ self.assertIn(point, text)
+ self.assertEqual(text.replace(sep, ''), '1234' + point + '5')
finally:
locale.setlocale(locale.LC_ALL, oldloc)

diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -9176,9 +9176,16 @@
thousands_sep_data = PyUnicode_DATA(thousands_sep);
thousands_sep_len = PyUnicode_GET_LENGTH(thousands_sep);
if (unicode != NULL && thousands_sep_kind != kind) {
- thousands_sep_data = _PyUnicode_AsKind(thousands_sep, kind);
- if (!thousands_sep_data)
- return -1;
+ if (thousands_sep_kind < kind) {
+ thousands_sep_data = _PyUnicode_AsKind(thousands_sep, kind);
+ if (!thousands_sep_data)
+ return -1;
+ }
+ else {
+ data = _PyUnicode_AsKind(unicode, thousands_sep_kind);
+ if (!data)
+ return -1;
+ }
}

switch (kind) {
@@ -9210,8 +9217,12 @@
assert(0);
return -1;
}
- if (unicode != NULL && thousands_sep_kind != kind)
- PyMem_Free(thousands_sep_data);
+ if (unicode != NULL && thousands_sep_kind != kind) {
+ if (thousands_sep_kind < kind)
+ PyMem_Free(thousands_sep_data);
+ else
+ PyMem_Free(data);
+ }
if (unicode == NULL) {
*maxchar = 127;
if (len != n_digits) {
diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c
--- a/Python/formatter_unicode.c
+++ b/Python/formatter_unicode.c
@@ -529,6 +529,9 @@
if (spec->n_lpadding || spec->n_spadding || spec->n_rpadding)
*maxchar = Py_MAX(*maxchar, format->fill_char);

+ if (spec->n_decimal)
+ *maxchar = Py_MAX(*maxchar, PyUnicode_MAX_CHAR_VALUE(locale->decimal_point));
+
return spec->n_lpadding + spec->n_sign + spec->n_prefix +
spec->n_spadding + spec->n_grouped_digits + spec->n_decimal +
spec->n_remainder + spec->n_rpadding;
@@ -548,10 +551,7 @@
Py_ssize_t d_pos = d_start;
unsigned int kind = PyUnicode_KIND(out);
void *data = PyUnicode_DATA(out);
-
-#ifndef NDEBUG
Py_ssize_t r;
-#endif

if (spec->n_lpadding) {
PyUnicode_Fill(out, pos, pos + spec->n_lpadding, fill_char);
@@ -593,18 +593,15 @@
if (pdigits == NULL)
return -1;
}
-#ifndef NDEBUG
- r =
-#endif
- _PyUnicode_InsertThousandsGrouping(
+ r = _PyUnicode_InsertThousandsGrouping(
out, pos,
spec->n_grouped_digits,
pdigits + kind * d_pos,
spec->n_digits, spec->n_min_width,
locale->grouping, locale->thousands_sep, NULL);
-#ifndef NDEBUG
+ if (r == -1)
+ return -1;
assert(r == spec->n_grouped_digits);
-#endif
if (PyUnicode_KIND(digits) < kind)
PyMem_Free(pdigits);
d_pos += spec->n_digits;

--
Repository URL: http://hg.python.org/cpython
cpython (merge default -> default): Merge [ In reply to ]
http://hg.python.org/cpython/rev/f417aff64dcc
changeset: 75306:f417aff64dcc
parent: 75305:dc0682e0b0cf
parent: 75300:17562834a246
user: Antoine Pitrou <solipsis@pitrou.net>
date: Mon Feb 27 01:01:58 2012 +0100
summary:
Merge

files:



--
Repository URL: http://hg.python.org/cpython
cpython (merge default -> default): Merge [ In reply to ]
http://hg.python.org/cpython/rev/72d1b21ee10f
changeset: 75400:72d1b21ee10f
parent: 75399:2843f32a3a34
parent: 75396:575a2affd214
user: Antoine Pitrou <solipsis@pitrou.net>
date: Sun Mar 04 20:59:01 2012 +0100
summary:
Merge

files:
Lib/test/crashers/loosing_mro_ref.py | 0
PCbuild/pcbuild.sln | 12 +++++-----
Tools/msi/msi.py | 19 +++++++++------
3 files changed, 17 insertions(+), 14 deletions(-)


diff --git a/Lib/test/crashers/loosing_mro_ref.py b/Lib/test/crashers/losing_mro_ref.py
rename from Lib/test/crashers/loosing_mro_ref.py
rename to Lib/test/crashers/losing_mro_ref.py
diff --git a/PCbuild/pcbuild.sln b/PCbuild/pcbuild.sln
--- a/PCbuild/pcbuild.sln
+++ b/PCbuild/pcbuild.sln
@@ -584,16 +584,16 @@
{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|x64.ActiveCfg = Release|x64
{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|x64.Build.0 = Release|x64
{885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|Win32.ActiveCfg = PGInstrument|Win32
- {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.ActiveCfg = Debug|x64
- {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.Build.0 = Debug|x64
+ {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.ActiveCfg = PGUpdate|x64
+ {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.Build.0 = PGUpdate|x64
{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
- {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.ActiveCfg = Release|x64
- {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.Build.0 = Release|x64
+ {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+ {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.Build.0 = PGInstrument|x64
{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
{885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
- {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.ActiveCfg = Release|x64
- {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.Build.0 = Release|x64
+ {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+ {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.Build.0 = PGUpdate|x64
{885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|Win32.ActiveCfg = Release|Win32
{885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|Win32.Build.0 = Release|Win32
{885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|x64.ActiveCfg = Release|x64
diff --git a/Tools/msi/msi.py b/Tools/msi/msi.py
--- a/Tools/msi/msi.py
+++ b/Tools/msi/msi.py
@@ -6,7 +6,6 @@
import uisample
from win32com.client import constants
from distutils.spawn import find_executable
-from uuids import product_codes
import tempfile

# Settings can be overridden in config.py below
@@ -77,9 +76,6 @@

if snapshot:
current_version = "%s.%s.%s" % (major, minor, int(time.time()/3600/24))
- product_code = msilib.gen_uuid()
-else:
- product_code = product_codes[current_version]

if full_current_version is None:
full_current_version = current_version
@@ -187,12 +183,19 @@
msilib.set_arch_from_file(dll_path)
if msilib.pe_type(dll_path) != msilib.pe_type("msisupport.dll"):
raise SystemError("msisupport.dll for incorrect architecture")
+
if msilib.Win64:
upgrade_code = upgrade_code_64
- # Bump the last digit of the code by one, so that 32-bit and 64-bit
- # releases get separate product codes
- digit = hex((int(product_code[-2],16)+1)%16)[-1]
- product_code = product_code[:-2] + digit + '}'
+
+if snapshot:
+ product_code = msilib.gen_uuid()
+else:
+ # official release: generate UUID from the download link that the file will have
+ import uuid
+ product_code = uuid.uuid3(uuid.NAMESPACE_URL,
+ 'http://www.python.org/ftp/python/%s.%s.%s/python-%s%s.msi' %
+ (major, minor, micro, full_current_version, msilib.arch_ext))
+ product_code = '{%s}' % product_code

if testpackage:
ext = 'px'

--
Repository URL: http://hg.python.org/cpython
cpython (merge default -> default): Merge [ In reply to ]
http://hg.python.org/cpython/rev/8639ec6f3d06
changeset: 75454:8639ec6f3d06
parent: 75453:7069d0a55470
parent: 75451:538cbae3ec2d
user: Antoine Pitrou <solipsis@pitrou.net>
date: Tue Mar 06 13:45:57 2012 +0100
summary:
Merge

files:
Doc/whatsnew/3.3.rst | 72 +++++++++++++++++++++++++++++--
1 files changed, 67 insertions(+), 5 deletions(-)


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
@@ -49,6 +49,8 @@
This article explains the new features in Python 3.3, compared to 3.2.


+.. pep-3118-update:
+
PEP 3118: New memoryview implementation and buffer protocol documentation
=========================================================================

@@ -85,7 +87,9 @@
* Multi-dimensional comparisons are supported for any array type.

* All array types are hashable if the exporting object is hashable
- and the view is read-only.
+ and the view is read-only. (Contributed by Antoine Pitrou in
+ :issue:`13411`)
+

* Arbitrary slicing of any 1-D arrays type is supported. For example, it
is now possible to reverse a memoryview in O(1) by using a negative step.
@@ -258,9 +262,56 @@
containing 'yield' to be factored out and placed in another generator.
Additionally, the subgenerator is allowed to return with a value, and the
value is made available to the delegating generator.
+
While designed primarily for use in delegating to a subgenerator, the ``yield
from`` expression actually allows delegation to arbitrary subiterators.

+For simple iterators, ``yield from iterable`` is essentially just a shortened
+form of ``for item in iterable: yield item``::
+
+ >>> def g(x):
+ ... yield from range(x, 0, -1)
+ ... yield from range(x)
+ ...
+ >>> list(g(5))
+ [5, 4, 3, 2, 1, 0, 1, 2, 3, 4]
+
+However, unlike an ordinary loop, ``yield from`` allows subgenerators to
+receive sent and thrown values directly from the calling scope, and
+return a final value to the outer generator::
+
+ >>> def accumulate(start=0):
+ ... tally = start
+ ... while 1:
+ ... next = yield
+ ... if next is None:
+ ... return tally
+ ... tally += next
+ ...
+ >>> def gather_tallies(tallies, start=0):
+ ... while 1:
+ ... tally = yield from accumulate()
+ ... tallies.append(tally)
+ ...
+ >>> tallies = []
+ >>> acc = gather_tallies(tallies)
+ >>> next(acc) # Ensure the accumulator is ready to accept values
+ >>> for i in range(10):
+ ... acc.send(i)
+ ...
+ >>> acc.send(None) # Finish the first tally
+ >>> for i in range(5):
+ ... acc.send(i)
+ ...
+ >>> acc.send(None) # Finish the second tally
+ >>> tallies
+ [45, 10]
+
+The main principle driving this change is to allow even generators that are
+designed to be used with the ``send`` and ``throw`` methods to be split into
+multiple subgenerators as easily as a single large function can be split into
+multiple subfunctions.
+
(Implementation by Greg Ewing, integrated into 3.3 by Renaud Blanch, Ryan
Kelly and Nick Coghlan, documentation by Zbigniew Jędrzejewski-Szmek and
Nick Coghlan)
@@ -327,6 +378,21 @@
KeyError('x',)


+PEP 414: Explicit Unicode literals
+======================================
+
+:pep:`414` - Explicit Unicode literals
+ PEP written by Armin Ronacher.
+
+To ease the transition from Python 2 for Unicode aware Python applications
+that make heavy use of Unicode literals, Python 3.3 once again supports the
+"``u``" prefix for string literals. This prefix has no semantic significance
+in Python 3, it is provided solely to reduce the number of purely mechanical
+changes in migrating to Python 3, making it easier for developers to focus on
+the more significant semantic changes (such as the stricter default
+separation of binary and text data).
+
+
PEP 3155: Qualified name for classes and functions
==================================================

@@ -408,10 +474,6 @@

(:issue:`12170`)

-* Memoryview objects are now hashable when the underlying object is hashable.
-
- (Contributed by Antoine Pitrou in :issue:`13411`)
-

New and Improved Modules
========================

--
Repository URL: http://hg.python.org/cpython
cpython (merge default -> default): Merge [ In reply to ]
http://hg.python.org/cpython/rev/b154ab2cdb1e
changeset: 75551:b154ab2cdb1e
parent: 75550:06628ec43732
parent: 75549:8538eeb71698
user: Michael Foord <michael@voidspace.org.uk>
date: Mon Mar 12 13:54:03 2012 -0700
summary:
Merge

files:
Lib/pickle.py | 8 ++++++++
Lib/test/pickletester.py | 12 ++++++++++++
Lib/test/test_sys.py | 2 +-
Misc/ACKS | 1 +
Modules/_pickle.c | 21 +++++++++++++++++++++
5 files changed, 43 insertions(+), 1 deletions(-)


diff --git a/Lib/pickle.py b/Lib/pickle.py
--- a/Lib/pickle.py
+++ b/Lib/pickle.py
@@ -438,6 +438,14 @@
self.write(NONE)
dispatch[type(None)] = save_none

+ def save_ellipsis(self, obj):
+ self.save_global(Ellipsis, 'Ellipsis')
+ dispatch[type(Ellipsis)] = save_ellipsis
+
+ def save_notimplemented(self, obj):
+ self.save_global(NotImplemented, 'NotImplemented')
+ dispatch[type(NotImplemented)] = save_notimplemented
+
def save_bool(self, obj):
if self.proto >= 2:
self.write(obj and NEWTRUE or NEWFALSE)
diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py
--- a/Lib/test/pickletester.py
+++ b/Lib/test/pickletester.py
@@ -743,6 +743,18 @@
u = self.loads(s)
self.assertEqual(t, u)

+ def test_ellipsis(self):
+ for proto in protocols:
+ s = self.dumps(..., proto)
+ u = self.loads(s)
+ self.assertEqual(..., u)
+
+ def test_notimplemented(self):
+ for proto in protocols:
+ s = self.dumps(NotImplemented, proto)
+ u = self.loads(s)
+ self.assertEqual(NotImplemented, u)
+
# Tests for protocol 2

def test_proto(self):
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -882,7 +882,7 @@
check = self.check_sizeof
# _ast.AST
import _ast
- check(_ast.AST(), size(h + ''))
+ check(_ast.AST(), size(h + 'P'))
# imp.NullImporter
import imp
check(imp.NullImporter(self.file.name), size(h + ''))
diff --git a/Misc/ACKS b/Misc/ACKS
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -883,6 +883,7 @@
Rich Salz
Kevin Samborn
Adrian Sampson
+James Sanders
Ilya Sandler
Mark Sapiro
Ty Sarna
diff --git a/Modules/_pickle.c b/Modules/_pickle.c
--- a/Modules/_pickle.c
+++ b/Modules/_pickle.c
@@ -2812,6 +2812,19 @@
}

static int
+save_ellipsis(PicklerObject *self, PyObject *obj)
+{
+ return save_global(self, Py_Ellipsis, PyUnicode_FromString("Ellipsis"));
+}
+
+static int
+save_notimplemented(PicklerObject *self, PyObject *obj)
+{
+ return save_global(self, Py_NotImplemented,
+ PyUnicode_FromString("NotImplemented"));
+}
+
+static int
save_pers(PicklerObject *self, PyObject *obj, PyObject *func)
{
PyObject *pid = NULL;
@@ -3114,6 +3127,14 @@
status = save_none(self, obj);
goto done;
}
+ else if (obj == Py_Ellipsis) {
+ status = save_ellipsis(self, obj);
+ goto done;
+ }
+ else if (obj == Py_NotImplemented) {
+ status = save_notimplemented(self, obj);
+ goto done;
+ }
else if (obj == Py_False || obj == Py_True) {
status = save_bool(self, obj);
goto done;

--
Repository URL: http://hg.python.org/cpython
cpython (merge default -> default): Merge [ In reply to ]
http://hg.python.org/cpython/rev/e04750e0ffd6
changeset: 75557:e04750e0ffd6
parent: 75556:8c5506468ecb
parent: 75555:9cccfaa6b534
user: Michael Foord <michael@voidspace.org.uk>
date: Mon Mar 12 15:25:12 2012 -0700
summary:
Merge

files:
Lib/aifc.py | 12 +-
Lib/test/test_aifc.py | 158 ++++++++++++++++++++++++++++-
Misc/NEWS | 2 +
Modules/_pickle.c | 11 +-
4 files changed, 165 insertions(+), 18 deletions(-)


diff --git a/Lib/aifc.py b/Lib/aifc.py
--- a/Lib/aifc.py
+++ b/Lib/aifc.py
@@ -136,6 +136,7 @@

import struct
import builtins
+import warnings

__all__ = ["Error", "open", "openfp"]

@@ -440,7 +441,7 @@
kludge = 0
if chunk.chunksize == 18:
kludge = 1
- print('Warning: bad COMM chunk size')
+ warnings.warn('Warning: bad COMM chunk size')
chunk.chunksize = 23
#DEBUG end
self._comptype = chunk.read(4)
@@ -484,11 +485,10 @@
# a position 0 and name ''
self._markers.append((id, pos, name))
except EOFError:
- print('Warning: MARK chunk contains only', end=' ')
- print(len(self._markers), end=' ')
- if len(self._markers) == 1: print('marker', end=' ')
- else: print('markers', end=' ')
- print('instead of', nmarkers)
+ w = ('Warning: MARK chunk contains only %s marker%s instead of %s' %
+ (len(self._markers), '' if len(self._markers) == 1 else 's',
+ nmarkers))
+ warnings.warn(w)

class Aifc_write:
# Variables used in this class:
diff --git a/Lib/test/test_aifc.py b/Lib/test/test_aifc.py
--- a/Lib/test/test_aifc.py
+++ b/Lib/test/test_aifc.py
@@ -1,7 +1,8 @@
-from test.support import findfile, run_unittest, TESTFN
+from test.support import findfile, run_unittest, TESTFN, unlink
import unittest
import os
import io
+import struct

import aifc

@@ -20,10 +21,8 @@
self.fout.close()
except (aifc.Error, AttributeError):
pass
- try:
- os.remove(TESTFN)
- except OSError:
- pass
+ unlink(TESTFN)
+ unlink(TESTFN + '.aiff')

def test_skipunknown(self):
#Issue 2245
@@ -32,6 +31,7 @@

def test_params(self):
f = self.f = aifc.open(self.sndfilepath)
+ self.assertEqual(f.getfp().name, self.sndfilepath)
self.assertEqual(f.getnchannels(), 2)
self.assertEqual(f.getsampwidth(), 2)
self.assertEqual(f.getframerate(), 48000)
@@ -45,6 +45,7 @@

def test_read(self):
f = self.f = aifc.open(self.sndfilepath)
+ self.assertEqual(f.readframes(0), b'')
self.assertEqual(f.tell(), 0)
self.assertEqual(f.readframes(2), b'\x00\x00\x00\x00\x0b\xd4\x0b\xd4')
f.rewind()
@@ -58,6 +59,10 @@
self.assertEqual(f.readframes(2), b'\x17t\x17t"\xad"\xad')
f.setpos(pos0)
self.assertEqual(f.readframes(2), b'\x00\x00\x00\x00\x0b\xd4\x0b\xd4')
+ with self.assertRaises(aifc.Error):
+ f.setpos(-1)
+ with self.assertRaises(aifc.Error):
+ f.setpos(f.getnframes() + 1)

def test_write(self):
f = self.f = aifc.open(self.sndfilepath)
@@ -92,8 +97,6 @@
self.assertEqual(f.getparams()[0:3], fout.getparams()[0:3])
self.assertEqual(fout.getcomptype(), b'ULAW')
self.assertEqual(fout.getcompname(), b'foo')
- # XXX: this test fails, not sure if it should succeed or not
- # self.assertEqual(f.readframes(5), fout.readframes(5))

def test_close(self):
class Wrapfile(object):
@@ -112,7 +115,7 @@

def test_write_header_comptype_sampwidth(self):
for comptype in (b'ULAW', b'ulaw', b'ALAW', b'alaw', b'G722'):
- fout = self.fout = aifc.open(io.BytesIO(), 'wb')
+ fout = aifc.open(io.BytesIO(), 'wb')
fout.setnchannels(1)
fout.setframerate(1)
fout.setcomptype(comptype, b'')
@@ -121,7 +124,7 @@
fout.initfp(None)

def test_write_markers_values(self):
- fout = self.fout = aifc.open(io.BytesIO(), 'wb')
+ fout = aifc.open(io.BytesIO(), 'wb')
self.assertEqual(fout.getmarkers(), None)
fout.setmark(1, 0, b'foo1')
fout.setmark(1, 1, b'foo2')
@@ -179,6 +182,143 @@
with self.assertRaises(ValueError):
aifc._write_string(f, b'too long' * 255)

+ def test_wrong_open_mode(self):
+ with self.assertRaises(aifc.Error):
+ aifc.open(TESTFN, 'wrong_mode')
+
+ def test_read_wrong_form(self):
+ b1 = io.BytesIO(b'WRNG' + struct.pack('>L', 0))
+ b2 = io.BytesIO(b'FORM' + struct.pack('>L', 4) + b'WRNG')
+ self.assertRaises(aifc.Error, aifc.open, b1)
+ self.assertRaises(aifc.Error, aifc.open, b2)
+
+ def test_read_no_comm_chunk(self):
+ b = io.BytesIO(b'FORM' + struct.pack('>L', 4) + b'AIFF')
+ self.assertRaises(aifc.Error, aifc.open, b)
+
+ def test_read_wrong_compression_type(self):
+ b = b'FORM' + struct.pack('>L', 4) + b'AIFC'
+ b += b'COMM' + struct.pack('>LhlhhLL', 23, 0, 0, 0, 0, 0, 0)
+ b += b'WRNG' + struct.pack('B', 0)
+ self.assertRaises(aifc.Error, aifc.open, io.BytesIO(b))
+
+ def test_read_wrong_marks(self):
+ b = b'FORM' + struct.pack('>L', 4) + b'AIFF'
+ b += b'COMM' + struct.pack('>LhlhhLL', 18, 0, 0, 0, 0, 0, 0)
+ b += b'SSND' + struct.pack('>L', 8) + b'\x00' * 8
+ b += b'MARK' + struct.pack('>LhB', 3, 1, 1)
+ with self.assertWarns(UserWarning):
+ f = aifc.open(io.BytesIO(b))
+ self.assertEqual(f.getmarkers(), None)
+
+ def test_read_comm_kludge_compname_even(self):
+ b = b'FORM' + struct.pack('>L', 4) + b'AIFC'
+ b += b'COMM' + struct.pack('>LhlhhLL', 18, 0, 0, 0, 0, 0, 0)
+ b += b'NONE' + struct.pack('B', 4) + b'even' + b'\x00'
+ b += b'SSND' + struct.pack('>L', 8) + b'\x00' * 8
+ with self.assertWarns(UserWarning):
+ f = aifc.open(io.BytesIO(b))
+ self.assertEqual(f.getcompname(), b'even')
+
+ def test_read_comm_kludge_compname_odd(self):
+ b = b'FORM' + struct.pack('>L', 4) + b'AIFC'
+ b += b'COMM' + struct.pack('>LhlhhLL', 18, 0, 0, 0, 0, 0, 0)
+ b += b'NONE' + struct.pack('B', 3) + b'odd'
+ b += b'SSND' + struct.pack('>L', 8) + b'\x00' * 8
+ with self.assertWarns(UserWarning):
+ f = aifc.open(io.BytesIO(b))
+ self.assertEqual(f.getcompname(), b'odd')
+
+ def test_write_params_raises(self):
+ fout = aifc.open(io.BytesIO(), 'wb')
+ wrong_params = (0, 0, 0, 0, b'WRNG', '')
+ self.assertRaises(aifc.Error, fout.setparams, wrong_params)
+ self.assertRaises(aifc.Error, fout.getparams)
+ self.assertRaises(aifc.Error, fout.setnchannels, 0)
+ self.assertRaises(aifc.Error, fout.getnchannels)
+ self.assertRaises(aifc.Error, fout.setsampwidth, 0)
+ self.assertRaises(aifc.Error, fout.getsampwidth)
+ self.assertRaises(aifc.Error, fout.setframerate, 0)
+ self.assertRaises(aifc.Error, fout.getframerate)
+ self.assertRaises(aifc.Error, fout.setcomptype, b'WRNG', '')
+ fout.aiff()
+ fout.setnchannels(1)
+ fout.setsampwidth(1)
+ fout.setframerate(1)
+ fout.setnframes(1)
+ fout.writeframes(b'\x00')
+ self.assertRaises(aifc.Error, fout.setparams, (1, 1, 1, 1, 1, 1))
+ self.assertRaises(aifc.Error, fout.setnchannels, 1)
+ self.assertRaises(aifc.Error, fout.setsampwidth, 1)
+ self.assertRaises(aifc.Error, fout.setframerate, 1)
+ self.assertRaises(aifc.Error, fout.setnframes, 1)
+ self.assertRaises(aifc.Error, fout.setcomptype, b'NONE', '')
+ self.assertRaises(aifc.Error, fout.aiff)
+ self.assertRaises(aifc.Error, fout.aifc)
+
+ def test_write_params_singles(self):
+ fout = aifc.open(io.BytesIO(), 'wb')
+ fout.aifc()
+ fout.setnchannels(1)
+ fout.setsampwidth(2)
+ fout.setframerate(3)
+ fout.setnframes(4)
+ fout.setcomptype(b'NONE', b'name')
+ self.assertEqual(fout.getnchannels(), 1)
+ self.assertEqual(fout.getsampwidth(), 2)
+ self.assertEqual(fout.getframerate(), 3)
+ self.assertEqual(fout.getnframes(), 0)
+ self.assertEqual(fout.tell(), 0)
+ self.assertEqual(fout.getcomptype(), b'NONE')
+ self.assertEqual(fout.getcompname(), b'name')
+ fout.writeframes(b'\x00' * 4 * fout.getsampwidth() * fout.getnchannels())
+ self.assertEqual(fout.getnframes(), 4)
+ self.assertEqual(fout.tell(), 4)
+
+ def test_write_params_bunch(self):
+ fout = aifc.open(io.BytesIO(), 'wb')
+ fout.aifc()
+ p = (1, 2, 3, 4, b'NONE', b'name')
+ fout.setparams(p)
+ self.assertEqual(fout.getparams(), p)
+ fout.initfp(None)
+
+ def test_write_header_raises(self):
+ fout = aifc.open(io.BytesIO(), 'wb')
+ self.assertRaises(aifc.Error, fout.close)
+ fout.setnchannels(1)
+ self.assertRaises(aifc.Error, fout.close)
+ fout.setsampwidth(1)
+ self.assertRaises(aifc.Error, fout.close)
+ fout.initfp(None)
+
+ def test_write_header_comptype_raises(self):
+ for comptype in (b'ULAW', b'ulaw', b'ALAW', b'alaw', b'G722'):
+ fout = aifc.open(io.BytesIO(), 'wb')
+ fout.setsampwidth(1)
+ fout.setcomptype(comptype, b'')
+ self.assertRaises(aifc.Error, fout.close)
+ fout.initfp(None)
+
+ def test_write_markers_raises(self):
+ fout = aifc.open(io.BytesIO(), 'wb')
+ self.assertRaises(aifc.Error, fout.setmark, 0, 0, b'')
+ self.assertRaises(aifc.Error, fout.setmark, 1, -1, b'')
+ self.assertRaises(aifc.Error, fout.setmark, 1, 0, None)
+ self.assertRaises(aifc.Error, fout.getmark, 1)
+ fout.initfp(None)
+
+ def test_write_aiff_by_extension(self):
+ sampwidth = 2
+ fout = self.fout = aifc.open(TESTFN + '.aiff', 'wb')
+ fout.setparams((1, sampwidth, 1, 1, b'ULAW', b''))
+ frames = b'\x00' * fout.getnchannels() * sampwidth
+ fout.writeframes(frames)
+ fout.close()
+ f = self.f = aifc.open(TESTFN + '.aiff', 'rb')
+ self.assertEqual(f.getcomptype(), b'NONE')
+ f.close()
+

def test_main():
run_unittest(AIFCTest)
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -24,6 +24,8 @@
Library
-------

+- Issue #13394: the aifc module now uses warnings.warn() to signal warnings.
+
- Issue #14252: Fix subprocess.Popen.terminate() to not raise an error under
Windows when the child process has already exited.

diff --git a/Modules/_pickle.c b/Modules/_pickle.c
--- a/Modules/_pickle.c
+++ b/Modules/_pickle.c
@@ -2814,14 +2814,19 @@
static int
save_ellipsis(PicklerObject *self, PyObject *obj)
{
- return save_global(self, Py_Ellipsis, PyUnicode_FromString("Ellipsis"));
+ PyObject *str = PyUnicode_FromString("Ellipsis");
+ if (str == NULL)
+ return -1;
+ return save_global(self, Py_Ellipsis, str);
}

static int
save_notimplemented(PicklerObject *self, PyObject *obj)
{
- return save_global(self, Py_NotImplemented,
- PyUnicode_FromString("NotImplemented"));
+ PyObject *str = PyUnicode_FromString("NotImplemented");
+ if (str == NULL)
+ return -1;
+ return save_global(self, Py_NotImplemented, str);
}

static int

--
Repository URL: http://hg.python.org/cpython
cpython (merge default -> default): Merge [ In reply to ]
http://hg.python.org/cpython/rev/4925efb9f9f6
changeset: 75637:4925efb9f9f6
parent: 75636:6493f091b401
parent: 75635:a7a9e0f46b8a
user: Michael Foord <michael@voidspace.org.uk>
date: Wed Mar 14 12:59:08 2012 -0700
summary:
Merge

files:
Modules/tkappinit.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)


diff --git a/Modules/tkappinit.c b/Modules/tkappinit.c
--- a/Modules/tkappinit.c
+++ b/Modules/tkappinit.c
@@ -26,7 +26,9 @@
int
Tcl_AppInit(Tcl_Interp *interp)
{
+#ifdef WITH_MOREBUTTONS
Tk_Window main_window;
+#endif
const char *_tkinter_skip_tk_init;
#ifdef TKINTER_PROTECT_LOADTK
const char *_tkinter_tk_failed;
@@ -111,7 +113,11 @@
return TCL_ERROR;
}

+#ifdef WITH_MOREBUTTONS
main_window = Tk_MainWindow(interp);
+#else
+ Tk_MainWindow(interp);
+#endif

#ifdef TK_AQUA
TkMacOSXInitAppleEvents(interp);

--
Repository URL: http://hg.python.org/cpython
cpython (merge default -> default): merge [ In reply to ]
http://hg.python.org/cpython/rev/b86b414673c3
changeset: 75685:b86b414673c3
parent: 75684:0ddb78341290
parent: 75683:dcf39147deeb
user: Raymond Hettinger <python@rcn.com>
date: Wed Mar 14 18:17:20 2012 -0700
summary:
merge

files:
Doc/howto/urllib2.rst | 4 +++-
Doc/library/urllib.request.rst | 17 ++++++++---------
Modules/expat/expat.h | 2 ++
Modules/pyexpat.c | 5 +++++
4 files changed, 18 insertions(+), 10 deletions(-)


diff --git a/Doc/howto/urllib2.rst b/Doc/howto/urllib2.rst
--- a/Doc/howto/urllib2.rst
+++ b/Doc/howto/urllib2.rst
@@ -115,6 +115,7 @@
'language' : 'Python' }

data = urllib.parse.urlencode(values)
+ data = data.encode('utf-8') # data should be bytes
req = urllib.request.Request(url, data)
response = urllib.request.urlopen(req)
the_page = response.read()
@@ -179,7 +180,8 @@
'language' : 'Python' }
headers = { 'User-Agent' : user_agent }

- data = urllib.parse.urlencode(values)
+ data = urllib.parse.urlencode(values)
+ data = data.encode('utf-8')
req = urllib.request.Request(url, data, headers)
response = urllib.request.urlopen(req)
the_page = response.read()
diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst
--- a/Doc/library/urllib.request.rst
+++ b/Doc/library/urllib.request.rst
@@ -138,14 +138,13 @@

*url* should be a string containing a valid URL.

- *data* may be a string specifying additional data to send to the
- server, or ``None`` if no such data is needed. Currently HTTP
- requests are the only ones that use *data*, in order to choose between
- ``'GET'`` and ``'POST'`` when *method* is not specified.
- *data* should be a buffer in the standard
- :mimetype:`application/x-www-form-urlencoded` format. The
- :func:`urllib.parse.urlencode` function takes a mapping or sequence
- of 2-tuples and returns a string in this format.
+ *data* may be a bytes object specifying additional data to send to the
+ server, or ``None`` if no such data is needed. Currently HTTP requests are
+ the only ones that use *data*; the HTTP request will be a POST instead of a
+ GET when the *data* parameter is provided. *data* should be a buffer in the
+ standard :mimetype:`application/x-www-form-urlencoded` format. The
+ :func:`urllib.parse.urlencode` function takes a mapping or sequence of
+ 2-tuples and returns a string in this format.

*headers* should be a dictionary, and will be treated as if
:meth:`add_header` was called with each key and value as arguments.
@@ -1183,7 +1182,7 @@

If the *url* uses the :file:`http:` scheme identifier, the optional *data*
argument may be given to specify a ``POST`` request (normally the request
- type is ``GET``). The *data* argument must in standard
+ type is ``GET``). The *data* argument must be a bytes object in standard
:mimetype:`application/x-www-form-urlencoded` format; see the
:func:`urlencode` function below.

diff --git a/Modules/expat/expat.h b/Modules/expat/expat.h
--- a/Modules/expat/expat.h
+++ b/Modules/expat/expat.h
@@ -892,6 +892,8 @@
XML_SetHashSalt(XML_Parser parser,
unsigned long hash_salt);

+#define XML_HAS_SET_HASH_SALT /* Python Only: Defined for pyexpat.c. */
+
/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then
XML_GetErrorCode returns information about the error.
*/
diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c
--- a/Modules/pyexpat.c
+++ b/Modules/pyexpat.c
@@ -1156,8 +1156,13 @@
else {
self->itself = XML_ParserCreate(encoding);
}
+#if ((XML_MAJOR_VERSION >= 2) && (XML_MINOR_VERSION >= 1)) || defined(XML_HAS_SET_HASH_SALT)
+ /* This feature was added upstream in libexpat 2.1.0. Our expat copy
+ * has a backport of this feature where we also define XML_HAS_SET_HASH_SALT
+ * to indicate that we can still use it. */
XML_SetHashSalt(self->itself,
(unsigned long)_Py_HashSecret.prefix);
+#endif
self->intern = intern;
Py_XINCREF(self->intern);
PyObject_GC_Track(self);

--
Repository URL: http://hg.python.org/cpython
cpython (merge default -> default): merge [ In reply to ]
http://hg.python.org/cpython/rev/870c0ef7e8a2
changeset: 75730:870c0ef7e8a2
parent: 75729:3b2856d8614b
parent: 75728:13c44ad094b4
user: Raymond Hettinger <python@rcn.com>
date: Fri Mar 16 01:18:33 2012 -0700
summary:
merge

files:
Lib/http/server.py | 9 ++++++++-
Lib/test/test_httpservers.py | 1 +
Misc/NEWS | 2 ++
3 files changed, 11 insertions(+), 1 deletions(-)


diff --git a/Lib/http/server.py b/Lib/http/server.py
--- a/Lib/http/server.py
+++ b/Lib/http/server.py
@@ -865,7 +865,14 @@
# Filter out blank non trailing parts before consuming the '..'.
path_parts = [part for part in path_parts[:-1] if part] + path_parts[-1:]
if path_parts:
- tail_part = path_parts.pop()
+ # Special case for CGI's for PATH_INFO
+ if path.startswith('/cgi-bin') or path.startswith('/htbin'):
+ tail_part = []
+ while path_parts[-1] not in ('cgi-bin','htbin'):
+ tail_part.insert(0,path_parts.pop())
+ tail_part = "/".join(tail_part)
+ else:
+ tail_part = path_parts.pop()
else:
tail_part = ''
head_parts = []
diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py
--- a/Lib/test/test_httpservers.py
+++ b/Lib/test/test_httpservers.py
@@ -377,6 +377,7 @@
'/.//': ('/', ''),
'cgi-bin/file1.py': ('/cgi-bin', 'file1.py'),
'/cgi-bin/file1.py': ('/cgi-bin', 'file1.py'),
+ '/cgi-bin/file1.py/PATH-INFO': ('/cgi-bin', 'file1.py/PATH-INFO'),
'a': ('/', 'a'),
'/a': ('/', 'a'),
'//a': ('/', 'a'),
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -24,6 +24,8 @@
Library
-------

+- Issue #10484: Fix the CGIHTTPServer's PATH_INFO handling problem.
+
- Issue #11199: Fix the with urllib which hangs on particular ftp urls.

- Improve the memory utilization and speed of functools.lru_cache.

--
Repository URL: http://hg.python.org/cpython
cpython (merge default -> default): Merge [ In reply to ]
http://hg.python.org/cpython/rev/fb76bb09ad0f
changeset: 75755:fb76bb09ad0f
parent: 75754:b2a8310de718
parent: 75753:13e2d09e0612
user: Antoine Pitrou <solipsis@pitrou.net>
date: Sat Mar 17 00:24:12 2012 +0100
summary:
Merge

files:
Lib/functools.py | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)


diff --git a/Lib/functools.py b/Lib/functools.py
--- a/Lib/functools.py
+++ b/Lib/functools.py
@@ -226,9 +226,11 @@

def cache_clear():
"""Clear the cache and cache statistics"""
- nonlocal hits, misses
+ nonlocal hits, misses, root
with lock:
cache.clear()
+ root = []
+ root[:] = [root, root, None, None]
hits = misses = 0

wrapper.cache_info = cache_info

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

1 2 3  View All