extern PyTypeObject* _PyType_CalculateMetaclass(PyTypeObject *, PyObject *);
extern PyObject* _PyType_GetDocFromInternalDoc(const char *, const char *);
-extern PyObject* _PyType_GetTextSignatureFromInternalDoc(const char *, const char *);
+extern PyObject* _PyType_GetTextSignatureFromInternalDoc(const char *, const char *, int);
extern int _PyObject_InitializeDict(PyObject *obj);
int _PyObject_InitInlineValues(PyObject *obj, PyTypeObject *tp);
import _pickle
import pickle
import shutil
+import stat
import sys
+import time
import types
import tempfile
import textwrap
import unittest.mock
import warnings
+
try:
from concurrent.futures import ThreadPoolExecutor
except ImportError:
yield
return 'spam'
+def meth_noargs(): pass
+def meth_o(object, /): pass
+def meth_self_noargs(self, /): pass
+def meth_self_o(self, object, /): pass
+def meth_type_noargs(type, /): pass
+def meth_type_o(type, object, /): pass
+
+
class TestPredicates(IsTestBase):
def test_excluding_predicates(self):
with self.assertRaises(TypeError):
inspect.getfullargspec(builtin)
+ cls = _testcapi.DocStringNoSignatureTest
+ obj = _testcapi.DocStringNoSignatureTest()
+ for builtin, template in [
+ (_testcapi.docstring_no_signature_noargs, meth_noargs),
+ (_testcapi.docstring_no_signature_o, meth_o),
+ (cls.meth_noargs, meth_self_noargs),
+ (cls.meth_o, meth_self_o),
+ (obj.meth_noargs, meth_self_noargs),
+ (obj.meth_o, meth_self_o),
+ (cls.meth_noargs_class, meth_type_noargs),
+ (cls.meth_o_class, meth_type_o),
+ (cls.meth_noargs_static, meth_noargs),
+ (cls.meth_o_static, meth_o),
+ (cls.meth_noargs_coexist, meth_self_noargs),
+ (cls.meth_o_coexist, meth_self_o),
+
+ (time.time, meth_noargs),
+ (stat.S_IMODE, meth_o),
+ (str.lower, meth_self_noargs),
+ (''.lower, meth_self_noargs),
+ (set.add, meth_self_o),
+ (set().add, meth_self_o),
+ (set.__contains__, meth_self_o),
+ (set().__contains__, meth_self_o),
+ (datetime.datetime.__dict__['utcnow'], meth_type_noargs),
+ (datetime.datetime.utcnow, meth_type_noargs),
+ (dict.__dict__['__class_getitem__'], meth_type_o),
+ (dict.__class_getitem__, meth_type_o),
+ ]:
+ with self.subTest(builtin):
+ self.assertEqual(inspect.getfullargspec(builtin),
+ inspect.getfullargspec(template))
+
def test_getfullargspec_definition_order_preserved_on_kwonly(self):
for fn in signatures_with_lexicographic_keyword_only_parameters():
signature = inspect.getfullargspec(fn)
'no signature found for builtin'):
inspect.signature(str)
+ cls = _testcapi.DocStringNoSignatureTest
+ obj = _testcapi.DocStringNoSignatureTest()
+ for builtin, template in [
+ (_testcapi.docstring_no_signature_noargs, meth_noargs),
+ (_testcapi.docstring_no_signature_o, meth_o),
+ (cls.meth_noargs, meth_self_noargs),
+ (cls.meth_o, meth_self_o),
+ (obj.meth_noargs, meth_noargs),
+ (obj.meth_o, meth_o),
+ (cls.meth_noargs_class, meth_noargs),
+ (cls.meth_o_class, meth_o),
+ (cls.meth_noargs_static, meth_noargs),
+ (cls.meth_o_static, meth_o),
+ (cls.meth_noargs_coexist, meth_self_noargs),
+ (cls.meth_o_coexist, meth_self_o),
+
+ (time.time, meth_noargs),
+ (stat.S_IMODE, meth_o),
+ (str.lower, meth_self_noargs),
+ (''.lower, meth_noargs),
+ (set.add, meth_self_o),
+ (set().add, meth_o),
+ (set.__contains__, meth_self_o),
+ (set().__contains__, meth_o),
+ (datetime.datetime.__dict__['utcnow'], meth_type_noargs),
+ (datetime.datetime.utcnow, meth_noargs),
+ (dict.__dict__['__class_getitem__'], meth_type_o),
+ (dict.__class_getitem__, meth_o),
+ ]:
+ with self.subTest(builtin):
+ self.assertEqual(inspect.signature(builtin),
+ inspect.signature(template))
+
def test_signature_on_non_function(self):
with self.assertRaisesRegex(TypeError, 'is not a callable object'):
inspect.signature(42)
+import datetime
import os
import sys
import contextlib
import stat
import tempfile
import test.support
+import time
import types
import typing
import unittest
self.assertEqual(self._get_summary_line(os.stat),
"stat(path, *, dir_fd=None, follow_symlinks=True)")
+ def test_module_level_callable_noargs(self):
+ self.assertEqual(self._get_summary_line(time.time),
+ "time()")
+
+ def test_module_level_callable_o(self):
+ self.assertEqual(self._get_summary_line(stat.S_IMODE),
+ "S_IMODE(object, /)")
+
+ def test_unbound_builtin_method_noargs(self):
+ self.assertEqual(self._get_summary_line(str.lower),
+ "lower(self, /)")
+
+ def test_bound_builtin_method_noargs(self):
+ self.assertEqual(self._get_summary_line(''.lower),
+ "lower() method of builtins.str instance")
+
+ def test_unbound_builtin_method_o(self):
+ self.assertEqual(self._get_summary_line(set.add),
+ "add(self, object, /)")
+
+ def test_bound_builtin_method_o(self):
+ self.assertEqual(self._get_summary_line(set().add),
+ "add(object, /) method of builtins.set instance")
+
+ def test_unbound_builtin_method_coexist_o(self):
+ self.assertEqual(self._get_summary_line(set.__contains__),
+ "__contains__(self, object, /)")
+
+ def test_bound_builtin_method_coexist_o(self):
+ self.assertEqual(self._get_summary_line(set().__contains__),
+ "__contains__(object, /) method of builtins.set instance")
+
+ def test_unbound_builtin_classmethod_noargs(self):
+ self.assertEqual(self._get_summary_line(datetime.datetime.__dict__['utcnow']),
+ "utcnow(type, /)")
+
+ def test_bound_builtin_classmethod_noargs(self):
+ self.assertEqual(self._get_summary_line(datetime.datetime.utcnow),
+ "utcnow() method of builtins.type instance")
+
+ def test_unbound_builtin_classmethod_o(self):
+ self.assertEqual(self._get_summary_line(dict.__dict__['__class_getitem__']),
+ "__class_getitem__(type, object, /)")
+
+ def test_bound_builtin_classmethod_o(self):
+ self.assertEqual(self._get_summary_line(dict.__class_getitem__),
+ "__class_getitem__(object, /) method of builtins.type instance")
+
@requires_docstrings
def test_staticmethod(self):
class X:
['str.{}('.format(x) for x in dir(str)
if x.startswith('s')])
self.assertEqual(self.stdcompleter.attr_matches('tuple.foospamegg'), [])
- expected = sorted({'None.%s%s' % (x, '(' if x != '__doc__' else '')
+ expected = sorted({'None.%s%s' % (x,
+ '()' if x == '__init_subclass__'
+ else '' if x == '__doc__'
+ else '(')
for x in dir(None)})
self.assertEqual(self.stdcompleter.attr_matches('None.'), expected)
self.assertEqual(self.stdcompleter.attr_matches('None._'), expected)
--- /dev/null
+Autogenerate signature for :c:macro:`METH_NOARGS` and :c:macro:`METH_O`
+extension functions.
static PyMethodDef test_methods[] = {
{"docstring_empty",
- (PyCFunction)test_with_docstring, METH_NOARGS,
+ (PyCFunction)test_with_docstring, METH_VARARGS,
docstring_empty},
{"docstring_no_signature",
+ (PyCFunction)test_with_docstring, METH_VARARGS,
+ docstring_no_signature},
+ {"docstring_no_signature_noargs",
(PyCFunction)test_with_docstring, METH_NOARGS,
docstring_no_signature},
+ {"docstring_no_signature_o",
+ (PyCFunction)test_with_docstring, METH_O,
+ docstring_no_signature},
{"docstring_with_invalid_signature",
- (PyCFunction)test_with_docstring, METH_NOARGS,
+ (PyCFunction)test_with_docstring, METH_VARARGS,
docstring_with_invalid_signature},
{"docstring_with_invalid_signature2",
- (PyCFunction)test_with_docstring, METH_NOARGS,
+ (PyCFunction)test_with_docstring, METH_VARARGS,
docstring_with_invalid_signature2},
{"docstring_with_signature",
- (PyCFunction)test_with_docstring, METH_NOARGS,
+ (PyCFunction)test_with_docstring, METH_VARARGS,
docstring_with_signature},
{"docstring_with_signature_and_extra_newlines",
- (PyCFunction)test_with_docstring, METH_NOARGS,
+ (PyCFunction)test_with_docstring, METH_VARARGS,
docstring_with_signature_and_extra_newlines},
{"docstring_with_signature_but_no_doc",
- (PyCFunction)test_with_docstring, METH_NOARGS,
+ (PyCFunction)test_with_docstring, METH_VARARGS,
docstring_with_signature_but_no_doc},
{"docstring_with_signature_with_defaults",
- (PyCFunction)test_with_docstring, METH_NOARGS,
+ (PyCFunction)test_with_docstring, METH_VARARGS,
docstring_with_signature_with_defaults},
{"no_docstring",
- (PyCFunction)test_with_docstring, METH_NOARGS},
+ (PyCFunction)test_with_docstring, METH_VARARGS},
{"test_with_docstring",
- test_with_docstring, METH_NOARGS,
+ test_with_docstring, METH_VARARGS,
PyDoc_STR("This is a pretty normal docstring.")},
{NULL},
};
+static PyMethodDef DocStringNoSignatureTest_methods[] = {
+ {"meth_noargs",
+ (PyCFunction)test_with_docstring, METH_NOARGS,
+ docstring_no_signature},
+ {"meth_o",
+ (PyCFunction)test_with_docstring, METH_O,
+ docstring_no_signature},
+ {"meth_noargs_class",
+ (PyCFunction)test_with_docstring, METH_NOARGS|METH_CLASS,
+ docstring_no_signature},
+ {"meth_o_class",
+ (PyCFunction)test_with_docstring, METH_O|METH_CLASS,
+ docstring_no_signature},
+ {"meth_noargs_static",
+ (PyCFunction)test_with_docstring, METH_NOARGS|METH_STATIC,
+ docstring_no_signature},
+ {"meth_o_static",
+ (PyCFunction)test_with_docstring, METH_O|METH_STATIC,
+ docstring_no_signature},
+ {"meth_noargs_coexist",
+ (PyCFunction)test_with_docstring, METH_NOARGS|METH_COEXIST,
+ docstring_no_signature},
+ {"meth_o_coexist",
+ (PyCFunction)test_with_docstring, METH_O|METH_COEXIST,
+ docstring_no_signature},
+ {NULL},
+};
+
+static PyTypeObject DocStringNoSignatureTest = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "_testcapi.DocStringNoSignatureTest",
+ .tp_basicsize = sizeof(PyObject),
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+ .tp_methods = DocStringNoSignatureTest_methods,
+ .tp_new = PyType_GenericNew,
+};
+
int
_PyTestCapi_Init_Docstring(PyObject *mod)
{
if (PyModule_AddFunctions(mod, test_methods) < 0) {
return -1;
}
+ if (PyModule_AddType(mod, &DocStringNoSignatureTest) < 0) {
+ return -1;
+ }
return 0;
}
static PyObject *
method_get_text_signature(PyMethodDescrObject *descr, void *closure)
{
- return _PyType_GetTextSignatureFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc);
+ return _PyType_GetTextSignatureFromInternalDoc(descr->d_method->ml_name,
+ descr->d_method->ml_doc,
+ descr->d_method->ml_flags);
}
static PyObject *
static PyObject *
wrapperdescr_get_text_signature(PyWrapperDescrObject *descr, void *closure)
{
- return _PyType_GetTextSignatureFromInternalDoc(descr->d_base->name, descr->d_base->doc);
+ return _PyType_GetTextSignatureFromInternalDoc(descr->d_base->name,
+ descr->d_base->doc, 0);
}
static PyGetSetDef wrapperdescr_getset[] = {
static PyObject *
wrapper_text_signature(wrapperobject *wp, void *Py_UNUSED(ignored))
{
- return _PyType_GetTextSignatureFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc);
+ return _PyType_GetTextSignatureFromInternalDoc(wp->descr->d_base->name,
+ wp->descr->d_base->doc, 0);
}
static PyObject *
static PyObject *
meth_get__text_signature__(PyCFunctionObject *m, void *closure)
{
- return _PyType_GetTextSignatureFromInternalDoc(m->m_ml->ml_name, m->m_ml->ml_doc);
+ return _PyType_GetTextSignatureFromInternalDoc(m->m_ml->ml_name,
+ m->m_ml->ml_doc,
+ m->m_ml->ml_flags);
}
static PyObject *
return PyUnicode_FromString(doc);
}
+static const char *
+signature_from_flags(int flags)
+{
+ switch (flags & ~METH_COEXIST) {
+ case METH_NOARGS:
+ return "($self, /)";
+ case METH_NOARGS|METH_CLASS:
+ return "($type, /)";
+ case METH_NOARGS|METH_STATIC:
+ return "()";
+ case METH_O:
+ return "($self, object, /)";
+ case METH_O|METH_CLASS:
+ return "($type, object, /)";
+ case METH_O|METH_STATIC:
+ return "(object, /)";
+ default:
+ return NULL;
+ }
+}
+
PyObject *
-_PyType_GetTextSignatureFromInternalDoc(const char *name, const char *internal_doc)
+_PyType_GetTextSignatureFromInternalDoc(const char *name, const char *internal_doc, int flags)
{
const char *start = find_signature(name, internal_doc);
const char *end;
else
end = NULL;
if (!end) {
+ start = signature_from_flags(flags);
+ if (start) {
+ return PyUnicode_FromString(start);
+ }
Py_RETURN_NONE;
}
static PyObject *
type_get_text_signature(PyTypeObject *type, void *context)
{
- return _PyType_GetTextSignatureFromInternalDoc(type->tp_name, type->tp_doc);
+ return _PyType_GetTextSignatureFromInternalDoc(type->tp_name, type->tp_doc, 0);
}
static int
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/exceptions.c - PyRecursingInfinitelyError_Type -
Modules/_testcapi/heaptype.c - _testcapimodule -
Modules/_testcapi/mem.c - FmData -