Merge heads
This commit is contained in:
commit
b49a1edc15
|
@ -34,5 +34,5 @@ will work on all subsequent Python releases, but fail to load (because of
|
|||
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."
|
||||
|
|
|
@ -716,8 +716,8 @@ Pointer instances are created by calling the :func:`pointer` function on a
|
|||
>>> 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 @@ other data types containing pointer type fields.
|
|||
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.
|
||||
|
||||
|
|
|
@ -24,20 +24,24 @@ class ArrayTestCase(unittest.TestCase):
|
|||
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))
|
||||
|
|
|
@ -56,9 +56,13 @@ class PointersTestCase(unittest.TestCase):
|
|||
# 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 @@ class PointersTestCase(unittest.TestCase):
|
|||
|
||||
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):
|
||||
|
|
|
@ -334,10 +334,12 @@ class SocketEINTRTest(EINTRBaseTest):
|
|||
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 @@ class SignalEINTRTest(EINTRBaseTest):
|
|||
@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 @@ class SignalEINTRTest(EINTRBaseTest):
|
|||
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
|
||||
|
|
|
@ -421,6 +421,8 @@ class MakefileTests(unittest.TestCase):
|
|||
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 @@ class MakefileTests(unittest.TestCase):
|
|||
'var3': 42,
|
||||
'var4': '$/invalid',
|
||||
'var5': 'dollar$5',
|
||||
'var6': '42/lib/python3.5/config-b42dollar$5-x86_64-linux-gnu',
|
||||
})
|
||||
|
||||
|
||||
|
|
|
@ -1497,6 +1497,7 @@ Dmitry Vasiliev
|
|||
Sebastian Ortiz Vasquez
|
||||
Alexandre Vassalotti
|
||||
Nadeem Vawda
|
||||
Sye van der Veen
|
||||
Frank Vercruesse
|
||||
Mike Verdone
|
||||
Jaap Vermeulen
|
||||
|
|
|
@ -66,6 +66,10 @@ Core and Builtins
|
|||
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.
|
||||
|
||||
|
|
|
@ -4519,6 +4519,19 @@ PyDoc_STRVAR(gethostbyname_doc,
|
|||
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 @@ gethost_common(struct hostent *h, struct sockaddr *addr, size_t alen, int af)
|
|||
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 @@ gethost_common(struct hostent *h, struct sockaddr *addr, size_t alen, int af)
|
|||
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 @@ socket_getnameinfo(PyObject *self, PyObject *args)
|
|||
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 @@ socket_getnameinfo(PyObject *self, PyObject *args)
|
|||
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)
|
||||
|
|
Loading…
Reference in New Issue