Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-105751: test_ctypes avoids the operator module #105797

Merged
merged 1 commit into from
Jun 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 4 additions & 4 deletions Lib/test/test_ctypes/test_arrays.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ def test_simple(self):
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)]
for n in range(alen):
ia[n] = new_values[n]
values = [ia[i] for i in range(alen)]
self.assertEqual(values, new_values)

Expand Down Expand Up @@ -79,8 +79,8 @@ def test_simple(self):
self.assertEqual(len(ca), 3)

# cannot delete items
from operator import delitem
self.assertRaises(TypeError, delitem, ca, 0)
with self.assertRaises(TypeError):
del ca[0]

def test_step_overflow(self):
a = (c_int * 5)()
Expand Down
8 changes: 4 additions & 4 deletions Lib/test/test_ctypes/test_callbacks.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import functools
import sys
import unittest
from test import support

Expand Down Expand Up @@ -109,15 +110,14 @@ def test_char_p(self):

def test_pyobject(self):
o = ()
from sys import getrefcount as grc
for o in (), [], object():
initial = grc(o)
initial = sys.getrefcount(o)
# This call leaks a reference to 'o'...
self.check_type(py_object, o)
before = grc(o)
before = sys.getrefcount(o)
# ...but this call doesn't leak any more. Where is the refcount?
self.check_type(py_object, o)
after = grc(o)
after = sys.getrefcount(o)
self.assertEqual((after, o), (before, o))

def test_unsupported_restype_1(self):
Expand Down
14 changes: 8 additions & 6 deletions Lib/test/test_ctypes/test_delattr.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,18 @@ class X(Structure):

class TestCase(unittest.TestCase):
def test_simple(self):
self.assertRaises(TypeError,
delattr, c_int(42), "value")
with self.assertRaises(TypeError):
del c_int(42).value

def test_chararray(self):
self.assertRaises(TypeError,
delattr, (c_char * 5)(), "value")
chararray = (c_char * 5)()
with self.assertRaises(TypeError):
del chararray.value

def test_struct(self):
self.assertRaises(TypeError,
delattr, X(), "foo")
struct = X()
with self.assertRaises(TypeError):
del struct.foo


if __name__ == "__main__":
Expand Down
10 changes: 5 additions & 5 deletions Lib/test/test_ctypes/test_internals.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# This tests the internal _objects attribute
import sys
import unittest
from ctypes import Structure, POINTER, c_char_p, c_int
from sys import getrefcount as grc

# XXX This test must be reviewed for correctness!!!

Expand All @@ -20,16 +20,16 @@ def assertSame(self, a, b):

def test_ints(self):
i = 42000123
refcnt = grc(i)
refcnt = sys.getrefcount(i)
ci = c_int(i)
self.assertEqual(refcnt, grc(i))
self.assertEqual(refcnt, sys.getrefcount(i))
self.assertEqual(ci._objects, None)

def test_c_char_p(self):
s = b"Hello, World"
refcnt = grc(s)
refcnt = sys.getrefcount(s)
cs = c_char_p(s)
self.assertEqual(refcnt + 1, grc(s))
self.assertEqual(refcnt + 1, sys.getrefcount(s))
self.assertSame(cs._objects, s)

def test_simple_struct(self):
Expand Down
11 changes: 6 additions & 5 deletions Lib/test/test_ctypes/test_keeprefs.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from ctypes import Structure, POINTER, pointer, c_char_p, c_int
import sys
import unittest
from ctypes import Structure, POINTER, pointer, c_char_p, c_int


class SimpleTestCase(unittest.TestCase):
def test_cint(self):
Expand Down Expand Up @@ -100,16 +102,15 @@ class X(Structure):
_fields_ = [("p", POINTER(c_char_p))]
x = X()
i = c_char_p("abc def")
from sys import getrefcount as grc
print("2?", grc(i))
print("2?", sys.getrefcount(i))
x.p = pointer(i)
print("3?", grc(i))
print("3?", sys.getrefcount(i))
for i in range(320):
c_int(99)
x.p[0]
print(x.p[0])
## del x
## print "2?", grc(i)
## print "2?", sys.getrefcount(i)
## del i
import gc
gc.collect()
Expand Down
4 changes: 2 additions & 2 deletions Lib/test/test_ctypes/test_pointers.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ def func(arg):
## print self.result

