Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b49a1ed

Browse files
Merge heads
2 parents c8241fd + 8f475ef commit b49a1ed

9 files changed

Lines changed: 119 additions & 18 deletions

File tree

Doc/c-api/stable.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,5 @@ will work on all subsequent Python releases, but fail to load (because of
3434
missing symbols) on the older releases.
3535

3636
As of Python 3.2, the set of functions available to the limited API is
37-
documented in PEP 384. In the C API documentation, API elements that are not
37+
documented in :pep:`384`. In the C API documentation, API elements that are not
3838
part of the limited API are marked as "Not part of the limited API."

Doc/library/ctypes.rst

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -716,8 +716,8 @@ Pointer instances are created by calling the :func:`pointer` function on a
716716
>>> pi = pointer(i)
717717
>>>
718718

719-
Pointer instances have a :attr:`contents` attribute which returns the object to
720-
which the pointer points, the ``i`` object above::
719+
Pointer instances have a :attr:`~_Pointer.contents` attribute which
720+
returns the object to which the pointer points, the ``i`` object above::
721721

722722
>>> pi.contents
723723
c_long(42)
@@ -2401,6 +2401,56 @@ other data types containing pointer type fields.
24012401
Arrays and pointers
24022402
^^^^^^^^^^^^^^^^^^^
24032403

