[Python-checkins] cpython (2.7): Issue #19023: Document ctypes array and pointer classes

martin.panter python-checkins at python.org
Thu Jan 28 18:21:40 EST 2016


https://hg.python.org/cpython/rev/034b077d3015
changeset:   100109:034b077d3015
branch:      2.7
user:        Martin Panter <vadmium+py at gmail.com>
date:        Fri Jan 29 10:12:19 2016 +0000
summary:
  Issue #19023: Document ctypes array and pointer classes

Also add some more tests. Based on patch by Sye van der Veen.

files:
  Doc/library/ctypes.rst           |  60 ++++++++++++++++++-
  Lib/ctypes/test/test_arrays.py   |  12 ++-
  Lib/ctypes/test/test_pointers.py |   9 ++-
  Misc/ACKS                        |   1 +
  4 files changed, 71 insertions(+), 11 deletions(-)


diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst
--- a/Doc/library/ctypes.rst
+++ b/Doc/library/ctypes.rst
@@ -708,8 +708,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)
@@ -2512,6 +2512,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 = 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
@@ -53,9 +53,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))
@@ -128,9 +132,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/Misc/ACKS b/Misc/ACKS
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -1418,6 +1418,7 @@
 Sebastian Ortiz Vasquez
 Alexandre Vassalotti
 Nadeem Vawda
+Sye van der Veen
 Frank Vercruesse
 Mike Verdone
 Jaap Vermeulen

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


More information about the Python-checkins mailing list