Issue #19674: inspect.signature() now produces a correct signature
for some builtins.
This commit is contained in:
parent
7fa6e1aeea
commit
44e2eaab54
|
@ -31,6 +31,7 @@ Here are some of the useful functions provided by this module:
|
||||||
__author__ = ('Ka-Ping Yee <ping@lfw.org>',
|
__author__ = ('Ka-Ping Yee <ping@lfw.org>',
|
||||||
'Yury Selivanov <yselivanov@sprymix.com>')
|
'Yury Selivanov <yselivanov@sprymix.com>')
|
||||||
|
|
||||||
|
import ast
|
||||||
import importlib.machinery
|
import importlib.machinery
|
||||||
import itertools
|
import itertools
|
||||||
import linecache
|
import linecache
|
||||||
|
@ -1461,6 +1462,9 @@ def signature(obj):
|
||||||
if isinstance(obj, types.FunctionType):
|
if isinstance(obj, types.FunctionType):
|
||||||
return Signature.from_function(obj)
|
return Signature.from_function(obj)
|
||||||
|
|
||||||
|
if isinstance(obj, types.BuiltinFunctionType):
|
||||||
|
return Signature.from_builtin(obj)
|
||||||
|
|
||||||
if isinstance(obj, functools.partial):
|
if isinstance(obj, functools.partial):
|
||||||
sig = signature(obj.func)
|
sig = signature(obj.func)
|
||||||
|
|
||||||
|
@ -1942,6 +1946,64 @@ class Signature:
|
||||||
return_annotation=annotations.get('return', _empty),
|
return_annotation=annotations.get('return', _empty),
|
||||||
__validate_parameters__=False)
|
__validate_parameters__=False)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_builtin(cls, func):
|
||||||
|
s = getattr(func, "__text_signature__", None)
|
||||||
|
if not s:
|
||||||
|
return None
|
||||||
|
|
||||||
|
if s.endswith("/)"):
|
||||||
|
kind = Parameter.POSITIONAL_ONLY
|
||||||
|
s = s[:-2] + ')'
|
||||||
|
else:
|
||||||
|
kind = Parameter.POSITIONAL_OR_KEYWORD
|
||||||
|
|
||||||
|
s = "def foo" + s + ": pass"
|
||||||
|
|
||||||
|
try:
|
||||||
|
module = ast.parse(s)
|
||||||
|
except SyntaxError:
|
||||||
|
return None
|
||||||
|
if not isinstance(module, ast.Module):
|
||||||
|
return None
|
||||||
|
|
||||||
|
# ast.FunctionDef
|
||||||
|
f = module.body[0]
|
||||||
|
|
||||||
|
parameters = []
|
||||||
|
empty = Parameter.empty
|
||||||
|
|
||||||
|
def p(name_node, default_node, default=empty):
|
||||||
|
name = name_node.arg
|
||||||
|
|
||||||
|
if isinstance(default_node, ast.Num):
|
||||||
|
default = default.n
|
||||||
|
elif isinstance(default_node, ast.NameConstant):
|
||||||
|
default = default_node.value
|
||||||
|
parameters.append(Parameter(name, kind, default=default, annotation=empty))
|
||||||
|
|
||||||
|
# non-keyword-only parameters
|
||||||
|
for name, default in reversed(list(itertools.zip_longest(reversed(f.args.args), reversed(f.args.defaults), fillvalue=None))):
|
||||||
|
p(name, default)
|
||||||
|
|
||||||
|
# *args
|
||||||
|
if f.args.vararg:
|
||||||
|
kind = Parameter.VAR_POSITIONAL
|
||||||
|
p(f.args.vararg, empty)
|
||||||
|
|
||||||
|
# keyword-only arguments
|
||||||
|
kind = Parameter.KEYWORD_ONLY
|
||||||
|
for name, default in zip(f.args.kwonlyargs, f.args.kw_defaults):
|
||||||
|
p(name, default)
|
||||||
|
|
||||||
|
# **kwargs
|
||||||
|
if f.args.kwarg:
|
||||||
|
kind = Parameter.VAR_KEYWORD
|
||||||
|
p(f.args.kwarg, empty)
|
||||||
|
|
||||||
|
return cls(parameters, return_annotation=cls.empty)
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def parameters(self):
|
def parameters(self):
|
||||||
return self._parameters
|
return self._parameters
|
||||||
|
|
28
Lib/pydoc.py
28
Lib/pydoc.py
|
@ -916,20 +916,18 @@ class HTMLDoc(Doc):
|
||||||
reallink = realname
|
reallink = realname
|
||||||
title = '<a name="%s"><strong>%s</strong></a> = %s' % (
|
title = '<a name="%s"><strong>%s</strong></a> = %s' % (
|
||||||
anchor, name, reallink)
|
anchor, name, reallink)
|
||||||
if inspect.isfunction(object):
|
argspec = None
|
||||||
args, varargs, kwonlyargs, kwdefaults, varkw, defaults, ann = \
|
if inspect.isfunction(object) or inspect.isbuiltin(object):
|
||||||
inspect.getfullargspec(object)
|
signature = inspect.signature(object)
|
||||||
argspec = inspect.formatargspec(
|
if signature:
|
||||||
args, varargs, kwonlyargs, kwdefaults, varkw, defaults, ann,
|
argspec = str(signature)
|
||||||
formatvalue=self.formatvalue,
|
|
||||||
formatannotation=inspect.formatannotationrelativeto(object))
|
|
||||||
if realname == '<lambda>':
|
if realname == '<lambda>':
|
||||||
title = '<strong>%s</strong> <em>lambda</em> ' % name
|
title = '<strong>%s</strong> <em>lambda</em> ' % name
|
||||||
# XXX lambda's won't usually have func_annotations['return']
|
# XXX lambda's won't usually have func_annotations['return']
|
||||||
# since the syntax doesn't support but it is possible.
|
# since the syntax doesn't support but it is possible.
|
||||||
# So removing parentheses isn't truly safe.
|
# So removing parentheses isn't truly safe.
|
||||||
argspec = argspec[1:-1] # remove parentheses
|
argspec = argspec[1:-1] # remove parentheses
|
||||||
else:
|
if not argspec:
|
||||||
argspec = '(...)'
|
argspec = '(...)'
|
||||||
|
|
||||||
decl = title + argspec + (note and self.grey(
|
decl = title + argspec + (note and self.grey(
|
||||||
|
@ -1313,20 +1311,18 @@ location listed above.
|
||||||
cl.__dict__[realname] is object):
|
cl.__dict__[realname] is object):
|
||||||
skipdocs = 1
|
skipdocs = 1
|
||||||
title = self.bold(name) + ' = ' + realname
|
title = self.bold(name) + ' = ' + realname
|
||||||
if inspect.isfunction(object):
|
argspec = None
|
||||||
args, varargs, varkw, defaults, kwonlyargs, kwdefaults, ann = \
|
if inspect.isfunction(object) or inspect.isbuiltin(object):
|
||||||
inspect.getfullargspec(object)
|
signature = inspect.signature(object)
|
||||||
argspec = inspect.formatargspec(
|
if signature:
|
||||||
args, varargs, varkw, defaults, kwonlyargs, kwdefaults, ann,
|
argspec = str(signature)
|
||||||
formatvalue=self.formatvalue,
|
|
||||||
formatannotation=inspect.formatannotationrelativeto(object))
|
|
||||||
if realname == '<lambda>':
|
if realname == '<lambda>':
|
||||||
title = self.bold(name) + ' lambda '
|
title = self.bold(name) + ' lambda '
|
||||||
# XXX lambda's won't usually have func_annotations['return']
|
# XXX lambda's won't usually have func_annotations['return']
|
||||||
# since the syntax doesn't support but it is possible.
|
# since the syntax doesn't support but it is possible.
|
||||||
# So removing parentheses isn't truly safe.
|
# So removing parentheses isn't truly safe.
|
||||||
argspec = argspec[1:-1] # remove parentheses
|
argspec = argspec[1:-1] # remove parentheses
|
||||||
else:
|
if not argspec:
|
||||||
argspec = '(...)'
|
argspec = '(...)'
|
||||||
decl = title + argspec + note
|
decl = title + argspec + note
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,35 @@ class CAPITest(unittest.TestCase):
|
||||||
self.assertRaises(TypeError, _posixsubprocess.fork_exec,
|
self.assertRaises(TypeError, _posixsubprocess.fork_exec,
|
||||||
Z(),[b'1'],3,[1, 2],5,6,7,8,9,10,11,12,13,14,15,16,17)
|
Z(),[b'1'],3,[1, 2],5,6,7,8,9,10,11,12,13,14,15,16,17)
|
||||||
|
|
||||||
|
def test_docstring_signature_parsing(self):
|
||||||
|
|
||||||
|
self.assertEqual(_testcapi.no_docstring.__doc__, None)
|
||||||
|
self.assertEqual(_testcapi.no_docstring.__text_signature__, None)
|
||||||
|
|
||||||
|
self.assertEqual(_testcapi.docstring_empty.__doc__, "")
|
||||||
|
self.assertEqual(_testcapi.docstring_empty.__text_signature__, None)
|
||||||
|
|
||||||
|
self.assertEqual(_testcapi.docstring_no_signature.__doc__,
|
||||||
|
"This docstring has no signature.")
|
||||||
|
self.assertEqual(_testcapi.docstring_no_signature.__text_signature__, None)
|
||||||
|
|
||||||
|
self.assertEqual(_testcapi.docstring_with_invalid_signature.__doc__,
|
||||||
|
"docstring_with_invalid_signature (boo)\n"
|
||||||
|
"\n"
|
||||||
|
"This docstring has an invalid signature."
|
||||||
|
)
|
||||||
|
self.assertEqual(_testcapi.docstring_with_invalid_signature.__text_signature__, None)
|
||||||
|
|
||||||
|
self.assertEqual(_testcapi.docstring_with_signature.__doc__,
|
||||||
|
"This docstring has a valid signature.")
|
||||||
|
self.assertEqual(_testcapi.docstring_with_signature.__text_signature__, "(sig)")
|
||||||
|
|
||||||
|
self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__doc__,
|
||||||
|
"This docstring has a valid signature and some extra newlines.")
|
||||||
|
self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__text_signature__,
|
||||||
|
"(parameter)")
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
@unittest.skipUnless(threading, 'Threading required for this test.')
|
||||||
class TestPendingCalls(unittest.TestCase):
|
class TestPendingCalls(unittest.TestCase):
|
||||||
|
|
||||||
|
|
|
@ -1588,10 +1588,9 @@ class TestSignatureObject(unittest.TestCase):
|
||||||
with self.assertRaisesRegex(ValueError, 'not supported by signature'):
|
with self.assertRaisesRegex(ValueError, 'not supported by signature'):
|
||||||
# support for 'method-wrapper'
|
# support for 'method-wrapper'
|
||||||
inspect.signature(min.__call__)
|
inspect.signature(min.__call__)
|
||||||
with self.assertRaisesRegex(ValueError,
|
self.assertEqual(inspect.signature(min), None)
|
||||||
'no signature found for builtin function'):
|
signature = inspect.signature(os.stat)
|
||||||
# support for 'method-wrapper'
|
self.assertTrue(isinstance(signature, inspect.Signature))
|
||||||
inspect.signature(min)
|
|
||||||
|
|
||||||
def test_signature_on_non_function(self):
|
def test_signature_on_non_function(self):
|
||||||
with self.assertRaisesRegex(TypeError, 'is not a callable object'):
|
with self.assertRaisesRegex(TypeError, 'is not a callable object'):
|
||||||
|
|
|
@ -68,6 +68,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #19674: inspect.signature() now produces a correct signature
|
||||||
|
for some builtins.
|
||||||
|
|
||||||
- Issue #19722: Added opcode.stack_effect(), which
|
- Issue #19722: Added opcode.stack_effect(), which
|
||||||
computes the stack effect of bytecode instructions.
|
computes the stack effect of bytecode instructions.
|
||||||
|
|
||||||
|
|
|
@ -134,6 +134,12 @@ typedef chtype attr_t; /* No attr_t type is available */
|
||||||
#define STRICT_SYSV_CURSES
|
#define STRICT_SYSV_CURSES
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*[clinic]
|
||||||
|
module curses
|
||||||
|
class curses.window
|
||||||
|
[clinic]*/
|
||||||
|
/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
|
||||||
|
|
||||||
/* Definition of exception curses.error */
|
/* Definition of exception curses.error */
|
||||||
|
|
||||||
static PyObject *PyCursesError;
|
static PyObject *PyCursesError;
|
||||||
|
@ -550,8 +556,6 @@ PyCursesWindow_Dealloc(PyCursesWindowObject *wo)
|
||||||
/* Addch, Addstr, Addnstr */
|
/* Addch, Addstr, Addnstr */
|
||||||
|
|
||||||
/*[clinic]
|
/*[clinic]
|
||||||
module curses
|
|
||||||
class curses.window
|
|
||||||
|
|
||||||
curses.window.addch
|
curses.window.addch
|
||||||
|
|
||||||
|
@ -580,9 +584,9 @@ current settings for the window object.
|
||||||
[clinic]*/
|
[clinic]*/
|
||||||
|
|
||||||
PyDoc_STRVAR(curses_window_addch__doc__,
|
PyDoc_STRVAR(curses_window_addch__doc__,
|
||||||
|
"addch([x, y,] ch, [attr])\n"
|
||||||
"Paint character ch at (y, x) with attributes attr.\n"
|
"Paint character ch at (y, x) with attributes attr.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"curses.window.addch([x, y,] ch, [attr])\n"
|
|
||||||
" x\n"
|
" x\n"
|
||||||
" X-coordinate.\n"
|
" X-coordinate.\n"
|
||||||
" y\n"
|
" y\n"
|
||||||
|
@ -646,7 +650,7 @@ curses_window_addch(PyObject *self, PyObject *args)
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
curses_window_addch_impl(PyObject *self, int group_left_1, int x, int y, PyObject *ch, int group_right_1, long attr)
|
curses_window_addch_impl(PyObject *self, int group_left_1, int x, int y, PyObject *ch, int group_right_1, long attr)
|
||||||
/*[clinic checksum: 094d012af1019387c0219a9c0bc76e90729c833f]*/
|
/*[clinic checksum: 44ed958b891cde91205e584c766e048f3999714f]*/
|
||||||
{
|
{
|
||||||
PyCursesWindowObject *cwself = (PyCursesWindowObject *)self;
|
PyCursesWindowObject *cwself = (PyCursesWindowObject *)self;
|
||||||
int coordinates_group = group_left_1;
|
int coordinates_group = group_left_1;
|
||||||
|
|
|
@ -16,6 +16,12 @@
|
||||||
#include "datetime.h"
|
#include "datetime.h"
|
||||||
#undef Py_BUILD_CORE
|
#undef Py_BUILD_CORE
|
||||||
|
|
||||||
|
/*[clinic]
|
||||||
|
module datetime
|
||||||
|
class datetime.datetime
|
||||||
|
[clinic]*/
|
||||||
|
/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
|
||||||
|
|
||||||
/* We require that C int be at least 32 bits, and use int virtually
|
/* We require that C int be at least 32 bits, and use int virtually
|
||||||
* everywhere. In just a few cases we use a temp long, where a Python
|
* everywhere. In just a few cases we use a temp long, where a Python
|
||||||
* API returns a C long. In such cases, we have to ensure that the
|
* API returns a C long. In such cases, we have to ensure that the
|
||||||
|
@ -4140,8 +4146,6 @@ datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*[clinic]
|
/*[clinic]
|
||||||
module datetime
|
|
||||||
class datetime.datetime
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
datetime.datetime.now
|
datetime.datetime.now
|
||||||
|
@ -4155,9 +4159,9 @@ If no tz is specified, uses local timezone.
|
||||||
[clinic]*/
|
[clinic]*/
|
||||||
|
|
||||||
PyDoc_STRVAR(datetime_datetime_now__doc__,
|
PyDoc_STRVAR(datetime_datetime_now__doc__,
|
||||||
|
"now(tz=None)\n"
|
||||||
"Returns new datetime object representing current time local to tz.\n"
|
"Returns new datetime object representing current time local to tz.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"datetime.datetime.now(tz=None)\n"
|
|
||||||
" tz\n"
|
" tz\n"
|
||||||
" Timezone object.\n"
|
" Timezone object.\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -4188,7 +4192,7 @@ exit:
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
datetime_datetime_now_impl(PyTypeObject *cls, PyObject *tz)
|
datetime_datetime_now_impl(PyTypeObject *cls, PyObject *tz)
|
||||||
/*[clinic checksum: 5e61647d5d1feaf1ab096c5406ccea17bb7b061c]*/
|
/*[clinic checksum: ca3d26a423b3f633b260c7622e303f0915a96f7c]*/
|
||||||
{
|
{
|
||||||
PyObject *self;
|
PyObject *self;
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,12 @@ static char *which_dbm = "Berkeley DB";
|
||||||
#error "No ndbm.h available!"
|
#error "No ndbm.h available!"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*[clinic]
|
||||||
|
module dbm
|
||||||
|
class dbm.dbm
|
||||||
|
[clinic]*/
|
||||||
|
/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
int di_size; /* -1 means recompute */
|
int di_size; /* -1 means recompute */
|
||||||
|
@ -43,12 +49,6 @@ static PyTypeObject Dbmtype;
|
||||||
|
|
||||||
static PyObject *DbmError;
|
static PyObject *DbmError;
|
||||||
|
|
||||||
/*[clinic]
|
|
||||||
module dbm
|
|
||||||
class dbm.dbm
|
|
||||||
[clinic]*/
|
|
||||||
/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
|
|
||||||
|
|
||||||
/*[python]
|
/*[python]
|
||||||
class dbmobject_converter(self_converter):
|
class dbmobject_converter(self_converter):
|
||||||
type = "dbmobject *"
|
type = "dbmobject *"
|
||||||
|
@ -278,9 +278,8 @@ Return the value for key if present, otherwise default.
|
||||||
[clinic]*/
|
[clinic]*/
|
||||||
|
|
||||||
PyDoc_STRVAR(dbm_dbm_get__doc__,
|
PyDoc_STRVAR(dbm_dbm_get__doc__,
|
||||||
"Return the value for key if present, otherwise default.\n"
|
"get(key, [default])\n"
|
||||||
"\n"
|
"Return the value for key if present, otherwise default.");
|
||||||
"dbm.dbm.get(key, [default])");
|
|
||||||
|
|
||||||
#define DBM_DBM_GET_METHODDEF \
|
#define DBM_DBM_GET_METHODDEF \
|
||||||
{"get", (PyCFunction)dbm_dbm_get, METH_VARARGS, dbm_dbm_get__doc__},
|
{"get", (PyCFunction)dbm_dbm_get, METH_VARARGS, dbm_dbm_get__doc__},
|
||||||
|
@ -318,7 +317,7 @@ dbm_dbm_get(PyObject *self, PyObject *args)
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
dbm_dbm_get_impl(dbmobject *dp, const char *key, Py_ssize_clean_t key_length, int group_right_1, PyObject *default_value)
|
dbm_dbm_get_impl(dbmobject *dp, const char *key, Py_ssize_clean_t key_length, int group_right_1, PyObject *default_value)
|
||||||
/*[clinic checksum: 5b4265e66568f163ef0fc7efec09410eaf793508]*/
|
/*[clinic checksum: 28cf8928811bde51e535d67ae98ea039d79df717]*/
|
||||||
{
|
{
|
||||||
datum dbm_key, val;
|
datum dbm_key, val;
|
||||||
|
|
||||||
|
@ -461,9 +460,9 @@ Return a database object.
|
||||||
[clinic]*/
|
[clinic]*/
|
||||||
|
|
||||||
PyDoc_STRVAR(dbmopen__doc__,
|
PyDoc_STRVAR(dbmopen__doc__,
|
||||||
|
"open(filename, flags=\'r\', mode=0o666)\n"
|
||||||
"Return a database object.\n"
|
"Return a database object.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"dbm.open(filename, flags=\'r\', mode=0o666)\n"
|
|
||||||
" filename\n"
|
" filename\n"
|
||||||
" The filename to open.\n"
|
" The filename to open.\n"
|
||||||
" flags\n"
|
" flags\n"
|
||||||
|
@ -498,7 +497,7 @@ exit:
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
dbmopen_impl(PyModuleDef *module, const char *filename, const char *flags, int mode)
|
dbmopen_impl(PyModuleDef *module, const char *filename, const char *flags, int mode)
|
||||||
/*[clinic checksum: c1f2036017ec36a43ac6f59893732751e67c19d5]*/
|
/*[clinic checksum: fb265f75641553ccd963f84c143b35c11f9121fc]*/
|
||||||
{
|
{
|
||||||
int iflags;
|
int iflags;
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "opcode.h"
|
#include "opcode.h"
|
||||||
|
|
||||||
|
/*[clinic]
|
||||||
|
module _opcode
|
||||||
|
[clinic]*/
|
||||||
|
/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
|
||||||
|
|
||||||
/*[clinic]
|
/*[clinic]
|
||||||
|
|
||||||
module _opcode
|
|
||||||
|
|
||||||
_opcode.stack_effect -> int
|
_opcode.stack_effect -> int
|
||||||
|
|
||||||
opcode: int
|
opcode: int
|
||||||
|
@ -19,18 +21,17 @@ Compute the stack effect of the opcode.
|
||||||
[clinic]*/
|
[clinic]*/
|
||||||
|
|
||||||
PyDoc_STRVAR(_opcode_stack_effect__doc__,
|
PyDoc_STRVAR(_opcode_stack_effect__doc__,
|
||||||
"Compute the stack effect of the opcode.\n"
|
"stack_effect(opcode, [oparg])\n"
|
||||||
"\n"
|
"Compute the stack effect of the opcode.");
|
||||||
"_opcode.stack_effect(opcode, [oparg])");
|
|
||||||
|
|
||||||
#define _OPCODE_STACK_EFFECT_METHODDEF \
|
#define _OPCODE_STACK_EFFECT_METHODDEF \
|
||||||
{"stack_effect", (PyCFunction)_opcode_stack_effect, METH_VARARGS, _opcode_stack_effect__doc__},
|
{"stack_effect", (PyCFunction)_opcode_stack_effect, METH_VARARGS, _opcode_stack_effect__doc__},
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_opcode_stack_effect_impl(PyObject *module, int opcode, int group_right_1, int oparg);
|
_opcode_stack_effect_impl(PyModuleDef *module, int opcode, int group_right_1, int oparg);
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_opcode_stack_effect(PyObject *module, PyObject *args)
|
_opcode_stack_effect(PyModuleDef *module, PyObject *args)
|
||||||
{
|
{
|
||||||
PyObject *return_value = NULL;
|
PyObject *return_value = NULL;
|
||||||
int opcode;
|
int opcode;
|
||||||
|
@ -62,8 +63,8 @@ exit:
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_opcode_stack_effect_impl(PyObject *module, int opcode, int group_right_1, int oparg)
|
_opcode_stack_effect_impl(PyModuleDef *module, int opcode, int group_right_1, int oparg)
|
||||||
/*[clinic checksum: 2312ded40abc9bcbce718942de21f53e61a2dfd3]*/
|
/*[clinic checksum: e880e62dc7b0de73403026eaf4f8074aa106358b]*/
|
||||||
{
|
{
|
||||||
int effect;
|
int effect;
|
||||||
if (HAS_ARG(opcode)) {
|
if (HAS_ARG(opcode)) {
|
||||||
|
|
|
@ -2842,6 +2842,33 @@ test_pyobject_setallocators(PyObject *self)
|
||||||
return test_setallocators(PYMEM_DOMAIN_OBJ);
|
return test_setallocators(PYMEM_DOMAIN_OBJ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(docstring_empty,
|
||||||
|
""
|
||||||
|
);
|
||||||
|
|
||||||
|
PyDoc_STRVAR(docstring_no_signature,
|
||||||
|
"This docstring has no signature."
|
||||||
|
);
|
||||||
|
|
||||||
|
PyDoc_STRVAR(docstring_with_invalid_signature,
|
||||||
|
"docstring_with_invalid_signature (boo)\n"
|
||||||
|
"\n"
|
||||||
|
"This docstring has an invalid signature."
|
||||||
|
);
|
||||||
|
|
||||||
|
PyDoc_STRVAR(docstring_with_signature,
|
||||||
|
"docstring_with_signature(sig)\n"
|
||||||
|
"This docstring has a valid signature."
|
||||||
|
);
|
||||||
|
|
||||||
|
PyDoc_STRVAR(docstring_with_signature_and_extra_newlines,
|
||||||
|
"docstring_with_signature_and_extra_newlines(parameter)\n"
|
||||||
|
"\n"
|
||||||
|
"\n"
|
||||||
|
"\n"
|
||||||
|
"This docstring has a valid signature and some extra newlines."
|
||||||
|
);
|
||||||
|
|
||||||
static PyMethodDef TestMethods[] = {
|
static PyMethodDef TestMethods[] = {
|
||||||
{"raise_exception", raise_exception, METH_VARARGS},
|
{"raise_exception", raise_exception, METH_VARARGS},
|
||||||
{"raise_memoryerror", (PyCFunction)raise_memoryerror, METH_NOARGS},
|
{"raise_memoryerror", (PyCFunction)raise_memoryerror, METH_NOARGS},
|
||||||
|
@ -2953,6 +2980,23 @@ static PyMethodDef TestMethods[] = {
|
||||||
(PyCFunction)test_pymem_setallocators, METH_NOARGS},
|
(PyCFunction)test_pymem_setallocators, METH_NOARGS},
|
||||||
{"test_pyobject_setallocators",
|
{"test_pyobject_setallocators",
|
||||||
(PyCFunction)test_pyobject_setallocators, METH_NOARGS},
|
(PyCFunction)test_pyobject_setallocators, METH_NOARGS},
|
||||||
|
{"no_docstring",
|
||||||
|
(PyCFunction)test_with_docstring, METH_NOARGS},
|
||||||
|
{"docstring_empty",
|
||||||
|
(PyCFunction)test_with_docstring, METH_NOARGS,
|
||||||
|
docstring_empty},
|
||||||
|
{"docstring_no_signature",
|
||||||
|
(PyCFunction)test_with_docstring, METH_NOARGS,
|
||||||
|
docstring_no_signature},
|
||||||
|
{"docstring_with_invalid_signature",
|
||||||
|
(PyCFunction)test_with_docstring, METH_NOARGS,
|
||||||
|
docstring_with_invalid_signature},
|
||||||
|
{"docstring_with_signature",
|
||||||
|
(PyCFunction)test_with_docstring, METH_NOARGS,
|
||||||
|
docstring_with_signature},
|
||||||
|
{"docstring_with_signature_and_extra_newlines",
|
||||||
|
(PyCFunction)test_with_docstring, METH_NOARGS,
|
||||||
|
docstring_with_signature_and_extra_newlines},
|
||||||
{NULL, NULL} /* sentinel */
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,11 @@
|
||||||
((PyWeakReference **) PyObject_GET_WEAKREFS_LISTPTR(o))
|
((PyWeakReference **) PyObject_GET_WEAKREFS_LISTPTR(o))
|
||||||
|
|
||||||
/*[clinic]
|
/*[clinic]
|
||||||
|
|
||||||
module _weakref
|
module _weakref
|
||||||
|
[clinic]*/
|
||||||
|
/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
|
||||||
|
|
||||||
|
/*[clinic]
|
||||||
|
|
||||||
_weakref.getweakrefcount -> Py_ssize_t
|
_weakref.getweakrefcount -> Py_ssize_t
|
||||||
|
|
||||||
|
@ -17,9 +20,8 @@ Return the number of weak references to 'object'.
|
||||||
[clinic]*/
|
[clinic]*/
|
||||||
|
|
||||||
PyDoc_STRVAR(_weakref_getweakrefcount__doc__,
|
PyDoc_STRVAR(_weakref_getweakrefcount__doc__,
|
||||||
"Return the number of weak references to \'object\'.\n"
|
"getweakrefcount(object)\n"
|
||||||
"\n"
|
"Return the number of weak references to \'object\'.");
|
||||||
"_weakref.getweakrefcount(object)");
|
|
||||||
|
|
||||||
#define _WEAKREF_GETWEAKREFCOUNT_METHODDEF \
|
#define _WEAKREF_GETWEAKREFCOUNT_METHODDEF \
|
||||||
{"getweakrefcount", (PyCFunction)_weakref_getweakrefcount, METH_O, _weakref_getweakrefcount__doc__},
|
{"getweakrefcount", (PyCFunction)_weakref_getweakrefcount, METH_O, _weakref_getweakrefcount__doc__},
|
||||||
|
@ -43,7 +45,7 @@ exit:
|
||||||
|
|
||||||
static Py_ssize_t
|
static Py_ssize_t
|
||||||
_weakref_getweakrefcount_impl(PyModuleDef *module, PyObject *object)
|
_weakref_getweakrefcount_impl(PyModuleDef *module, PyObject *object)
|
||||||
/*[clinic checksum: 015113be0c9a0a8672d35df10c63e3642cc23da4]*/
|
/*[clinic checksum: 436e8fbe0297434375f039d8c2d9fc3a9bbe773c]*/
|
||||||
{
|
{
|
||||||
PyWeakReference **list;
|
PyWeakReference **list;
|
||||||
|
|
||||||
|
|
|
@ -190,7 +190,10 @@ corresponding Unix manual entries for more information on calls.");
|
||||||
#endif /* ! __WATCOMC__ || __QNX__ */
|
#endif /* ! __WATCOMC__ || __QNX__ */
|
||||||
|
|
||||||
|
|
||||||
|
/*[clinic]
|
||||||
|
module os
|
||||||
|
[clinic]*/
|
||||||
|
/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
|
||||||
|
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
|
|
||||||
|
@ -2404,7 +2407,6 @@ class dir_fd_converter(CConverter):
|
||||||
/*[python checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
|
/*[python checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
|
||||||
|
|
||||||
/*[clinic]
|
/*[clinic]
|
||||||
module os
|
|
||||||
|
|
||||||
os.stat -> object(doc_default='stat_result')
|
os.stat -> object(doc_default='stat_result')
|
||||||
|
|
||||||
|
@ -2435,9 +2437,9 @@ It's an error to use dir_fd or follow_symlinks when specifying path as
|
||||||
[clinic]*/
|
[clinic]*/
|
||||||
|
|
||||||
PyDoc_STRVAR(os_stat__doc__,
|
PyDoc_STRVAR(os_stat__doc__,
|
||||||
|
"stat(path, *, dir_fd=None, follow_symlinks=True)\n"
|
||||||
"Perform a stat system call on the given path.\n"
|
"Perform a stat system call on the given path.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"os.stat(path, *, dir_fd=None, follow_symlinks=True) -> stat_result\n"
|
|
||||||
" path\n"
|
" path\n"
|
||||||
" Path to be examined; can be string, bytes, or open-file-descriptor int.\n"
|
" Path to be examined; can be string, bytes, or open-file-descriptor int.\n"
|
||||||
" dir_fd\n"
|
" dir_fd\n"
|
||||||
|
@ -2486,7 +2488,7 @@ exit:
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks)
|
os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks)
|
||||||
/*[clinic checksum: b08112eff0ceab3ec2c72352da95ce73f245d104]*/
|
/*[clinic checksum: 85a71ad602e89f8e280118da976f70cd2f9abdf1]*/
|
||||||
{
|
{
|
||||||
return posix_do_stat("stat", path, dir_fd, follow_symlinks);
|
return posix_do_stat("stat", path, dir_fd, follow_symlinks);
|
||||||
}
|
}
|
||||||
|
@ -2567,9 +2569,9 @@ Note that most operations will use the effective uid/gid, therefore this
|
||||||
[clinic]*/
|
[clinic]*/
|
||||||
|
|
||||||
PyDoc_STRVAR(os_access__doc__,
|
PyDoc_STRVAR(os_access__doc__,
|
||||||
|
"access(path, mode, *, dir_fd=None, effective_ids=False, follow_symlinks=True)\n"
|
||||||
"Use the real uid/gid to test for access to a path.\n"
|
"Use the real uid/gid to test for access to a path.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"os.access(path, mode, *, dir_fd=None, effective_ids=False, follow_symlinks=True) -> True if granted, False otherwise\n"
|
|
||||||
" path\n"
|
" path\n"
|
||||||
" Path to be tested; can be string, bytes, or open-file-descriptor int.\n"
|
" Path to be tested; can be string, bytes, or open-file-descriptor int.\n"
|
||||||
" mode\n"
|
" mode\n"
|
||||||
|
@ -2587,7 +2589,6 @@ PyDoc_STRVAR(os_access__doc__,
|
||||||
" access will examine the symbolic link itself instead of the file\n"
|
" access will examine the symbolic link itself instead of the file\n"
|
||||||
" the link points to.\n"
|
" the link points to.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"{parameters}\n"
|
|
||||||
"dir_fd, effective_ids, and follow_symlinks may not be implemented\n"
|
"dir_fd, effective_ids, and follow_symlinks may not be implemented\n"
|
||||||
" on your platform. If they are unavailable, using them will raise a\n"
|
" on your platform. If they are unavailable, using them will raise a\n"
|
||||||
" NotImplementedError.\n"
|
" NotImplementedError.\n"
|
||||||
|
@ -2628,7 +2629,7 @@ exit:
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks)
|
os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks)
|
||||||
/*[clinic checksum: b9f8ececb061d31b64220c29526bfee642d1b602]*/
|
/*[clinic checksum: 636e835c36562a2fc11acab75314634127fdf769]*/
|
||||||
{
|
{
|
||||||
PyObject *return_value = NULL;
|
PyObject *return_value = NULL;
|
||||||
|
|
||||||
|
@ -2724,9 +2725,9 @@ Return the name of the terminal device connected to 'fd'.
|
||||||
[clinic]*/
|
[clinic]*/
|
||||||
|
|
||||||
PyDoc_STRVAR(os_ttyname__doc__,
|
PyDoc_STRVAR(os_ttyname__doc__,
|
||||||
|
"ttyname(fd)\n"
|
||||||
"Return the name of the terminal device connected to \'fd\'.\n"
|
"Return the name of the terminal device connected to \'fd\'.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"os.ttyname(fd)\n"
|
|
||||||
" fd\n"
|
" fd\n"
|
||||||
" Integer file descriptor handle.");
|
" Integer file descriptor handle.");
|
||||||
|
|
||||||
|
@ -2758,7 +2759,7 @@ exit:
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
os_ttyname_impl(PyModuleDef *module, int fd)
|
os_ttyname_impl(PyModuleDef *module, int fd)
|
||||||
/*[clinic checksum: 61e4e525984cb293f949ccae6ae393c0011dfe8e]*/
|
/*[clinic checksum: 0f368134dc0a7f21f25185e2e6bacf7675fb473a]*/
|
||||||
{
|
{
|
||||||
char *ret;
|
char *ret;
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,12 @@
|
||||||
#include "ucnhash.h"
|
#include "ucnhash.h"
|
||||||
#include "structmember.h"
|
#include "structmember.h"
|
||||||
|
|
||||||
|
/*[clinic]
|
||||||
|
module unicodedata
|
||||||
|
class unicodedata.UCD
|
||||||
|
[clinic]*/
|
||||||
|
/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
|
||||||
|
|
||||||
/* character properties */
|
/* character properties */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -108,8 +114,7 @@ static Py_UCS4 getuchar(PyUnicodeObject *obj)
|
||||||
/* --- Module API --------------------------------------------------------- */
|
/* --- Module API --------------------------------------------------------- */
|
||||||
|
|
||||||
/*[clinic]
|
/*[clinic]
|
||||||
module unicodedata
|
|
||||||
class unicodedata.UCD
|
|
||||||
unicodedata.UCD.decimal
|
unicodedata.UCD.decimal
|
||||||
|
|
||||||
unichr: object(type='str')
|
unichr: object(type='str')
|
||||||
|
@ -124,10 +129,9 @@ not given, ValueError is raised.
|
||||||
[clinic]*/
|
[clinic]*/
|
||||||
|
|
||||||
PyDoc_STRVAR(unicodedata_UCD_decimal__doc__,
|
PyDoc_STRVAR(unicodedata_UCD_decimal__doc__,
|
||||||
|
"decimal(unichr, default=None)\n"
|
||||||
"Converts a Unicode character into its equivalent decimal value.\n"
|
"Converts a Unicode character into its equivalent decimal value.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"unicodedata.UCD.decimal(unichr, default=None)\n"
|
|
||||||
"\n"
|
|
||||||
"Returns the decimal value assigned to the Unicode character unichr\n"
|
"Returns the decimal value assigned to the Unicode character unichr\n"
|
||||||
"as integer. If no such value is defined, default is returned, or, if\n"
|
"as integer. If no such value is defined, default is returned, or, if\n"
|
||||||
"not given, ValueError is raised.");
|
"not given, ValueError is raised.");
|
||||||
|
@ -157,7 +161,7 @@ exit:
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
unicodedata_UCD_decimal_impl(PyObject *self, PyObject *unichr, PyObject *default_value)
|
unicodedata_UCD_decimal_impl(PyObject *self, PyObject *unichr, PyObject *default_value)
|
||||||
/*[clinic checksum: a0980c387387287e2ac230c37d95b26f6903e0d2]*/
|
/*[clinic checksum: 9576fa55f4ea0be82968af39dc9d0283e634beeb]*/
|
||||||
{
|
{
|
||||||
PyUnicodeObject *v = (PyUnicodeObject *)unichr;
|
PyUnicodeObject *v = (PyUnicodeObject *)unichr;
|
||||||
int have_old = 0;
|
int have_old = 0;
|
||||||
|
|
|
@ -165,6 +165,7 @@ PyZlib_Free(voidpf ctx, void *ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*[clinic]
|
/*[clinic]
|
||||||
|
|
||||||
zlib.compress
|
zlib.compress
|
||||||
bytes: Py_buffer
|
bytes: Py_buffer
|
||||||
Binary data to be compressed.
|
Binary data to be compressed.
|
||||||
|
@ -179,9 +180,9 @@ Returns compressed string.
|
||||||
[clinic]*/
|
[clinic]*/
|
||||||
|
|
||||||
PyDoc_STRVAR(zlib_compress__doc__,
|
PyDoc_STRVAR(zlib_compress__doc__,
|
||||||
|
"compress(bytes, [level])\n"
|
||||||
"Returns compressed string.\n"
|
"Returns compressed string.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"zlib.compress(bytes, [level])\n"
|
|
||||||
" bytes\n"
|
" bytes\n"
|
||||||
" Binary data to be compressed.\n"
|
" Binary data to be compressed.\n"
|
||||||
" level\n"
|
" level\n"
|
||||||
|
@ -226,7 +227,7 @@ zlib_compress(PyModuleDef *module, PyObject *args)
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
zlib_compress_impl(PyModuleDef *module, Py_buffer *bytes, int group_right_1, int level)
|
zlib_compress_impl(PyModuleDef *module, Py_buffer *bytes, int group_right_1, int level)
|
||||||
/*[clinic checksum: 03e857836db25448d4d572da537eb7faf7695d71]*/
|
/*[clinic checksum: f490708eff84be652b5ebe7fe622ab73ac12c888]*/
|
||||||
{
|
{
|
||||||
PyObject *ReturnVal = NULL;
|
PyObject *ReturnVal = NULL;
|
||||||
Byte *input, *output = NULL;
|
Byte *input, *output = NULL;
|
||||||
|
@ -742,6 +743,7 @@ save_unconsumed_input(compobject *self, int err)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*[clinic]
|
/*[clinic]
|
||||||
|
|
||||||
zlib.Decompress.decompress
|
zlib.Decompress.decompress
|
||||||
|
|
||||||
data: Py_buffer
|
data: Py_buffer
|
||||||
|
@ -760,9 +762,9 @@ Call the flush() method to clear these buffers.
|
||||||
[clinic]*/
|
[clinic]*/
|
||||||
|
|
||||||
PyDoc_STRVAR(zlib_Decompress_decompress__doc__,
|
PyDoc_STRVAR(zlib_Decompress_decompress__doc__,
|
||||||
|
"decompress(data, max_length=0)\n"
|
||||||
"Return a string containing the decompressed version of the data.\n"
|
"Return a string containing the decompressed version of the data.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"zlib.Decompress.decompress(data, max_length=0)\n"
|
|
||||||
" data\n"
|
" data\n"
|
||||||
" The binary data to decompress.\n"
|
" The binary data to decompress.\n"
|
||||||
" max_length\n"
|
" max_length\n"
|
||||||
|
@ -803,7 +805,7 @@ exit:
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
zlib_Decompress_decompress_impl(PyObject *self, Py_buffer *data, unsigned int max_length)
|
zlib_Decompress_decompress_impl(PyObject *self, Py_buffer *data, unsigned int max_length)
|
||||||
/*[clinic checksum: f83e91728d327462d7ccbee95299514f26b92253]*/
|
/*[clinic checksum: 4683928665a1fa6987f5c57cada4a22807a78fbb]*/
|
||||||
{
|
{
|
||||||
compobject *zself = (compobject *)self;
|
compobject *zself = (compobject *)self;
|
||||||
int err;
|
int err;
|
||||||
|
@ -1029,16 +1031,15 @@ Return a copy of the compression object.
|
||||||
[clinic]*/
|
[clinic]*/
|
||||||
|
|
||||||
PyDoc_STRVAR(zlib_Compress_copy__doc__,
|
PyDoc_STRVAR(zlib_Compress_copy__doc__,
|
||||||
"Return a copy of the compression object.\n"
|
"copy()\n"
|
||||||
"\n"
|
"Return a copy of the compression object.");
|
||||||
"zlib.Compress.copy()");
|
|
||||||
|
|
||||||
#define ZLIB_COMPRESS_COPY_METHODDEF \
|
#define ZLIB_COMPRESS_COPY_METHODDEF \
|
||||||
{"copy", (PyCFunction)zlib_Compress_copy, METH_NOARGS, zlib_Compress_copy__doc__},
|
{"copy", (PyCFunction)zlib_Compress_copy, METH_NOARGS, zlib_Compress_copy__doc__},
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
zlib_Compress_copy(PyObject *self)
|
zlib_Compress_copy(PyObject *self)
|
||||||
/*[clinic checksum: 2551952e72329f0f2beb48a1dde3780e485a220b]*/
|
/*[clinic checksum: 8d30351f05defbc2b335c2a78d18f07aa367bb1d]*/
|
||||||
{
|
{
|
||||||
compobject *zself = (compobject *)self;
|
compobject *zself = (compobject *)self;
|
||||||
compobject *retval = NULL;
|
compobject *retval = NULL;
|
||||||
|
|
|
@ -69,6 +69,11 @@ to the combined-table form.
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "stringlib/eq.h"
|
#include "stringlib/eq.h"
|
||||||
|
|
||||||
|
/*[clinic]
|
||||||
|
class dict
|
||||||
|
[clinic]*/
|
||||||
|
/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* Cached hash code of me_key. */
|
/* Cached hash code of me_key. */
|
||||||
Py_hash_t me_hash;
|
Py_hash_t me_hash;
|
||||||
|
@ -2160,7 +2165,6 @@ dict_richcompare(PyObject *v, PyObject *w, int op)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*[clinic]
|
/*[clinic]
|
||||||
class dict
|
|
||||||
|
|
||||||
@coexist
|
@coexist
|
||||||
dict.__contains__
|
dict.__contains__
|
||||||
|
@ -2172,16 +2176,15 @@ True if D has a key k, else False"
|
||||||
[clinic]*/
|
[clinic]*/
|
||||||
|
|
||||||
PyDoc_STRVAR(dict___contains____doc__,
|
PyDoc_STRVAR(dict___contains____doc__,
|
||||||
"True if D has a key k, else False\"\n"
|
"__contains__(key)\n"
|
||||||
"\n"
|
"True if D has a key k, else False\"");
|
||||||
"dict.__contains__(key)");
|
|
||||||
|
|
||||||
#define DICT___CONTAINS___METHODDEF \
|
#define DICT___CONTAINS___METHODDEF \
|
||||||
{"__contains__", (PyCFunction)dict___contains__, METH_O|METH_COEXIST, dict___contains____doc__},
|
{"__contains__", (PyCFunction)dict___contains__, METH_O|METH_COEXIST, dict___contains____doc__},
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
dict___contains__(PyObject *self, PyObject *key)
|
dict___contains__(PyObject *self, PyObject *key)
|
||||||
/*[clinic checksum: 61c5c802ea1d35699a1a754f1f3538ea9b259cf4]*/
|
/*[clinic checksum: 3bbac5ce898ae630d9668fa1c8b3afb645ff22e8]*/
|
||||||
{
|
{
|
||||||
register PyDictObject *mp = (PyDictObject *)self;
|
register PyDictObject *mp = (PyDictObject *)self;
|
||||||
Py_hash_t hash;
|
Py_hash_t hash;
|
||||||
|
|
|
@ -159,17 +159,77 @@ meth_dealloc(PyCFunctionObject *m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* finds the docstring's introspection signature.
|
||||||
|
* if present, returns a pointer pointing to the first '('.
|
||||||
|
* otherwise returns NULL.
|
||||||
|
*/
|
||||||
|
static const char *find_signature(PyCFunctionObject *m)
|
||||||
|
{
|
||||||
|
const char *trace = m->m_ml->ml_doc;
|
||||||
|
const char *name = m->m_ml->ml_name;
|
||||||
|
size_t length;
|
||||||
|
if (!trace || !name)
|
||||||
|
return NULL;
|
||||||
|
length = strlen(name);
|
||||||
|
if (strncmp(trace, name, length))
|
||||||
|
return NULL;
|
||||||
|
trace += length;
|
||||||
|
if (*trace != '(')
|
||||||
|
return NULL;
|
||||||
|
return trace;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* skips to the end of the docstring's instrospection signature.
|
||||||
|
*/
|
||||||
|
static const char *skip_signature(const char *trace)
|
||||||
|
{
|
||||||
|
while (*trace && *trace != '\n')
|
||||||
|
trace++;
|
||||||
|
return trace;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *skip_eols(const char *trace)
|
||||||
|
{
|
||||||
|
while (*trace == '\n')
|
||||||
|
trace++;
|
||||||
|
return trace;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
meth_get__text_signature__(PyCFunctionObject *m, void *closure)
|
||||||
|
{
|
||||||
|
const char *start = find_signature(m);
|
||||||
|
const char *trace;
|
||||||
|
|
||||||
|
if (!start) {
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
trace = skip_signature(start);
|
||||||
|
return PyUnicode_FromStringAndSize(start, trace - start);
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
meth_get__doc__(PyCFunctionObject *m, void *closure)
|
meth_get__doc__(PyCFunctionObject *m, void *closure)
|
||||||
{
|
{
|
||||||
const char *doc = m->m_ml->ml_doc;
|
const char *doc = find_signature(m);
|
||||||
|
|
||||||
if (doc != NULL)
|
if (doc)
|
||||||
return PyUnicode_FromString(doc);
|
doc = skip_eols(skip_signature(doc));
|
||||||
|
else
|
||||||
|
doc = m->m_ml->ml_doc;
|
||||||
|
|
||||||
|
if (!doc) {
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
return Py_None;
|
return Py_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return PyUnicode_FromString(doc);
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
meth_get__name__(PyCFunctionObject *m, void *closure)
|
meth_get__name__(PyCFunctionObject *m, void *closure)
|
||||||
{
|
{
|
||||||
|
@ -236,6 +296,7 @@ static PyGetSetDef meth_getsets [] = {
|
||||||
{"__name__", (getter)meth_get__name__, NULL, NULL},
|
{"__name__", (getter)meth_get__name__, NULL, NULL},
|
||||||
{"__qualname__", (getter)meth_get__qualname__, NULL, NULL},
|
{"__qualname__", (getter)meth_get__qualname__, NULL, NULL},
|
||||||
{"__self__", (getter)meth_get__self__, NULL, NULL},
|
{"__self__", (getter)meth_get__self__, NULL, NULL},
|
||||||
|
{"__text_signature__", (getter)meth_get__text_signature__, NULL, NULL},
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,11 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*[clinic]
|
||||||
|
class str
|
||||||
|
[clinic]*/
|
||||||
|
/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
|
||||||
|
|
||||||
/* --- Globals ------------------------------------------------------------
|
/* --- Globals ------------------------------------------------------------
|
||||||
|
|
||||||
NOTE: In the interpreter's initialization phase, some globals are currently
|
NOTE: In the interpreter's initialization phase, some globals are currently
|
||||||
|
@ -12883,7 +12888,6 @@ unicode_swapcase(PyObject *self)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*[clinic]
|
/*[clinic]
|
||||||
class str
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
str.maketrans as unicode_maketrans
|
str.maketrans as unicode_maketrans
|
||||||
|
@ -12908,10 +12912,9 @@ must be a string, whose characters will be mapped to None in the result.
|
||||||
[clinic]*/
|
[clinic]*/
|
||||||
|
|
||||||
PyDoc_STRVAR(unicode_maketrans__doc__,
|
PyDoc_STRVAR(unicode_maketrans__doc__,
|
||||||
|
"maketrans(x, y=None, z=None)\n"
|
||||||
"Return a translation table usable for str.translate().\n"
|
"Return a translation table usable for str.translate().\n"
|
||||||
"\n"
|
"\n"
|
||||||
"str.maketrans(x, y=None, z=None)\n"
|
|
||||||
"\n"
|
|
||||||
"If there is only one argument, it must be a dictionary mapping Unicode\n"
|
"If there is only one argument, it must be a dictionary mapping Unicode\n"
|
||||||
"ordinals (integers) or characters to Unicode ordinals, strings or None.\n"
|
"ordinals (integers) or characters to Unicode ordinals, strings or None.\n"
|
||||||
"Character keys will be then converted to ordinals.\n"
|
"Character keys will be then converted to ordinals.\n"
|
||||||
|
@ -12946,7 +12949,7 @@ exit:
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
unicode_maketrans_impl(void *null, PyObject *x, PyObject *y, PyObject *z)
|
unicode_maketrans_impl(void *null, PyObject *x, PyObject *y, PyObject *z)
|
||||||
/*[clinic checksum: 6d522e3aea2f2e123da3c5d367132a99d803f9b9]*/
|
/*[clinic checksum: 7f76f414a0dfd0c614e0d4717872eeb520516da7]*/
|
||||||
{
|
{
|
||||||
PyObject *new = NULL, *key, *value;
|
PyObject *new = NULL, *key, *value;
|
||||||
Py_ssize_t i = 0;
|
Py_ssize_t i = 0;
|
||||||
|
|
|
@ -24,17 +24,6 @@ import tempfile
|
||||||
import textwrap
|
import textwrap
|
||||||
|
|
||||||
# TODO:
|
# TODO:
|
||||||
# converters for
|
|
||||||
#
|
|
||||||
# es
|
|
||||||
# es#
|
|
||||||
# et
|
|
||||||
# et#
|
|
||||||
# s#
|
|
||||||
# u#
|
|
||||||
# y#
|
|
||||||
# z#
|
|
||||||
# Z#
|
|
||||||
#
|
#
|
||||||
# soon:
|
# soon:
|
||||||
#
|
#
|
||||||
|
@ -44,12 +33,6 @@ import textwrap
|
||||||
# * max and min use positional only with an optional group
|
# * max and min use positional only with an optional group
|
||||||
# and keyword-only
|
# and keyword-only
|
||||||
#
|
#
|
||||||
# * Generate forward slash for docstring first line
|
|
||||||
# (if I get positional-only syntax pep accepted)
|
|
||||||
#
|
|
||||||
# * Add "version" directive, so we can complain if the file
|
|
||||||
# is too new for us.
|
|
||||||
#
|
|
||||||
|
|
||||||
version = '1'
|
version = '1'
|
||||||
|
|
||||||
|
@ -2441,7 +2424,7 @@ class DSLParser:
|
||||||
## docstring first line
|
## docstring first line
|
||||||
##
|
##
|
||||||
|
|
||||||
add(f.full_name)
|
add(f.name)
|
||||||
add('(')
|
add('(')
|
||||||
|
|
||||||
# populate "right_bracket_count" field for every parameter
|
# populate "right_bracket_count" field for every parameter
|
||||||
|
@ -2498,29 +2481,32 @@ class DSLParser:
|
||||||
add(fix_right_bracket_count(0))
|
add(fix_right_bracket_count(0))
|
||||||
add(')')
|
add(')')
|
||||||
|
|
||||||
if f.return_converter.doc_default:
|
# if f.return_converter.doc_default:
|
||||||
add(' -> ')
|
# add(' -> ')
|
||||||
add(f.return_converter.doc_default)
|
# add(f.return_converter.doc_default)
|
||||||
|
|
||||||
docstring_first_line = output()
|
docstring_first_line = output()
|
||||||
|
|
||||||
# now fix up the places where the brackets look wrong
|
# now fix up the places where the brackets look wrong
|
||||||
docstring_first_line = docstring_first_line.replace(', ]', ',] ')
|
docstring_first_line = docstring_first_line.replace(', ]', ',] ')
|
||||||
|
|
||||||
# okay. now we're officially building the
|
# okay. now we're officially building the "parameters" section.
|
||||||
# "prototype" section.
|
|
||||||
add(docstring_first_line)
|
|
||||||
|
|
||||||
# create substitution text for {parameters}
|
# create substitution text for {parameters}
|
||||||
|
spacer_line = False
|
||||||
for p in parameters:
|
for p in parameters:
|
||||||
if not p.docstring.strip():
|
if not p.docstring.strip():
|
||||||
continue
|
continue
|
||||||
|
if spacer_line:
|
||||||
add('\n')
|
add('\n')
|
||||||
|
else:
|
||||||
|
spacer_line = True
|
||||||
add(" ")
|
add(" ")
|
||||||
add(p.name)
|
add(p.name)
|
||||||
add('\n')
|
add('\n')
|
||||||
add(textwrap.indent(rstrip_lines(p.docstring.rstrip()), " "))
|
add(textwrap.indent(rstrip_lines(p.docstring.rstrip()), " "))
|
||||||
prototype = output()
|
parameters = output()
|
||||||
|
if parameters:
|
||||||
|
parameters += '\n'
|
||||||
|
|
||||||
##
|
##
|
||||||
## docstring body
|
## docstring body
|
||||||
|
@ -2549,21 +2535,26 @@ class DSLParser:
|
||||||
elif len(lines) == 1:
|
elif len(lines) == 1:
|
||||||
# the docstring is only one line right now--the summary line.
|
# the docstring is only one line right now--the summary line.
|
||||||
# add an empty line after the summary line so we have space
|
# add an empty line after the summary line so we have space
|
||||||
# between it and the {prototype} we're about to add.
|
# between it and the {parameters} we're about to add.
|
||||||
lines.append('')
|
lines.append('')
|
||||||
|
|
||||||
prototype_marker_count = len(docstring.split('{prototype}')) - 1
|
parameters_marker_count = len(docstring.split('{parameters}')) - 1
|
||||||
if prototype_marker_count:
|
if parameters_marker_count > 1:
|
||||||
fail('You may not specify {prototype} in a docstring!')
|
fail('You may not specify {parameters} more than once in a docstring!')
|
||||||
# insert *after* the summary line
|
|
||||||
lines.insert(2, '{prototype}\n')
|
if not parameters_marker_count:
|
||||||
|
# insert after summary line
|
||||||
|
lines.insert(2, '{parameters}')
|
||||||
|
|
||||||
|
# insert at front of docstring
|
||||||
|
lines.insert(0, docstring_first_line)
|
||||||
|
|
||||||
docstring = "\n".join(lines)
|
docstring = "\n".join(lines)
|
||||||
|
|
||||||
add(docstring)
|
add(docstring)
|
||||||
docstring = output()
|
docstring = output()
|
||||||
|
|
||||||
docstring = linear_format(docstring, prototype=prototype)
|
docstring = linear_format(docstring, parameters=parameters)
|
||||||
docstring = docstring.rstrip()
|
docstring = docstring.rstrip()
|
||||||
|
|
||||||
return docstring
|
return docstring
|
||||||
|
|
Loading…
Reference in New Issue