2404-
Not yet written - please see the sections :ref:`ctypes-pointers` and section
2405-
:ref:`ctypes-arrays` in the tutorial.
2404+
.. class:: Array(\*args)
2405+
2406+
Abstract base class for arrays.
2407+
2408+
The recommended way to create concrete array types is by multiplying any
2409+
:mod:`ctypes` data type with a positive integer. Alternatively, you can subclass
2410+
this type and define :attr:`_length_` and :attr:`_type_` class variables.
2411+
Array elements can be read and written using standard
2412+
subscript and slice accesses; for slice reads, the resulting object is
2413+
*not* itself an :class:`Array`.
2414+
2415+
2416+
.. attribute:: _length_
2417+
2418+
A positive integer specifying the number of elements in the array.
2419+
Out-of-range subscripts result in an :exc:`IndexError`. Will be
2420+
returned by :func:`len`.
2421+
2422+
2423+
.. attribute:: _type_
2424+
2425+
Specifies the type of each element in the array.
2426+
2427+
2428+
Array subclass constructors accept positional arguments, used to
2429+
initialize the elements in order.
2430+
2431+
2432+
.. class:: _Pointer
2433+
2434+
Private, abstract base class for pointers.
2435+
2436+
Concrete pointer types are created by calling :func:`POINTER` with the
2437+
type that will be pointed to; this is done automatically by
2438+
:func:`pointer`.
2439+
2440+
If a pointer points to an array, its elements can be read and
2441+
written using standard subscript and slice accesses. Pointer objects
2442+
have no size, so :func:`len` will raise :exc:`TypeError`. Negative
2443+
subscripts will read from the memory *before* the pointer (as in C), and
2444+
out-of-range subscripts will probably crash with an access violation (if
2445+
you're lucky).
2446+
2447+
2448+
.. attribute:: _type_
2449+
2450+
Specifies the type pointed to.
2451+
2452+
.. attribute:: contents
2453+
2454+
Returns the object to which to pointer points. Assigning to this
2455+
attribute changes the pointer to point to the assigned object.
24062456

Lib/ctypes/test/test_arrays.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,24 @@ def test_simple(self):
2424
self.assertEqual(len(ia), alen)
2525

2626
# slot values ok?
27-
values = [ia[i] for i in range(len(init))]
27+
values = [ia[i] for i in range(alen)]
2828
self.assertEqual(values, init)
2929

30+
# out-of-bounds accesses should be caught
31+
with self.assertRaises(IndexError): ia[alen]
32+
with self.assertRaises(IndexError): ia[-alen-1]
33+
3034
# change the items
3135
from operator import setitem
3236
new_values = list(range(42, 42+alen))
3337
[setitem(ia, n, new_values[n]) for n in range(alen)]
34-
values = [ia[i] for i in range(len(init))]
38+
values = [ia[i] for i in range(alen)]
3539
self.assertEqual(values, new_values)
3640

3741
# are the items initialized to 0?
3842
ia = int_array()
39-
values = [ia[i] for i in range(len(init))]
40-
self.assertEqual(values, [0] * len(init))
43+
values = [ia[i] for i in range(alen)]
44+
self.assertEqual(values, [0] * alen)
4145

4246
# Too many initializers should be caught
4347
self.assertRaises(IndexError, int_array, *range(alen*2))

Lib/ctypes/test/test_pointers.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,13 @@ def test_change_pointers(self):
5656
# C code:
5757
# int x = 12321;
5858
# res = &x
59-
res.contents = c_int(12321)
59+
x = c_int(12321)
60+
res.contents = x
6061
self.assertEqual(i.value, 54345)
6162

63+
x.value = -99
64+
self.assertEqual(res.contents.value, -99)
65+
6266
def test_callbacks_with_pointers(self):
6367
# a function type receiving a pointer
6468
PROTOTYPE = CFUNCTYPE(c_int, POINTER(c_int))
@@ -131,9 +135,10 @@ class Table(Structure):
131135

132136
def test_basic(self):
133137
p = pointer(c_int(42))
134-
# Although a pointer can be indexed, it ha no length
138+
# Although a pointer can be indexed, it has no length
135139
self.assertRaises(TypeError, len, p)
136140
self.assertEqual(p[0], 42)
141+
self.assertEqual(p[0:1], [42])
137142
self.assertEqual(p.contents.value, 42)
138143

139144
def test_charpp(self):

Lib/test/eintrdata/eintr_tester.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -334,10 +334,12 @@ def test_open(self):
334334
self._test_open("fp = open(path, 'r')\nfp.close()",
335335
self.python_open)
336336

337+
@unittest.skipIf(sys.platform == 'darwin', "hangs under OS X; see issue #25234")
337338
def os_open(self, path):
338339
fd = os.open(path, os.O_WRONLY)
339340
os.close(fd)
340341

342+
@unittest.skipIf(sys.platform == "darwin", "hangs under OS X; see issue #25234")
341343
def test_os_open(self):
342344
self._test_open("fd = os.open(path, os.O_RDONLY)\nos.close(fd)",
343345
self.os_open)
@@ -370,29 +372,39 @@ def test_sigtimedwait(self):
370372
@unittest.skipUnless(hasattr(signal, 'sigwaitinfo'),
371373
'need signal.sigwaitinfo()')
372374
def test_sigwaitinfo(self):
373-
# Issue #25277: The sleep is a weak synchronization between the parent
374-
# and the child process. If the sleep is too low, the test hangs on
375-
# slow or highly loaded systems.
376-
self.sleep_time = 2.0
375+
# Issue #25277, #25868: give a few miliseconds to the parent process
376+
# between os.write() and signal.sigwaitinfo() to works around a race
377+
# condition
378+
self.sleep_time = 0.100
377379

378380
signum = signal.SIGUSR1
379381
pid = os.getpid()
380382

381383
old_handler = signal.signal(signum, lambda *args: None)
382384
self.addCleanup(signal.signal, signum, old_handler)
383385

386+
rpipe, wpipe = os.pipe()
387+
384388
code = '\n'.join((
385389
'import os, time',
386390
'pid = %s' % os.getpid(),
387391
'signum = %s' % int(signum),
388392
'sleep_time = %r' % self.sleep_time,
393+
'rpipe = %r' % rpipe,
394+
'os.read(rpipe, 1)',
395+
'os.close(rpipe)',
389396
'time.sleep(sleep_time)',
390397
'os.kill(pid, signum)',
391398
))
392399

393400
t0 = time.monotonic()
394-
proc = self.subprocess(code)
401+
proc = self.subprocess(code, pass_fds=(rpipe,))
402+
os.close(rpipe)
395403
with kill_on_error(proc):
404+
# sync child-parent
405+
os.write(wpipe, b'x')
406+
os.close(wpipe)
407+
396408
# parent
397409
signal.sigwaitinfo([signum])
398410
dt = time.monotonic() - t0

Lib/test/test_sysconfig.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,13 +421,16 @@ def test_parse_makefile(self):
421421
print("var3=42", file=makefile)
422422
print("var4=$/invalid", file=makefile)
423423
print("var5=dollar$$5", file=makefile)
424+
print("var6=${var3}/lib/python3.5/config-$(VAR2)$(var5)"
425+
"-x86_64-linux-gnu", file=makefile)
424426
vars = sysconfig._parse_makefile(TESTFN)
425427
self.assertEqual(vars, {
426428
'var1': 'ab42',
427429
'VAR2': 'b42',
428430
'var3': 42,
429431
'var4': '$/invalid',
430432
'var5': 'dollar$5',
433+
'var6': '42/lib/python3.5/config-b42dollar$5-x86_64-linux-gnu',
431434
})
432435

433436

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1497,6 +1497,7 @@ Dmitry Vasiliev
14971497
Sebastian Ortiz Vasquez
14981498
Alexandre Vassalotti
14991499
Nadeem Vawda
1500+
Sye van der Veen
15001501
Frank Vercruesse
15011502
Mike Verdone
15021503
Jaap Vermeulen

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ Core and Builtins
6666
Library
6767
-------
6868

69+
- Issue #26227: On Windows, getnameinfo(), gethostbyaddr() and
70+
gethostbyname_ex() functions of the socket module now decode the hostname
71+
from the ANSI code page rather than UTF-8.
72+
6973
- Issue #26147: xmlrpc now works with strings not encodable with used
7074
non-UTF-8 encoding.
7175

Modules/socketmodule.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4519,6 +4519,19 @@ PyDoc_STRVAR(gethostbyname_doc,
45194519
Return the IP address (a string of the form '255.255.255.255') for a host.");
45204520

45214521

4522+
static PyObject*
4523+
sock_decode_hostname(const char *name)
4524+
{
4525+
#ifdef MS_WINDOWS
4526+
/* Issue #26227: gethostbyaddr() returns a string encoded
4527+
* to the ANSI code page */
4528+
return PyUnicode_DecodeFSDefault(name);
4529+
#else
4530+
/* Decode from UTF-8 */
4531+
return PyUnicode_FromString(name);
4532+
#endif
4533+
}
4534+
45224535
/* Convenience function common to gethostbyname_ex and gethostbyaddr */
45234536

45244537
static PyObject *
@@ -4529,6 +4542,7 @@ gethost_common(struct hostent *h, struct sockaddr *addr, size_t alen, int af)
45294542
PyObject *name_list = (PyObject *)NULL;
45304543
PyObject *addr_list = (PyObject *)NULL;
45314544
PyObject *tmp;
4545+
PyObject *name;
45324546

45334547
if (h == NULL) {
45344548
/* 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)
46374651
goto err;
46384652
}
46394653

4640-
rtn_tuple = Py_BuildValue("sOO", h->h_name, name_list, addr_list);
4654+
name = sock_decode_hostname(h->h_name);
4655+
if (name == NULL)
4656+
goto err;
4657+
rtn_tuple = Py_BuildValue("NOO", name, name_list, addr_list);
46414658

46424659
err:
46434660
Py_XDECREF(name_list);
@@ -5623,6 +5640,7 @@ socket_getnameinfo(PyObject *self, PyObject *args)
56235640
struct addrinfo hints, *res = NULL;
56245641
int error;
56255642
PyObject *ret = (PyObject *)NULL;
5643+
PyObject *name;
56265644

56275645
flags = flowinfo = scope_id = 0;
56285646
if (!PyArg_ParseTuple(args, "Oi:getnameinfo", &sa, &flags))
@@ -5686,7 +5704,11 @@ socket_getnameinfo(PyObject *self, PyObject *args)
56865704
set_gaierror(error);
56875705
goto fail;
56885706
}
5689-
ret = Py_BuildValue("ss", hbuf, pbuf);
5707+
5708+
name = sock_decode_hostname(hbuf);
5709+
if (name == NULL)
5710+
goto fail;
5711+
ret = Py_BuildValue("Ns", name, pbuf);
56905712

56915713
fail:
56925714
if (res)

0 commit comments

Comments
 (0)