]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Add more C API tests (GH-112522)
authorSerhiy Storchaka <storchaka@gmail.com>
Wed, 29 Nov 2023 15:37:05 +0000 (17:37 +0200)
committerGitHub <noreply@github.com>
Wed, 29 Nov 2023 15:37:05 +0000 (17:37 +0200)
Add tests for PyObject_Str(), PyObject_Repr(), PyObject_ASCII() and
PyObject_Bytes().

Lib/test/test_capi/test_abstract.py
Modules/_testcapi/abstract.c

index 26152c3049848ce78c83c0614c0617200e43d0b2..97ed939928c360158a483906674d538670cdcb42 100644 (file)
@@ -8,6 +8,30 @@ from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX
 
 NULL = None
 
+class StrSubclass(str):
+    pass
+
+class BytesSubclass(bytes):
+    pass
+
+class WithStr:
+    def __init__(self, value):
+        self.value = value
+    def __str__(self):
+        return self.value
+
+class WithRepr:
+    def __init__(self, value):
+        self.value = value
+    def __repr__(self):
+        return self.value
+
+class WithBytes:
+    def __init__(self, value):
+        self.value = value
+    def __bytes__(self):
+        return self.value
+
 class TestObject:
     @property
     def evil(self):
@@ -44,6 +68,68 @@ def gen():
 
 
 class CAPITest(unittest.TestCase):
+    def assertTypedEqual(self, actual, expected):
+        self.assertIs(type(actual), type(expected))
+        self.assertEqual(actual, expected)
+
+    def test_object_str(self):
+        # Test PyObject_Str()
+        object_str = _testcapi.object_str
+        self.assertTypedEqual(object_str(''), '')
+        self.assertTypedEqual(object_str('abc'), 'abc')
+        self.assertTypedEqual(object_str('\U0001f40d'), '\U0001f40d')
+        self.assertTypedEqual(object_str(StrSubclass('abc')), 'abc')
+        self.assertTypedEqual(object_str(WithStr('abc')), 'abc')
+        self.assertTypedEqual(object_str(WithStr(StrSubclass('abc'))), StrSubclass('abc'))
+        self.assertTypedEqual(object_str(WithRepr('<abc>')), '<abc>')
+        self.assertTypedEqual(object_str(WithRepr(StrSubclass('<abc>'))), StrSubclass('<abc>'))
+        self.assertTypedEqual(object_str(NULL), '<NULL>')
+
+    def test_object_repr(self):
+        # Test PyObject_Repr()
+        object_repr = _testcapi.object_repr
+        self.assertTypedEqual(object_repr(''), "''")
+        self.assertTypedEqual(object_repr('abc'), "'abc'")
+        self.assertTypedEqual(object_repr('\U0001f40d'), "'\U0001f40d'")
+        self.assertTypedEqual(object_repr(StrSubclass('abc')), "'abc'")
+        self.assertTypedEqual(object_repr(WithRepr('<abc>')), '<abc>')
+        self.assertTypedEqual(object_repr(WithRepr(StrSubclass('<abc>'))), StrSubclass('<abc>'))
+        self.assertTypedEqual(object_repr(WithRepr('<\U0001f40d>')), '<\U0001f40d>')
+        self.assertTypedEqual(object_repr(WithRepr(StrSubclass('<\U0001f40d>'))), StrSubclass('<\U0001f40d>'))
+        self.assertTypedEqual(object_repr(NULL), '<NULL>')
+
+    def test_object_ascii(self):
+        # Test PyObject_ASCII()
+        object_ascii = _testcapi.object_ascii
+        self.assertTypedEqual(object_ascii(''), "''")
+        self.assertTypedEqual(object_ascii('abc'), "'abc'")
+        self.assertTypedEqual(object_ascii('\U0001f40d'), r"'\U0001f40d'")
+        self.assertTypedEqual(object_ascii(StrSubclass('abc')), "'abc'")
+        self.assertTypedEqual(object_ascii(WithRepr('<abc>')), '<abc>')
+        self.assertTypedEqual(object_ascii(WithRepr(StrSubclass('<abc>'))), StrSubclass('<abc>'))
+        self.assertTypedEqual(object_ascii(WithRepr('<\U0001f40d>')), r'<\U0001f40d>')
+        self.assertTypedEqual(object_ascii(WithRepr(StrSubclass('<\U0001f40d>'))), r'<\U0001f40d>')
+        self.assertTypedEqual(object_ascii(NULL), '<NULL>')
+
+    def test_object_bytes(self):
+        # Test PyObject_Bytes()
+        object_bytes = _testcapi.object_bytes
+        self.assertTypedEqual(object_bytes(b''), b'')
+        self.assertTypedEqual(object_bytes(b'abc'), b'abc')
+        self.assertTypedEqual(object_bytes(BytesSubclass(b'abc')), b'abc')
+        self.assertTypedEqual(object_bytes(WithBytes(b'abc')), b'abc')
+        self.assertTypedEqual(object_bytes(WithBytes(BytesSubclass(b'abc'))), BytesSubclass(b'abc'))
+        self.assertTypedEqual(object_bytes(bytearray(b'abc')), b'abc')
+        self.assertTypedEqual(object_bytes(memoryview(b'abc')), b'abc')
+        self.assertTypedEqual(object_bytes([97, 98, 99]), b'abc')
+        self.assertTypedEqual(object_bytes((97, 98, 99)), b'abc')
+        self.assertTypedEqual(object_bytes(iter([97, 98, 99])), b'abc')
+        self.assertRaises(TypeError, object_bytes, WithBytes(bytearray(b'abc')))
+        self.assertRaises(TypeError, object_bytes, WithBytes([97, 98, 99]))
+        self.assertRaises(TypeError, object_bytes, 3)
+        self.assertRaises(TypeError, object_bytes, 'abc')
+        self.assertRaises(TypeError, object_bytes, object())
+        self.assertTypedEqual(object_bytes(NULL), b'<NULL>')
 
     def test_object_getattr(self):
         xgetattr = _testcapi.object_getattr
index 4a9144e66f0fcd71c80aa40b6fb1abfa9b4b219a..a8ba009eb6a54bafa36f3202fedacf82e1a1108c 100644 (file)
@@ -2,6 +2,34 @@
 #include "util.h"
 
 
+static PyObject *
+object_repr(PyObject *self, PyObject *arg)
+{
+    NULLABLE(arg);
+    return PyObject_Repr(arg);
+}
+
+static PyObject *
+object_ascii(PyObject *self, PyObject *arg)
+{
+    NULLABLE(arg);
+    return PyObject_ASCII(arg);
+}
+
+static PyObject *
+object_str(PyObject *self, PyObject *arg)
+{
+    NULLABLE(arg);
+    return PyObject_Str(arg);
+}
+
+static PyObject *
+object_bytes(PyObject *self, PyObject *arg)
+{
+    NULLABLE(arg);
+    return PyObject_Bytes(arg);
+}
+
 static PyObject *
 object_getattr(PyObject *self, PyObject *args)
 {
@@ -616,6 +644,11 @@ sequence_tuple(PyObject *self, PyObject *obj)
 
 
 static PyMethodDef test_methods[] = {
+    {"object_repr", object_repr, METH_O},
+    {"object_ascii", object_ascii, METH_O},
+    {"object_str", object_str, METH_O},
+    {"object_bytes", object_bytes, METH_O},
+
     {"object_getattr", object_getattr, METH_VARARGS},
     {"object_getattrstring", object_getattrstring, METH_VARARGS},
     {"object_getoptionalattr", object_getoptionalattr, METH_VARARGS},