[Python-checkins] cpython (merge 3.5 -> 3.5): Merge heads
serhiy.storchaka
python-checkins at python.org
Thu Jan 28 12:58:03 EST 2016
https://hg.python.org/cpython/rev/66fcbda87c31
changeset: 100100:66fcbda87c31
branch: 3.5
parent: 100097:1c690cb4def8
parent: 100095:ddce15b21c21
user: Serhiy Storchaka <storchaka at gmail.com>
date: Thu Jan 28 19:56:40 2016 +0200
summary:
Merge heads
files:
Doc/c-api/stable.rst | 2 +-
Doc/library/ctypes.rst | 60 ++++++++++++++++-
Lib/ctypes/test/test_arrays.py | 12 ++-
Lib/ctypes/test/test_pointers.py | 9 ++-
Lib/test/eintrdata/eintr_tester.py | 22 +++++-
Lib/test/test_sysconfig.py | 3 +
Misc/ACKS | 1 +
Misc/NEWS | 4 +
Modules/socketmodule.c | 26 +++++++-
9 files changed, 120 insertions(+), 19 deletions(-)
diff --git a/Doc/c-api/stable.rst b/Doc/c-api/stable.rst
--- a/Doc/c-api/stable.rst
+++ b/Doc/c-api/stable.rst
@@ -34,5 +34,5 @@
missing symbols) on the older releases.
As of Python 3.2, the set of functions available to the limited API is
-documented in PEP 384. In the C API documentation, API elements that are not
+documented in :pep:`384`. In the C API documentation, API elements that are not
part of the limited API are marked as "Not part of the limited API."
diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst
--- a/Doc/library/ctypes.rst
+++ b/Doc/library/ctypes.rst
@@ -716,8 +716,8 @@
>>> pi = pointer(i)
>>>
-Pointer instances have a :attr:`contents` attribute which returns the object to
-which the pointer points, the ``i`` object above::
+Pointer instances have a :attr:`~_Pointer.contents` attribute which
+returns the object to which the pointer points, the ``i`` object above::
>>> pi.contents
c_long(42)
@@ -2401,6 +2401,56 @@
Arrays and pointers
^^^^^^^^^^^^^^^^^^^
-Not yet written - please see the sections :ref:`ctypes-pointers` and section
-:ref:`ctypes-arrays` in the tutorial.
-
+.. class:: Array(\*args)
+
+ Abstract base class for arrays.
+
+ The recommended way to create concrete array types is by multiplying any
+ :mod:`ctypes` data type with a positive integer. Alternatively, you can subclass
+ this type and define :attr:`_length_` and :attr:`_type_` class variables.
+ Array elements can be read and written using standard
+ subscript and slice accesses; for slice reads, the resulting object is
+ *not* itself an :class:`Array`.
+
+
+ .. attribute:: _length_
+
+ A positive integer specifying the number of elements in the array.
+ Out-of-range subscripts result in an :exc:`IndexError`. Will be
+ returned by :func:`len`.
+
+
+ .. attribute:: _type_
+
+ Specifies the type of each element in the array.
+
+
+ Array subclass constructors accept positional arguments, used to
+ initialize the elements in order.
+
+
+.. class:: _Pointer
+
+ Private, abstract base class for pointers.
+
+ Concrete pointer types are created by calling :func:`POINTER` with the
+ type that will be pointed to; this is done automatically by
+ :func:`pointer`.
+
+ If a pointer points to an array, its elements can be read and
+ written using standard subscript and slice accesses. Pointer objects
+ have no size, so :func:`len` will raise :exc:`TypeError`. Negative
+ subscripts will read from the memory *before* the pointer (as in C), and
+ out-of-range subscripts will probably crash with an access violation (if
+ you're lucky).
+
+
+ .. attribute:: _type_
+
+ Specifies the type pointed to.
+
+ .. attribute:: contents
+
+ Returns the object to which to pointer points. Assigning to this
+ attribute changes the pointer to point to the assigned object.
+
diff --git a/Lib/ctypes/test/test_arrays.py b/Lib/ctypes/test/test_arrays.py
--- a/Lib/ctypes/test/test_arrays.py
+++ b/Lib/ctypes/test/test_arrays.py
@@ -24,20 +24,24 @@
self.assertEqual(len(ia), alen)
# slot values ok?
- values = [ia[i] for i in range(len(init))]
+ values = [ia[i] for i in range(alen)]
self.assertEqual(values, init)
+ # out-of-bounds accesses should be caught
+ with self.assertRaises(IndexError): ia[alen]
+ with self.assertRaises(IndexError): ia[-alen-1]
+
# change the items
from operator import setitem
new_values = list(range(42, 42+alen))
[setitem(ia, n, new_values[n]) for n in range(alen)]
- values = [ia[i] for i in range(len(init))]
+ values = [ia[i] for i in range(alen)]
self.assertEqual(values, new_values)
# are the items initialized to 0?
ia = int_array()
- values = [ia[i] for i in range(len(init))]
- self.assertEqual(values, [0] * len(init))
+ values = [ia[i] for i in range(alen)]
+ self.assertEqual(values, [0] * alen)
# Too many initializers should be caught
self.assertRaises(IndexError, int_array, *range(alen*2))
diff --git a/Lib/ctypes/test/test_pointers.py b/Lib/ctypes/test/test_pointers.py
--- a/Lib/ctypes/test/test_pointers.py
+++ b/Lib/ctypes/test/test_pointers.py
@@ -56,9 +56,13 @@
# C code:
# int x = 12321;
# res = &x
- res.contents = c_int(12321)
+ x = c_int(12321)
+ res.contents = x
self.assertEqual(i.value, 54345)
+ x.value = -99
+ self.assertEqual(res.contents.value, -99)
+
def test_callbacks_with_pointers(self):
# a function type receiving a pointer
PROTOTYPE = CFUNCTYPE(c_int, POINTER(c_int))
@@ -131,9 +135,10 @@
def test_basic(self):
p = pointer(c_int(42))
- # Although a pointer can be indexed, it ha no length
+ # Although a pointer can be indexed, it has no length
self.assertRaises(TypeError, len, p)
self.assertEqual(p[0], 42)
+ self.assertEqual(p[0:1], [42])
self.assertEqual(p.contents.value, 42)
def test_charpp(self):
diff --git a/Lib/test/eintrdata/eintr_tester.py b/Lib/test/eintrdata/eintr_tester.py
--- a/Lib/test/eintrdata/eintr_tester.py
+++ b/Lib/test/eintrdata/eintr_tester.py
@@ -334,10 +334,12 @@
self._test_open("fp = open(path, 'r')\nfp.close()",
self.python_open)
+ @unittest.skipIf(sys.platform == 'darwin', "hangs under OS X; see issue #25234")
def os_open(self, path):
fd = os.open(path, os.O_WRONLY)
os.close(fd)
+ @unittest.skipIf(sys.platform == "darwin", "hangs under OS X; see issue #25234")
def test_os_open(self):
self._test_open("fd = os.open(path, os.O_RDONLY)\nos.close(fd)",
self.os_open)
@@ -370,10 +372,10 @@
@unittest.skipUnless(hasattr(signal, 'sigwaitinfo'),
'need signal.sigwaitinfo()')
def test_sigwaitinfo(self):
- # Issue #25277: The sleep is a weak synchronization between the parent
- # and the child process. If the sleep is too low, the test hangs on
- # slow or highly loaded systems.
- self.sleep_time = 2.0
+ # Issue #25277, #25868: give a few miliseconds to the parent process
+ # between os.write() and signal.sigwaitinfo() to works around a race
+ # condition
+ self.sleep_time = 0.100
signum = signal.SIGUSR1
pid = os.getpid()
@@ -381,18 +383,28 @@
old_handler = signal.signal(signum, lambda *args: None)
self.addCleanup(signal.signal, signum, old_handler)
+ rpipe, wpipe = os.pipe()
+
code = '\n'.join((
'import os, time',
'pid = %s' % os.getpid(),
'signum = %s' % int(signum),
'sleep_time = %r' % self.sleep_time,
+ 'rpipe = %r' % rpipe,
+ 'os.read(rpipe, 1)',
+ 'os.close(rpipe)',
'time.sleep(sleep_time)',
'os.kill(pid, signum)',
))
t0 = time.monotonic()
- proc = self.subprocess(code)
+ proc = self.subprocess(code, pass_fds=(rpipe,))
+ os.close(rpipe)
with kill_on_error(proc):
+ # sync child-parent
+ os.write(wpipe, b'x')
+ os.close(wpipe)
+
# parent
signal.sigwaitinfo([signum])
dt = time.monotonic() - t0
diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py
--- a/Lib/test/test_sysconfig.py
+++ b/Lib/test/test_sysconfig.py
@@ -421,6 +421,8 @@
print("var3=42", file=makefile)
print("var4=$/invalid", file=makefile)
print("var5=dollar$$5", file=makefile)
+ print("var6=${var3}/lib/python3.5/config-$(VAR2)$(var5)"
+ "-x86_64-linux-gnu", file=makefile)
vars = sysconfig._parse_makefile(TESTFN)
self.assertEqual(vars, {
'var1': 'ab42',
@@ -428,6 +430,7 @@
'var3': 42,
'var4': '$/invalid',
'var5': 'dollar$5',
+ 'var6': '42/lib/python3.5/config-b42dollar$5-x86_64-linux-gnu',
})
diff --git a/Misc/ACKS b/Misc/ACKS
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -1497,6 +1497,7 @@
Sebastian Ortiz Vasquez
Alexandre Vassalotti
Nadeem Vawda
+Sye van der Veen
Frank Vercruesse
Mike Verdone
Jaap Vermeulen
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -66,6 +66,10 @@
Library
-------
+- Issue #26227: On Windows, getnameinfo(), gethostbyaddr() and
+ gethostbyname_ex() functions of the socket module now decode the hostname
+ from the ANSI code page rather than UTF-8.
+
- Issue #26147: xmlrpc now works with strings not encodable with used
non-UTF-8 encoding.
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -4519,6 +4519,19 @@
Return the IP address (a string of the form '255.255.255.255') for a host.");
+static PyObject*
+sock_decode_hostname(const char *name)
+{
+#ifdef MS_WINDOWS
+ /* Issue #26227: gethostbyaddr() returns a string encoded
+ * to the ANSI code page */
+ return PyUnicode_DecodeFSDefault(name);
+#else
+ /* Decode from UTF-8 */
+ return PyUnicode_FromString(name);
+#endif
+}
+
/* Convenience function common to gethostbyname_ex and gethostbyaddr */
static PyObject *
@@ -4529,6 +4542,7 @@
PyObject *name_list = (PyObject *)NULL;
PyObject *addr_list = (PyObject *)NULL;
PyObject *tmp;
+ PyObject *name;
if (h == NULL) {
/* Let's get real error message to return */
@@ -4637,7 +4651,10 @@
goto err;
}
- rtn_tuple = Py_BuildValue("sOO", h->h_name, name_list, addr_list);
+ name = sock_decode_hostname(h->h_name);
+ if (name == NULL)
+ goto err;
+ rtn_tuple = Py_BuildValue("NOO", name, name_list, addr_list);
err:
Py_XDECREF(name_list);
@@ -5623,6 +5640,7 @@
struct addrinfo hints, *res = NULL;
int error;
PyObject *ret = (PyObject *)NULL;
+ PyObject *name;
flags = flowinfo = scope_id = 0;
if (!PyArg_ParseTuple(args, "Oi:getnameinfo", &sa, &flags))
@@ -5686,7 +5704,11 @@
set_gaierror(error);
goto fail;
}
- ret = Py_BuildValue("ss", hbuf, pbuf);
+
+ name = sock_decode_hostname(hbuf);
+ if (name == NULL)
+ goto fail;
+ ret = Py_BuildValue("Ns", name, pbuf);
fail:
if (res)
--
Repository URL: https://hg.python.org/cpython
More information about the Python-checkins
mailing list