def test_basics(self):
from operator import delitem
for ct, pt in zip(ctype_types, python_types):
i = ct(42)
p = pointer(i)
Expand All @@ -108,7 +107,8 @@ def test_basics(self):
## self.assertEqual(p.contents, 42)
## self.assertEqual(p[0], 42)

self.assertRaises(TypeError, delitem, p, 0)
with self.assertRaises(TypeError):
del p[0]

def test_from_address(self):
from array import array
Expand Down
22 changes: 11 additions & 11 deletions Lib/test/test_ctypes/test_python_api.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import unittest
import sys
from test import support
from ctypes import (pythonapi, POINTER, c_buffer, sizeof,
py_object, c_char_p, c_char, c_long, c_size_t)
Expand All @@ -11,7 +12,6 @@

################################################################

from sys import getrefcount as grc

class PythonAPITestCase(unittest.TestCase):

Expand All @@ -29,41 +29,41 @@ def test_PyString_FromString(self):
pythonapi.PyBytes_FromString.argtypes = (c_char_p,)

s = b"abc"
refcnt = grc(s)
refcnt = sys.getrefcount(s)
pyob = pythonapi.PyBytes_FromString(s)
self.assertEqual(grc(s), refcnt)
self.assertEqual(sys.getrefcount(s), refcnt)
self.assertEqual(s, pyob)
del pyob
self.assertEqual(grc(s), refcnt)
self.assertEqual(sys.getrefcount(s), refcnt)

@support.refcount_test
def test_PyLong_Long(self):
ref42 = grc(42)
ref42 = sys.getrefcount(42)
pythonapi.PyLong_FromLong.restype = py_object
self.assertEqual(pythonapi.PyLong_FromLong(42), 42)

self.assertEqual(grc(42), ref42)
self.assertEqual(sys.getrefcount(42), ref42)

pythonapi.PyLong_AsLong.argtypes = (py_object,)
pythonapi.PyLong_AsLong.restype = c_long

res = pythonapi.PyLong_AsLong(42)
# Small int refcnts don't change
self.assertEqual(grc(res), ref42)
self.assertEqual(sys.getrefcount(res), ref42)
del res
self.assertEqual(grc(42), ref42)
self.assertEqual(sys.getrefcount(42), ref42)

@support.refcount_test
def test_PyObj_FromPtr(self):
s = "abc def ghi jkl"
ref = grc(s)
ref = sys.getrefcount(s)
# id(python-object) is the address
pyobj = PyObj_FromPtr(id(s))
self.assertIs(s, pyobj)

self.assertEqual(grc(s), ref + 1)
self.assertEqual(sys.getrefcount(s), ref + 1)
del pyobj
self.assertEqual(grc(s), ref)
self.assertEqual(sys.getrefcount(s), ref)

def test_PyOS_snprintf(self):
PyOS_snprintf = pythonapi.PyOS_snprintf
Expand Down
32 changes: 15 additions & 17 deletions Lib/test/test_ctypes/test_refcounts.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import unittest
from test import support
import ctypes
import gc
import sys
import unittest
from test import support

MyCallback = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int)
OtherCallback = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_ulonglong)
Expand All @@ -13,8 +14,6 @@ class RefcountTestCase(unittest.TestCase):

@support.refcount_test
def test_1(self):
from sys import getrefcount as grc

f = dll._testfunc_callback_i_if
f.restype = ctypes.c_int
f.argtypes = [ctypes.c_int, MyCallback]
Expand All @@ -23,66 +22,65 @@ def callback(value):
#print "called back with", value
return value

self.assertEqual(grc(callback), 2)
self.assertEqual(sys.getrefcount(callback), 2)
cb = MyCallback(callback)

self.assertGreater(grc(callback), 2)
self.assertGreater(sys.getrefcount(callback), 2)
result = f(-10, cb)
self.assertEqual(result, -18)
cb = None

gc.collect()

self.assertEqual(grc(callback), 2)
self.assertEqual(sys.getrefcount(callback), 2)


@support.refcount_test
def test_refcount(self):
from sys import getrefcount as grc
def func(*args):
pass
# this is the standard refcount for func
self.assertEqual(grc(func), 2)
self.assertEqual(sys.getrefcount(func), 2)

