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-107782: Use _testcapi to test non-representable signatures #109325

Merged
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 37 additions & 2 deletions Lib/test/test_pydoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from io import StringIO
from collections import namedtuple
from urllib.request import urlopen, urlcleanup
from test import support
from test.support import import_helper
from test.support import os_helper
from test.support.script_helper import (assert_python_ok,
Expand Down Expand Up @@ -1236,22 +1237,56 @@ def test_bound_builtin_classmethod_o(self):
self.assertEqual(self._get_summary_line(dict.__class_getitem__),
"__class_getitem__(object, /) method of builtins.type instance")

@support.cpython_only
def test_module_level_callable_unrepresentable_default(self):
self.assertEqual(self._get_summary_line(getattr),
"getattr(...)")
import _testcapi
builtin = _testcapi.func_with_unrepresentable_signature
self.assertEqual(self._get_summary_line(builtin),
"func_with_unrepresentable_signature(a, b=<x>)")

@support.cpython_only
def test_builtin_staticmethod_unrepresentable_default(self):
self.assertEqual(self._get_summary_line(str.maketrans),
"maketrans(x, y=<unrepresentable>, z=<unrepresentable>, /)")
import _testcapi
cls = _testcapi.DocStringUnrepresentableSignatureTest
self.assertEqual(self._get_summary_line(cls.staticmeth),
"staticmeth(a, b=<x>)")

@support.cpython_only
def test_unbound_builtin_method_unrepresentable_default(self):
self.assertEqual(self._get_summary_line(dict.pop),
"pop(self, key, default=<unrepresentable>, /)")
import _testcapi
cls = _testcapi.DocStringUnrepresentableSignatureTest
self.assertEqual(self._get_summary_line(cls.meth),
"meth(self, /, a, b=<x>)")

@support.cpython_only
def test_bound_builtin_method_unrepresentable_default(self):
self.assertEqual(self._get_summary_line({}.pop),
"pop(key, default=<unrepresentable>, /) "
"method of builtins.dict instance")
import _testcapi
obj = _testcapi.DocStringUnrepresentableSignatureTest()
self.assertEqual(self._get_summary_line(obj.meth),
"meth(a, b=<x>) "
"method of _testcapi.DocStringUnrepresentableSignatureTest instance")

@support.cpython_only
def test_unbound_builtin_classmethod_unrepresentable_default(self):
import _testcapi
cls = _testcapi.DocStringUnrepresentableSignatureTest
descr = cls.__dict__['classmeth']
self.assertEqual(self._get_summary_line(descr),
"classmeth(type, /, a, b=<x>)")

@support.cpython_only
def test_bound_builtin_classmethod_unrepresentable_default(self):
import _testcapi
cls = _testcapi.DocStringUnrepresentableSignatureTest
self.assertEqual(self._get_summary_line(cls.classmeth),
"classmeth(a, b=<x>) method of builtins.type instance")

def test_overridden_text_signature(self):
class C:
Expand Down
44 changes: 44 additions & 0 deletions Modules/_testcapi/docstring.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,13 @@ static PyMethodDef test_methods[] = {
{"test_with_docstring",
test_with_docstring, METH_VARARGS,
PyDoc_STR("This is a pretty normal docstring.")},
{"func_with_unrepresentable_signature",
(PyCFunction)test_with_docstring, METH_VARARGS,
PyDoc_STR(
"func_with_unrepresentable_signature($module, /, a, b=<x>)\n"
"--\n\n"
"This docstring has a signature with unrepresentable default."
)},
{NULL},
};

Expand Down Expand Up @@ -140,6 +147,40 @@ static PyTypeObject DocStringNoSignatureTest = {
.tp_new = PyType_GenericNew,
};

static PyMethodDef DocStringUnrepresentableSignatureTest_methods[] = {
{"meth",
(PyCFunction)test_with_docstring, METH_VARARGS,
PyDoc_STR(
"meth($self, /, a, b=<x>)\n"
"--\n\n"
"This docstring has a signature with unrepresentable default."
)},
{"classmeth",
(PyCFunction)test_with_docstring, METH_VARARGS|METH_CLASS,
PyDoc_STR(
"classmeth($type, /, a, b=<x>)\n"
"--\n\n"
"This docstring has a signature with unrepresentable default."
)},
{"staticmeth",
(PyCFunction)test_with_docstring, METH_VARARGS|METH_STATIC,
PyDoc_STR(
"staticmeth(a, b=<x>)\n"
"--\n\n"
"This docstring has a signature with unrepresentable default."
)},
{NULL},
};

static PyTypeObject DocStringUnrepresentableSignatureTest = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "_testcapi.DocStringUnrepresentableSignatureTest",
.tp_basicsize = sizeof(PyObject),
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_methods = DocStringUnrepresentableSignatureTest_methods,
.tp_new = PyType_GenericNew,
};

int
_PyTestCapi_Init_Docstring(PyObject *mod)
{
Expand All @@ -149,5 +190,8 @@ _PyTestCapi_Init_Docstring(PyObject *mod)
if (PyModule_AddType(mod, &DocStringNoSignatureTest) < 0) {
return -1;
}
if (PyModule_AddType(mod, &DocStringUnrepresentableSignatureTest) < 0) {
return -1;
}
return 0;
}
1 change: 1 addition & 0 deletions Tools/c-analyzer/cpython/ignored.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,7 @@ Modules/_testcapi/buffer.c - testBufType -
Modules/_testcapi/code.c get_code_extra_index key -
Modules/_testcapi/datetime.c - test_run_counter -
Modules/_testcapi/docstring.c - DocStringNoSignatureTest -
Modules/_testcapi/docstring.c - DocStringUnrepresentableSignatureTest -
Modules/_testcapi/exceptions.c - PyRecursingInfinitelyError_Type -
Modules/_testcapi/heaptype.c - _testcapimodule -
Modules/_testcapi/mem.c - FmData -
Expand Down
Loading