# the CFuncPtr instance holds at least one refcount on func:
f = OtherCallback(func)
self.assertGreater(grc(func), 2)
self.assertGreater(sys.getrefcount(func), 2)

# and may release it again
del f
self.assertGreaterEqual(grc(func), 2)
self.assertGreaterEqual(sys.getrefcount(func), 2)

# but now it must be gone
gc.collect()
self.assertEqual(grc(func), 2)
self.assertEqual(sys.getrefcount(func), 2)

class X(ctypes.Structure):
_fields_ = [("a", OtherCallback)]
x = X()
x.a = OtherCallback(func)

# the CFuncPtr instance holds at least one refcount on func:
self.assertGreater(grc(func), 2)
self.assertGreater(sys.getrefcount(func), 2)

# and may release it again
del x
self.assertGreaterEqual(grc(func), 2)
self.assertGreaterEqual(sys.getrefcount(func), 2)

# and now it must be gone again
gc.collect()
self.assertEqual(grc(func), 2)
self.assertEqual(sys.getrefcount(func), 2)

f = OtherCallback(func)

# the CFuncPtr instance holds at least one refcount on func:
self.assertGreater(grc(func), 2)
self.assertGreater(sys.getrefcount(func), 2)

# create a cycle
f.cycle = f

del f
gc.collect()
self.assertEqual(grc(func), 2)
self.assertEqual(sys.getrefcount(func), 2)

class AnotherLeak(unittest.TestCase):
def test_callback(self):
Expand Down
50 changes: 27 additions & 23 deletions Lib/test/test_ctypes/test_slicing.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,21 @@ def test_setslice_cint(self):
b[33::-3] = range(12)
self.assertEqual(a[:], b)

from operator import setitem

# TypeError: int expected instead of str instance
self.assertRaises(TypeError, setitem, a, slice(0, 5), "abcde")
with self.assertRaises(TypeError):
a[:5] = "abcde"

# TypeError: int expected instead of str instance
self.assertRaises(TypeError, setitem, a, slice(0, 5),
["a", "b", "c", "d", "e"])
with self.assertRaises(TypeError):
a[:5] = ["a", "b", "c", "d", "e"]

# TypeError: int expected instead of float instance
self.assertRaises(TypeError, setitem, a, slice(0, 5),
[1, 2, 3, 4, 3.14])
with self.assertRaises(TypeError):
a[:5] = [1, 2, 3, 4, 3.14]

# ValueError: Can only assign sequence of same size
self.assertRaises(ValueError, setitem, a, slice(0, 5), range(32))
with self.assertRaises(ValueError):
a[:5] = range(32)

def test_char_ptr(self):
s = b"abcdefghijklmnopqrstuvwxyz"
Expand All @@ -74,18 +77,20 @@ def test_char_ptr(self):
self.assertEqual(res[len(s)-1:5:-7], s[:5:-7])
self.assertEqual(res[0:-1:-1], s[0::-1])

import operator
self.assertRaises(ValueError, operator.getitem,
res, slice(None, None, None))
self.assertRaises(ValueError, operator.getitem,
res, slice(0, None, None))
self.assertRaises(ValueError, operator.getitem,
res, slice(None, 5, -1))
self.assertRaises(ValueError, operator.getitem,
res, slice(-5, None, None))

self.assertRaises(TypeError, operator.setitem,
res, slice(0, 5), "abcde")
# get items
with self.assertRaises(ValueError):
res[:]
with self.assertRaises(ValueError):
res[0:]
with self.assertRaises(ValueError):
res[:5:-1]
with self.assertRaises(ValueError):
res[-5:]

# set items
with self.assertRaises(TypeError):
res[:5] = "abcde"

dll.my_free(res)

dll.my_strdup.restype = POINTER(c_byte)
Expand Down Expand Up @@ -141,9 +146,8 @@ def test_wchar_ptr(self):
self.assertEqual(res[len(s)-1:-1:-1], s[::-1])
self.assertEqual(res[len(s)-1:5:-7], s[:5:-7])

import operator
self.assertRaises(TypeError, operator.setitem,
res, slice(0, 5), "abcde")
with self.assertRaises(TypeError):
res[:5] = "abcde"
dll.my_free(res)

if sizeof(c_wchar) == sizeof(c_short):
Expand Down