Issue #20189: Four additional builtin types (PyTypeObject,

PyMethodDescr_Type, _PyMethodWrapper_Type, and PyWrapperDescr_Type)
have been modified to provide introspection information for builtins.
Also: many additional Lib, test suite, and Argument Clinic fixes.
This commit is contained in:
Larry Hastings 2014-01-24 06:17:25 -08:00
parent b3c0f4067d
commit 5c66189e88
31 changed files with 851 additions and 508 deletions

View File

@ -429,6 +429,9 @@ function.
Accepts a wide range of python callables, from plain functions and classes to Accepts a wide range of python callables, from plain functions and classes to
:func:`functools.partial` objects. :func:`functools.partial` objects.
Raises :exc:`ValueError` if no signature can be provided, and
:exc:`TypeError` if that type of object is not supported.
.. note:: .. note::
Some callables may not be introspectable in certain implementations of Some callables may not be introspectable in certain implementations of

View File

@ -492,6 +492,9 @@ PyAPI_FUNC(PyTypeObject *) _PyType_CalculateMetaclass(PyTypeObject *, PyObject *
PyAPI_FUNC(unsigned int) PyType_ClearCache(void); PyAPI_FUNC(unsigned int) PyType_ClearCache(void);
PyAPI_FUNC(void) PyType_Modified(PyTypeObject *); PyAPI_FUNC(void) PyType_Modified(PyTypeObject *);
PyAPI_FUNC(PyObject *) _PyType_GetDocFromInternalDoc(const char *name, const char *internal_doc);
PyAPI_FUNC(PyObject *) _PyType_GetTextSignatureFromInternalDoc(const char *name, const char *internal_doc);
/* Generic operations on objects */ /* Generic operations on objects */
struct _Py_Identifier; struct _Py_Identifier;
#ifndef Py_LIMITED_API #ifndef Py_LIMITED_API

View File

@ -55,24 +55,27 @@ class Get_signatureTest(unittest.TestCase):
gtest(list.__new__, gtest(list.__new__,
'T.__new__(S, ...) -> a new object with type S, a subtype of T') 'T.__new__(S, ...) -> a new object with type S, a subtype of T')
gtest(list.__init__, gtest(list.__init__,
'x.__init__(...) initializes x; see help(type(x)) for signature') 'Initializes self. See help(type(self)) for accurate signature.')
append_doc = "L.append(object) -> None -- append object to end" append_doc = "L.append(object) -> None -- append object to end"
gtest(list.append, append_doc) gtest(list.append, append_doc)
gtest([].append, append_doc) gtest([].append, append_doc)
gtest(List.append, append_doc) gtest(List.append, append_doc)
gtest(types.MethodType, "method(function, instance)") gtest(types.MethodType, "Create a bound instance method object.")
gtest(SB(), default_tip) gtest(SB(), default_tip)
def test_multiline_docstring(self): def test_multiline_docstring(self):
# Test fewer lines than max. # Test fewer lines than max.
self.assertEqual(signature(list), self.assertEqual(signature(dict),
"list() -> new empty list\n" "dict(mapping) -> new dictionary initialized from a mapping object's\n"
"list(iterable) -> new list initialized from iterable's items") "(key, value) pairs\n"
"dict(iterable) -> new dictionary initialized as if via:\n"
"d = {}\n"
"for k, v in iterable:"
)
# Test max lines and line (currently) too long. # Test max lines and line (currently) too long.
self.assertEqual(signature(bytes), self.assertEqual(signature(bytes),
"bytes(iterable_of_ints) -> bytes\n"
"bytes(string, encoding[, errors]) -> bytes\n" "bytes(string, encoding[, errors]) -> bytes\n"
"bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer\n" "bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer\n"
#bytes(int) -> bytes object of size given by the parameter initialized with null bytes #bytes(int) -> bytes object of size given by the parameter initialized with null bytes

View File

@ -1419,9 +1419,11 @@ def getgeneratorlocals(generator):
_WrapperDescriptor = type(type.__call__) _WrapperDescriptor = type(type.__call__)
_MethodWrapper = type(all.__call__) _MethodWrapper = type(all.__call__)
_ClassMethodWrapper = type(int.__dict__['from_bytes'])
_NonUserDefinedCallables = (_WrapperDescriptor, _NonUserDefinedCallables = (_WrapperDescriptor,
_MethodWrapper, _MethodWrapper,
_ClassMethodWrapper,
types.BuiltinFunctionType) types.BuiltinFunctionType)
@ -1443,6 +1445,13 @@ def signature(obj):
if not callable(obj): if not callable(obj):
raise TypeError('{!r} is not a callable object'.format(obj)) raise TypeError('{!r} is not a callable object'.format(obj))
if (isinstance(obj, _NonUserDefinedCallables) or
ismethoddescriptor(obj) or
isinstance(obj, type)):
sig = Signature.from_builtin(obj)
if sig:
return sig
if isinstance(obj, types.MethodType): if isinstance(obj, types.MethodType):
# In this case we skip the first parameter of the underlying # In this case we skip the first parameter of the underlying
# function (usually `self` or `cls`). # function (usually `self` or `cls`).
@ -1460,13 +1469,9 @@ def signature(obj):
if sig is not None: if sig is not None:
return sig return sig
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)
@ -2033,7 +2038,7 @@ class Signature:
name = parse_name(name_node) name = parse_name(name_node)
if name is invalid: if name is invalid:
return None return None
if default_node: if default_node and default_node is not _empty:
try: try:
default_node = RewriteSymbolics().visit(default_node) default_node = RewriteSymbolics().visit(default_node)
o = ast.literal_eval(default_node) o = ast.literal_eval(default_node)
@ -2066,6 +2071,23 @@ class Signature:
kind = Parameter.VAR_KEYWORD kind = Parameter.VAR_KEYWORD
p(f.args.kwarg, empty) p(f.args.kwarg, empty)
if parameters and (hasattr(func, '__self__') or
isinstance(func, _WrapperDescriptor,) or
ismethoddescriptor(func)
):
name = parameters[0].name
if name not in ('self', 'module', 'type'):
pass
elif getattr(func, '__self__', None):
# strip off self (it's already been bound)
p = parameters.pop(0)
if not p.name in ('self', 'module', 'type'):
raise ValueError('Unexpected name ' + repr(p.name) + ', expected self/module/cls/type')
else:
# for builtins, self parameter is always positional-only!
p = parameters[0].replace(kind=Parameter.POSITIONAL_ONLY)
parameters[0] = p
return cls(parameters, return_annotation=cls.empty) return cls(parameters, return_annotation=cls.empty)

View File

@ -925,7 +925,10 @@ class HTMLDoc(Doc):
anchor, name, reallink) anchor, name, reallink)
argspec = None argspec = None
if inspect.isfunction(object) or inspect.isbuiltin(object): if inspect.isfunction(object) or inspect.isbuiltin(object):
signature = inspect.signature(object) try:
signature = inspect.signature(object)
except (ValueError, TypeError):
signature = None
if signature: if signature:
argspec = str(signature) argspec = str(signature)
if realname == '<lambda>': if realname == '<lambda>':
@ -1319,8 +1322,12 @@ location listed above.
skipdocs = 1 skipdocs = 1
title = self.bold(name) + ' = ' + realname title = self.bold(name) + ' = ' + realname
argspec = None argspec = None
if inspect.isfunction(object) or inspect.isbuiltin(object):
signature = inspect.signature(object) if inspect.isroutine(object):
try:
signature = inspect.signature(object)
except (ValueError, TypeError):
signature = None
if signature: if signature:
argspec = str(signature) argspec = str(signature)
if realname == '<lambda>': if realname == '<lambda>':

View File

@ -125,7 +125,7 @@ class CAPITest(unittest.TestCase):
self.assertEqual(_testcapi.docstring_no_signature.__text_signature__, None) self.assertEqual(_testcapi.docstring_no_signature.__text_signature__, None)
self.assertEqual(_testcapi.docstring_with_invalid_signature.__doc__, self.assertEqual(_testcapi.docstring_with_invalid_signature.__doc__,
"docstring_with_invalid_signature (boo)\n" "docstring_with_invalid_signature (module, boo)\n"
"\n" "\n"
"This docstring has an invalid signature." "This docstring has an invalid signature."
) )
@ -133,12 +133,12 @@ class CAPITest(unittest.TestCase):
self.assertEqual(_testcapi.docstring_with_signature.__doc__, self.assertEqual(_testcapi.docstring_with_signature.__doc__,
"This docstring has a valid signature.") "This docstring has a valid signature.")
self.assertEqual(_testcapi.docstring_with_signature.__text_signature__, "(sig)") self.assertEqual(_testcapi.docstring_with_signature.__text_signature__, "(module, sig)")
self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__doc__, self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__doc__,
"This docstring has a valid signature and some extra newlines.") "This docstring has a valid signature and some extra newlines.")
self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__text_signature__, self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__text_signature__,
"(parameter)") "(module, parameter)")
@unittest.skipUnless(threading, 'Threading required for this test.') @unittest.skipUnless(threading, 'Threading required for this test.')

View File

@ -436,8 +436,8 @@ From the Iterators list, about the types of these things.
>>> [s for s in dir(i) if not s.startswith('_')] >>> [s for s in dir(i) if not s.startswith('_')]
['close', 'gi_code', 'gi_frame', 'gi_running', 'send', 'throw'] ['close', 'gi_code', 'gi_frame', 'gi_running', 'send', 'throw']
>>> from test.support import HAVE_DOCSTRINGS >>> from test.support import HAVE_DOCSTRINGS
>>> print(i.__next__.__doc__ if HAVE_DOCSTRINGS else 'x.__next__() <==> next(x)') >>> print(i.__next__.__doc__ if HAVE_DOCSTRINGS else 'Implements next(self).')
x.__next__() <==> next(x) Implements next(self).
>>> iter(i) is i >>> iter(i) is i
True True
>>> import types >>> import types

View File

@ -222,8 +222,8 @@ Check that generator attributes are present
True True
>>> from test.support import HAVE_DOCSTRINGS >>> from test.support import HAVE_DOCSTRINGS
>>> print(g.__next__.__doc__ if HAVE_DOCSTRINGS else 'x.__next__() <==> next(x)') >>> print(g.__next__.__doc__ if HAVE_DOCSTRINGS else 'Implements next(self).')
x.__next__() <==> next(x) Implements next(self).
>>> import types >>> import types
>>> isinstance(g, types.GeneratorType) >>> isinstance(g, types.GeneratorType)
True True

View File

@ -1,21 +1,25 @@
import re import _testcapi
import sys
import types
import unittest
import inspect
import linecache
import datetime
import collections import collections
import os import datetime
import shutil
import functools import functools
import importlib import importlib
import inspect
import io
import linecache
import os
from os.path import normcase from os.path import normcase
import _pickle
import re
import shutil
import sys
import types
import unicodedata
import unittest
try: try:
from concurrent.futures import ThreadPoolExecutor from concurrent.futures import ThreadPoolExecutor
except ImportError: except ImportError:
ThreadPoolExecutor = None ThreadPoolExecutor = None
import _testcapi
from test.support import run_unittest, TESTFN, DirsOnSysPath from test.support import run_unittest, TESTFN, DirsOnSysPath
from test.support import MISSING_C_DOCSTRINGS from test.support import MISSING_C_DOCSTRINGS
@ -23,8 +27,6 @@ from test.script_helper import assert_python_ok, assert_python_failure
from test import inspect_fodder as mod from test import inspect_fodder as mod
from test import inspect_fodder2 as mod2 from test import inspect_fodder2 as mod2
# C module for test_findsource_binary
import unicodedata
# Functions tested in this suite: # Functions tested in this suite:
# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode, # ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
@ -1582,23 +1584,30 @@ class TestSignatureObject(unittest.TestCase):
...)) ...))
def test_signature_on_unsupported_builtins(self): def test_signature_on_unsupported_builtins(self):
with self.assertRaisesRegex(ValueError, 'not supported by signature'): with self.assertRaisesRegex(ValueError, 'no signature found'):
inspect.signature(type) # min simply doesn't have a signature (yet)
with self.assertRaisesRegex(ValueError, 'not supported by signature'): inspect.signature(min)
# support for 'wrapper_descriptor'
inspect.signature(type.__call__)
with self.assertRaisesRegex(ValueError, 'not supported by signature'):
# support for 'method-wrapper'
inspect.signature(min.__call__)
@unittest.skipIf(MISSING_C_DOCSTRINGS, @unittest.skipIf(MISSING_C_DOCSTRINGS,
"Signature information for builtins requires docstrings") "Signature information for builtins requires docstrings")
def test_signature_on_builtins(self): def test_signature_on_builtins(self):
# min doesn't have a signature (yet)
self.assertEqual(inspect.signature(min), None)
signature = inspect.signature(_testcapi.docstring_with_signature_with_defaults) def test_unbound_method(o):
self.assertTrue(isinstance(signature, inspect.Signature)) """Use this to test unbound methods (things that should have a self)"""
signature = inspect.signature(o)
self.assertTrue(isinstance(signature, inspect.Signature))
self.assertEqual(list(signature.parameters.values())[0].name, 'self')
return signature
def test_callable(o):
"""Use this to test bound methods or normal callables (things that don't expect self)"""
signature = inspect.signature(o)
self.assertTrue(isinstance(signature, inspect.Signature))
if signature.parameters:
self.assertNotEqual(list(signature.parameters.values())[0].name, 'self')
return signature
signature = test_callable(_testcapi.docstring_with_signature_with_defaults)
def p(name): return signature.parameters[name].default def p(name): return signature.parameters[name].default
self.assertEqual(p('s'), 'avocado') self.assertEqual(p('s'), 'avocado')
self.assertEqual(p('b'), b'bytes') self.assertEqual(p('b'), b'bytes')
@ -1611,6 +1620,41 @@ class TestSignatureObject(unittest.TestCase):
self.assertEqual(p('sys'), sys.maxsize) self.assertEqual(p('sys'), sys.maxsize)
self.assertEqual(p('exp'), sys.maxsize - 1) self.assertEqual(p('exp'), sys.maxsize - 1)
test_callable(type)
test_callable(object)
# normal method
# (PyMethodDescr_Type, "method_descriptor")
test_unbound_method(_pickle.Pickler.dump)
d = _pickle.Pickler(io.StringIO())
test_callable(d.dump)
# static method
test_callable(str.maketrans)
test_callable('abc'.maketrans)
# class method
test_callable(dict.fromkeys)
test_callable({}.fromkeys)
# wrapper around slot (PyWrapperDescr_Type, "wrapper_descriptor")
test_unbound_method(type.__call__)
test_unbound_method(int.__add__)
test_callable((3).__add__)
# _PyMethodWrapper_Type
# support for 'method-wrapper'
test_callable(min.__call__)
class ThisWorksNow:
__call__ = type
test_callable(ThisWorksNow())
def test_signature_on_builtins_no_signature(self):
with self.assertRaisesRegex(ValueError, 'no signature found for builtin'):
inspect.signature(_testcapi.docstring_no_signature)
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'):
inspect.signature(42) inspect.signature(42)
@ -1985,12 +2029,6 @@ class TestSignatureObject(unittest.TestCase):
((('a', ..., ..., "positional_or_keyword"),), ((('a', ..., ..., "positional_or_keyword"),),
...)) ...))
class ToFail:
__call__ = type
with self.assertRaisesRegex(ValueError, "not supported by signature"):
inspect.signature(ToFail())
class Wrapped: class Wrapped:
pass pass
Wrapped.__wrapped__ = lambda a: None Wrapped.__wrapped__ = lambda a: None

View File

@ -112,11 +112,24 @@ def _check_signature(func, mock, skipfirst, instance=False):
def _copy_func_details(func, funcopy): def _copy_func_details(func, funcopy):
funcopy.__name__ = func.__name__ funcopy.__name__ = func.__name__
funcopy.__doc__ = func.__doc__ funcopy.__doc__ = func.__doc__
try:
funcopy.__text_signature__ = func.__text_signature__
except AttributeError:
pass
# we explicitly don't copy func.__dict__ into this copy as it would # we explicitly don't copy func.__dict__ into this copy as it would
# expose original attributes that should be mocked # expose original attributes that should be mocked
funcopy.__module__ = func.__module__ try:
funcopy.__defaults__ = func.__defaults__ funcopy.__module__ = func.__module__
funcopy.__kwdefaults__ = func.__kwdefaults__ except AttributeError:
pass
try:
funcopy.__defaults__ = func.__defaults__
except AttributeError:
pass
try:
funcopy.__kwdefaults__ = func.__kwdefaults__
except AttributeError:
pass
def _callable(obj): def _callable(obj):

View File

@ -10,6 +10,10 @@ Release date: 2014-01-19
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #20189: Four additional builtin types (PyTypeObject,
PyMethodDescr_Type, _PyMethodWrapper_Type, and PyWrapperDescr_Type)
have been modified to provide introspection information for builtins.
- Issue #17825: Cursor "^" is correctly positioned for SyntaxError and - Issue #17825: Cursor "^" is correctly positioned for SyntaxError and
IndentationError. IndentationError.
@ -32,6 +36,10 @@ Core and Builtins
Library Library
------- -------
- Issue #20189: unittest.mock now no longer assumes that any object for
which it could get an inspect.Signature is a callable written in Python.
Fix courtesy of Michael Foord.
- Issue #20311: selector.PollSelector.select() now rounds the timeout away from - Issue #20311: selector.PollSelector.select() now rounds the timeout away from
zero, instead of rounding towards zero. For example, a timeout of one zero, instead of rounding towards zero. For example, a timeout of one
microsecond is now rounded to one millisecond, instead of being rounded to microsecond is now rounded to one millisecond, instead of being rounded to
@ -122,7 +130,7 @@ IDLE
--Issue #17390: Add Python version to Idle editor window title bar. --Issue #17390: Add Python version to Idle editor window title bar.
Original patches by Edmond Burnett and Kent Johnson. Original patches by Edmond Burnett and Kent Johnson.
- Issue #18960: IDLE now ignores the source encoding declaration on the second - Issue #18960: IDLE now ignores the source encoding declaration on the second
line if the first line contains anything except a comment. line if the first line contains anything except a comment.
@ -133,6 +141,16 @@ Tests
Tools/Demos Tools/Demos
----------- -----------
- Issue #20189: Argument Clinic now ensures that parser functions for
__new__ are always of type newfunc, the type of the tp_new slot.
Similarly, parser functions for __init__ are now always of type initproc,
the type of tp_init.
- Issue #20189: Argument Clinic now suppresses the docstring for __new__
and __init__ functions if no docstring is provided in the input.
- Issue #20189: Argument Clinic now suppresses the "self" parameter in the
impl for @staticmethod functions.
- Issue #20294: Argument Clinic now supports argument parsing for __new__ and - Issue #20294: Argument Clinic now supports argument parsing for __new__ and
__init__ functions. __init__ functions.

View File

@ -30,7 +30,7 @@ results for a given *word*.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(crypt_crypt__doc__, PyDoc_STRVAR(crypt_crypt__doc__,
"crypt(word, salt)\n" "crypt(module, word, salt)\n"
"Hash a *word* with the given *salt* and return the hashed password.\n" "Hash a *word* with the given *salt* and return the hashed password.\n"
"\n" "\n"
"*word* will usually be a user\'s password. *salt* (either a random 2 or 16\n" "*word* will usually be a user\'s password. *salt* (either a random 2 or 16\n"
@ -63,7 +63,7 @@ exit:
static PyObject * static PyObject *
crypt_crypt_impl(PyModuleDef *module, const char *word, const char *salt) crypt_crypt_impl(PyModuleDef *module, const char *word, const char *salt)
/*[clinic end generated code: checksum=a137540bf6862f9935fc112b8bb1d62d6dd1ad02]*/ /*[clinic end generated code: checksum=dbfe26a21eb335abefe6a0bbd0a682ea22b9adc0]*/
{ {
/* On some platforms (AtheOS) crypt returns NULL for an invalid /* On some platforms (AtheOS) crypt returns NULL for an invalid
salt. Return None in that case. XXX Maybe raise an exception? */ salt. Return None in that case. XXX Maybe raise an exception? */

View File

@ -584,7 +584,7 @@ current settings for the window object.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(curses_window_addch__doc__, PyDoc_STRVAR(curses_window_addch__doc__,
"addch([x, y,] ch, [attr])\n" "addch(self, [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"
" x\n" " x\n"
@ -651,7 +651,7 @@ exit:
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 end generated code: checksum=53d44d79791b30950972b3256bdd464f7426bf82]*/ /*[clinic end generated code: checksum=f6eeada77a9ec085125f3a27e4a2095f2a4c50be]*/
{ {
PyCursesWindowObject *cwself = (PyCursesWindowObject *)self; PyCursesWindowObject *cwself = (PyCursesWindowObject *)self;
int coordinates_group = group_left_1; int coordinates_group = group_left_1;

View File

@ -4159,7 +4159,7 @@ If no tz is specified, uses local timezone.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(datetime_datetime_now__doc__, PyDoc_STRVAR(datetime_datetime_now__doc__,
"now(tz=None)\n" "now(type, 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"
" tz\n" " tz\n"
@ -4171,10 +4171,10 @@ PyDoc_STRVAR(datetime_datetime_now__doc__,
{"now", (PyCFunction)datetime_datetime_now, METH_VARARGS|METH_KEYWORDS|METH_CLASS, datetime_datetime_now__doc__}, {"now", (PyCFunction)datetime_datetime_now, METH_VARARGS|METH_KEYWORDS|METH_CLASS, datetime_datetime_now__doc__},
static PyObject * static PyObject *
datetime_datetime_now_impl(PyTypeObject *cls, PyObject *tz); datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz);
static PyObject * static PyObject *
datetime_datetime_now(PyTypeObject *cls, PyObject *args, PyObject *kwargs) datetime_datetime_now(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{ {
PyObject *return_value = NULL; PyObject *return_value = NULL;
static char *_keywords[] = {"tz", NULL}; static char *_keywords[] = {"tz", NULL};
@ -4184,15 +4184,15 @@ datetime_datetime_now(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
"|O:now", _keywords, "|O:now", _keywords,
&tz)) &tz))
goto exit; goto exit;
return_value = datetime_datetime_now_impl(cls, tz); return_value = datetime_datetime_now_impl(type, tz);
exit: exit:
return return_value; return return_value;
} }
static PyObject * static PyObject *
datetime_datetime_now_impl(PyTypeObject *cls, PyObject *tz) datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
/*[clinic end generated code: checksum=ca3d26a423b3f633b260c7622e303f0915a96f7c]*/ /*[clinic end generated code: checksum=a6d3ad2c0ab6389075289af3467f7b8eb13f5f5c]*/
{ {
PyObject *self; PyObject *self;
@ -4202,7 +4202,7 @@ datetime_datetime_now_impl(PyTypeObject *cls, PyObject *tz)
if (check_tzinfo_subclass(tz) < 0) if (check_tzinfo_subclass(tz) < 0)
return NULL; return NULL;
self = datetime_best_possible((PyObject *)cls, self = datetime_best_possible((PyObject *)type,
tz == Py_None ? localtime : gmtime, tz == Py_None ? localtime : gmtime,
tz); tz);
if (self != NULL && tz != Py_None) { if (self != NULL && tz != Py_None) {

View File

@ -279,7 +279,7 @@ Return the value for key if present, otherwise default.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(dbm_dbm_get__doc__, PyDoc_STRVAR(dbm_dbm_get__doc__,
"get(key, [default])\n" "get(self, key, [default])\n"
"Return the value for key if present, otherwise default."); "Return the value for key if present, otherwise default.");
#define DBM_DBM_GET_METHODDEF \ #define DBM_DBM_GET_METHODDEF \
@ -289,7 +289,7 @@ 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);
static PyObject * static PyObject *
dbm_dbm_get(PyObject *self, PyObject *args) dbm_dbm_get(dbmobject *dp, PyObject *args)
{ {
PyObject *return_value = NULL; PyObject *return_value = NULL;
const char *key; const char *key;
@ -311,7 +311,7 @@ dbm_dbm_get(PyObject *self, PyObject *args)
PyErr_SetString(PyExc_TypeError, "dbm.dbm.get requires 1 to 2 arguments"); PyErr_SetString(PyExc_TypeError, "dbm.dbm.get requires 1 to 2 arguments");
goto exit; goto exit;
} }
return_value = dbm_dbm_get_impl((dbmobject *)self, key, key_length, group_right_1, default_value); return_value = dbm_dbm_get_impl(dp, key, key_length, group_right_1, default_value);
exit: exit:
return return_value; return return_value;
@ -319,7 +319,7 @@ exit:
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 end generated code: checksum=ca8bf63ec226e71d3cf390749777f7d5b7361478]*/ /*[clinic end generated code: checksum=31d5180d6b36f1eafea78ec4391adf3559916379]*/
{ {
datum dbm_key, val; datum dbm_key, val;
@ -462,7 +462,7 @@ Return a database object.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(dbmopen__doc__, PyDoc_STRVAR(dbmopen__doc__,
"open(filename, flags=\'r\', mode=0o666)\n" "open(module, filename, flags=\'r\', mode=0o666)\n"
"Return a database object.\n" "Return a database object.\n"
"\n" "\n"
" filename\n" " filename\n"
@ -499,7 +499,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 end generated code: checksum=fb265f75641553ccd963f84c143b35c11f9121fc]*/ /*[clinic end generated code: checksum=9efae7d3c3b67a365011bf4e463e918901ba6c79]*/
{ {
int iflags; int iflags;

View File

@ -21,7 +21,7 @@ Compute the stack effect of the opcode.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(_opcode_stack_effect__doc__, PyDoc_STRVAR(_opcode_stack_effect__doc__,
"stack_effect(opcode, [oparg])\n" "stack_effect(module, opcode, [oparg])\n"
"Compute the stack effect of the opcode."); "Compute the stack effect of the opcode.");
#define _OPCODE_STACK_EFFECT_METHODDEF \ #define _OPCODE_STACK_EFFECT_METHODDEF \
@ -64,7 +64,7 @@ exit:
static int static int
_opcode_stack_effect_impl(PyModuleDef *module, int opcode, int group_right_1, int oparg) _opcode_stack_effect_impl(PyModuleDef *module, int opcode, int group_right_1, int oparg)
/*[clinic end generated code: checksum=58fb4f1b174fc92f783dc945ca712fb752a6c283]*/ /*[clinic end generated code: checksum=4689140ffda2494a123ea2593fb63445fb039774]*/
{ {
int effect; int effect;
if (HAS_ARG(opcode)) { if (HAS_ARG(opcode)) {

View File

@ -3889,7 +3889,7 @@ re-using picklers.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(_pickle_Pickler_clear_memo__doc__, PyDoc_STRVAR(_pickle_Pickler_clear_memo__doc__,
"clear_memo()\n" "clear_memo(self)\n"
"Clears the pickler\'s \"memo\".\n" "Clears the pickler\'s \"memo\".\n"
"\n" "\n"
"The memo is the data structure that remembers which objects the\n" "The memo is the data structure that remembers which objects the\n"
@ -3904,14 +3904,14 @@ static PyObject *
_pickle_Pickler_clear_memo_impl(PicklerObject *self); _pickle_Pickler_clear_memo_impl(PicklerObject *self);
static PyObject * static PyObject *
_pickle_Pickler_clear_memo(PyObject *self, PyObject *Py_UNUSED(ignored)) _pickle_Pickler_clear_memo(PicklerObject *self, PyObject *Py_UNUSED(ignored))
{ {
return _pickle_Pickler_clear_memo_impl((PicklerObject *)self); return _pickle_Pickler_clear_memo_impl(self);
} }
static PyObject * static PyObject *
_pickle_Pickler_clear_memo_impl(PicklerObject *self) _pickle_Pickler_clear_memo_impl(PicklerObject *self)
/*[clinic end generated code: checksum=015cc3c5befea86cb08b9396938477bebbea4157]*/ /*[clinic end generated code: checksum=17b1165d8dcae5a2e90b1703bf5cbbfc26114c5a]*/
{ {
if (self->memo) if (self->memo)
PyMemoTable_Clear(self->memo); PyMemoTable_Clear(self->memo);
@ -3931,7 +3931,7 @@ Write a pickled representation of the given object to the open file.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(_pickle_Pickler_dump__doc__, PyDoc_STRVAR(_pickle_Pickler_dump__doc__,
"dump(obj)\n" "dump(self, obj)\n"
"Write a pickled representation of the given object to the open file."); "Write a pickled representation of the given object to the open file.");
#define _PICKLE_PICKLER_DUMP_METHODDEF \ #define _PICKLE_PICKLER_DUMP_METHODDEF \
@ -3939,7 +3939,7 @@ PyDoc_STRVAR(_pickle_Pickler_dump__doc__,
static PyObject * static PyObject *
_pickle_Pickler_dump(PicklerObject *self, PyObject *obj) _pickle_Pickler_dump(PicklerObject *self, PyObject *obj)
/*[clinic end generated code: checksum=b72a69ec98737fabf66dae7c5a3210178bdbd3e6]*/ /*[clinic end generated code: checksum=36db7f67c8bc05ca6f17b8ab57c54d64bfd0539e]*/
{ {
/* Check whether the Pickler was initialized correctly (issue3664). /* Check whether the Pickler was initialized correctly (issue3664).
Developers often forget to call __init__() in their subclasses, which Developers often forget to call __init__() in their subclasses, which
@ -4077,7 +4077,7 @@ _pickle_Pickler___init__(PyObject *self, PyObject *args, PyObject *kwargs)
int fix_imports = 1; int fix_imports = 1;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"O|Op:__init__", _keywords, "O|Op:Pickler", _keywords,
&file, &protocol, &fix_imports)) &file, &protocol, &fix_imports))
goto exit; goto exit;
return_value = _pickle_Pickler___init___impl((PicklerObject *)self, file, protocol, fix_imports); return_value = _pickle_Pickler___init___impl((PicklerObject *)self, file, protocol, fix_imports);
@ -4088,7 +4088,7 @@ exit:
static int static int
_pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, PyObject *protocol, int fix_imports) _pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, PyObject *protocol, int fix_imports)
/*[clinic end generated code: checksum=d10dfb463511430b4faad9fca07627041a35b96e]*/ /*[clinic end generated code: checksum=b055bf46cfb5b92c1863302d075246a68bd89153]*/
{ {
_Py_IDENTIFIER(persistent_id); _Py_IDENTIFIER(persistent_id);
_Py_IDENTIFIER(dispatch_table); _Py_IDENTIFIER(dispatch_table);
@ -4164,7 +4164,7 @@ Remove all items from memo.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(_pickle_PicklerMemoProxy_clear__doc__, PyDoc_STRVAR(_pickle_PicklerMemoProxy_clear__doc__,
"clear()\n" "clear(self)\n"
"Remove all items from memo."); "Remove all items from memo.");
#define _PICKLE_PICKLERMEMOPROXY_CLEAR_METHODDEF \ #define _PICKLE_PICKLERMEMOPROXY_CLEAR_METHODDEF \
@ -4174,14 +4174,14 @@ static PyObject *
_pickle_PicklerMemoProxy_clear_impl(PicklerMemoProxyObject *self); _pickle_PicklerMemoProxy_clear_impl(PicklerMemoProxyObject *self);
static PyObject * static PyObject *
_pickle_PicklerMemoProxy_clear(PyObject *self, PyObject *Py_UNUSED(ignored)) _pickle_PicklerMemoProxy_clear(PicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored))
{ {
return _pickle_PicklerMemoProxy_clear_impl((PicklerMemoProxyObject *)self); return _pickle_PicklerMemoProxy_clear_impl(self);
} }
static PyObject * static PyObject *
_pickle_PicklerMemoProxy_clear_impl(PicklerMemoProxyObject *self) _pickle_PicklerMemoProxy_clear_impl(PicklerMemoProxyObject *self)
/*[clinic end generated code: checksum=bf8dd8c8688d0c0f7a2e59a804c47375b740f2f0]*/ /*[clinic end generated code: checksum=fb4a5ba40918b3eccc9bc1e9d6875cb2737127a9]*/
{ {
if (self->pickler->memo) if (self->pickler->memo)
PyMemoTable_Clear(self->pickler->memo); PyMemoTable_Clear(self->pickler->memo);
@ -4197,7 +4197,7 @@ Copy the memo to a new object.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(_pickle_PicklerMemoProxy_copy__doc__, PyDoc_STRVAR(_pickle_PicklerMemoProxy_copy__doc__,
"copy()\n" "copy(self)\n"
"Copy the memo to a new object."); "Copy the memo to a new object.");
#define _PICKLE_PICKLERMEMOPROXY_COPY_METHODDEF \ #define _PICKLE_PICKLERMEMOPROXY_COPY_METHODDEF \
@ -4207,14 +4207,14 @@ static PyObject *
_pickle_PicklerMemoProxy_copy_impl(PicklerMemoProxyObject *self); _pickle_PicklerMemoProxy_copy_impl(PicklerMemoProxyObject *self);
static PyObject * static PyObject *
_pickle_PicklerMemoProxy_copy(PyObject *self, PyObject *Py_UNUSED(ignored)) _pickle_PicklerMemoProxy_copy(PicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored))
{ {
return _pickle_PicklerMemoProxy_copy_impl((PicklerMemoProxyObject *)self); return _pickle_PicklerMemoProxy_copy_impl(self);
} }
static PyObject * static PyObject *
_pickle_PicklerMemoProxy_copy_impl(PicklerMemoProxyObject *self) _pickle_PicklerMemoProxy_copy_impl(PicklerMemoProxyObject *self)
/*[clinic end generated code: checksum=72d46879dc658adbd3d28b5c82dd8dcfa6b9b124]*/ /*[clinic end generated code: checksum=3d27d3005725f1828c9a92a38197811c54c64abb]*/
{ {
Py_ssize_t i; Py_ssize_t i;
PyMemoTable *memo; PyMemoTable *memo;
@ -4260,7 +4260,7 @@ Implement pickle support.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(_pickle_PicklerMemoProxy___reduce____doc__, PyDoc_STRVAR(_pickle_PicklerMemoProxy___reduce____doc__,
"__reduce__()\n" "__reduce__(self)\n"
"Implement pickle support."); "Implement pickle support.");
#define _PICKLE_PICKLERMEMOPROXY___REDUCE___METHODDEF \ #define _PICKLE_PICKLERMEMOPROXY___REDUCE___METHODDEF \
@ -4270,14 +4270,14 @@ static PyObject *
_pickle_PicklerMemoProxy___reduce___impl(PicklerMemoProxyObject *self); _pickle_PicklerMemoProxy___reduce___impl(PicklerMemoProxyObject *self);
static PyObject * static PyObject *
_pickle_PicklerMemoProxy___reduce__(PyObject *self, PyObject *Py_UNUSED(ignored)) _pickle_PicklerMemoProxy___reduce__(PicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored))
{ {
return _pickle_PicklerMemoProxy___reduce___impl((PicklerMemoProxyObject *)self); return _pickle_PicklerMemoProxy___reduce___impl(self);
} }
static PyObject * static PyObject *
_pickle_PicklerMemoProxy___reduce___impl(PicklerMemoProxyObject *self) _pickle_PicklerMemoProxy___reduce___impl(PicklerMemoProxyObject *self)
/*[clinic end generated code: checksum=aad71c4d81d1ed8bf0d32362dd80a29b9f3b0d03]*/ /*[clinic end generated code: checksum=2682cf8a3a5027def6328419001b086b047d47c8]*/
{ {
PyObject *reduce_value, *dict_args; PyObject *reduce_value, *dict_args;
PyObject *contents = _pickle_PicklerMemoProxy_copy_impl(self); PyObject *contents = _pickle_PicklerMemoProxy_copy_impl(self);
@ -6299,7 +6299,7 @@ specified therein.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(_pickle_Unpickler_load__doc__, PyDoc_STRVAR(_pickle_Unpickler_load__doc__,
"load()\n" "load(self)\n"
"Load a pickle.\n" "Load a pickle.\n"
"\n" "\n"
"Read a pickled object representation from the open file object given\n" "Read a pickled object representation from the open file object given\n"
@ -6320,7 +6320,7 @@ _pickle_Unpickler_load(PyObject *self, PyObject *Py_UNUSED(ignored))
static PyObject * static PyObject *
_pickle_Unpickler_load_impl(PyObject *self) _pickle_Unpickler_load_impl(PyObject *self)
/*[clinic end generated code: checksum=9477099fe6a90748c13ff1a6dd92ba7ab7a89602]*/ /*[clinic end generated code: checksum=fb1119422c5e03045d690d1cd6c457f1ca4c585d]*/
{ {
UnpicklerObject *unpickler = (UnpicklerObject*)self; UnpicklerObject *unpickler = (UnpicklerObject*)self;
@ -6363,7 +6363,7 @@ needed. Both arguments passed are str objects.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(_pickle_Unpickler_find_class__doc__, PyDoc_STRVAR(_pickle_Unpickler_find_class__doc__,
"find_class(module_name, global_name)\n" "find_class(self, module_name, global_name)\n"
"Return an object from a specified module.\n" "Return an object from a specified module.\n"
"\n" "\n"
"If necessary, the module will be imported. Subclasses may override\n" "If necessary, the module will be imported. Subclasses may override\n"
@ -6380,7 +6380,7 @@ static PyObject *
_pickle_Unpickler_find_class_impl(UnpicklerObject *self, PyObject *module_name, PyObject *global_name); _pickle_Unpickler_find_class_impl(UnpicklerObject *self, PyObject *module_name, PyObject *global_name);
static PyObject * static PyObject *
_pickle_Unpickler_find_class(PyObject *self, PyObject *args) _pickle_Unpickler_find_class(UnpicklerObject *self, PyObject *args)
{ {
PyObject *return_value = NULL; PyObject *return_value = NULL;
PyObject *module_name; PyObject *module_name;
@ -6390,7 +6390,7 @@ _pickle_Unpickler_find_class(PyObject *self, PyObject *args)
2, 2, 2, 2,
&module_name, &global_name)) &module_name, &global_name))
goto exit; goto exit;
return_value = _pickle_Unpickler_find_class_impl((UnpicklerObject *)self, module_name, global_name); return_value = _pickle_Unpickler_find_class_impl(self, module_name, global_name);
exit: exit:
return return_value; return return_value;
@ -6398,7 +6398,7 @@ exit:
static PyObject * static PyObject *
_pickle_Unpickler_find_class_impl(UnpicklerObject *self, PyObject *module_name, PyObject *global_name) _pickle_Unpickler_find_class_impl(UnpicklerObject *self, PyObject *module_name, PyObject *global_name)
/*[clinic end generated code: checksum=15ed4836fd5860425fff9ea7855d4f1f4413c170]*/ /*[clinic end generated code: checksum=2b8d5398787c8ac7ea5d45f644433169e441003b]*/
{ {
PyObject *global; PyObject *global;
PyObject *modules_dict; PyObject *modules_dict;
@ -6617,7 +6617,7 @@ _pickle_Unpickler___init__(PyObject *self, PyObject *args, PyObject *kwargs)
const char *errors = "strict"; const char *errors = "strict";
if (!PyArg_ParseTupleAndKeywords(args, kwargs, if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"O|$pss:__init__", _keywords, "O|$pss:Unpickler", _keywords,
&file, &fix_imports, &encoding, &errors)) &file, &fix_imports, &encoding, &errors))
goto exit; goto exit;
return_value = _pickle_Unpickler___init___impl((UnpicklerObject *)self, file, fix_imports, encoding, errors); return_value = _pickle_Unpickler___init___impl((UnpicklerObject *)self, file, fix_imports, encoding, errors);
@ -6628,7 +6628,7 @@ exit:
static int static int
_pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file, int fix_imports, const char *encoding, const char *errors) _pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file, int fix_imports, const char *encoding, const char *errors)
/*[clinic end generated code: checksum=eb1a2cfc7b6f97c33980cff3d3b97d184a382f02]*/ /*[clinic end generated code: checksum=a8a9dde29eb4ddd538b45099408ea77e01940692]*/
{ {
_Py_IDENTIFIER(persistent_load); _Py_IDENTIFIER(persistent_load);
@ -6698,7 +6698,7 @@ Remove all items from memo.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(_pickle_UnpicklerMemoProxy_clear__doc__, PyDoc_STRVAR(_pickle_UnpicklerMemoProxy_clear__doc__,
"clear()\n" "clear(self)\n"
"Remove all items from memo."); "Remove all items from memo.");
#define _PICKLE_UNPICKLERMEMOPROXY_CLEAR_METHODDEF \ #define _PICKLE_UNPICKLERMEMOPROXY_CLEAR_METHODDEF \
@ -6708,14 +6708,14 @@ static PyObject *
_pickle_UnpicklerMemoProxy_clear_impl(UnpicklerMemoProxyObject *self); _pickle_UnpicklerMemoProxy_clear_impl(UnpicklerMemoProxyObject *self);
static PyObject * static PyObject *
_pickle_UnpicklerMemoProxy_clear(PyObject *self, PyObject *Py_UNUSED(ignored)) _pickle_UnpicklerMemoProxy_clear(UnpicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored))
{ {
return _pickle_UnpicklerMemoProxy_clear_impl((UnpicklerMemoProxyObject *)self); return _pickle_UnpicklerMemoProxy_clear_impl(self);
} }
static PyObject * static PyObject *
_pickle_UnpicklerMemoProxy_clear_impl(UnpicklerMemoProxyObject *self) _pickle_UnpicklerMemoProxy_clear_impl(UnpicklerMemoProxyObject *self)
/*[clinic end generated code: checksum=07adecee2181e5e268b2ff184360b1d88ad947f2]*/ /*[clinic end generated code: checksum=32f6ee47e44405dd587f768f3690d47947bb5a8e]*/
{ {
_Unpickler_MemoCleanup(self->unpickler); _Unpickler_MemoCleanup(self->unpickler);
self->unpickler->memo = _Unpickler_NewMemo(self->unpickler->memo_size); self->unpickler->memo = _Unpickler_NewMemo(self->unpickler->memo_size);
@ -6733,7 +6733,7 @@ Copy the memo to a new object.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(_pickle_UnpicklerMemoProxy_copy__doc__, PyDoc_STRVAR(_pickle_UnpicklerMemoProxy_copy__doc__,
"copy()\n" "copy(self)\n"
"Copy the memo to a new object."); "Copy the memo to a new object.");
#define _PICKLE_UNPICKLERMEMOPROXY_COPY_METHODDEF \ #define _PICKLE_UNPICKLERMEMOPROXY_COPY_METHODDEF \
@ -6743,14 +6743,14 @@ static PyObject *
_pickle_UnpicklerMemoProxy_copy_impl(UnpicklerMemoProxyObject *self); _pickle_UnpicklerMemoProxy_copy_impl(UnpicklerMemoProxyObject *self);
static PyObject * static PyObject *
_pickle_UnpicklerMemoProxy_copy(PyObject *self, PyObject *Py_UNUSED(ignored)) _pickle_UnpicklerMemoProxy_copy(UnpicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored))
{ {
return _pickle_UnpicklerMemoProxy_copy_impl((UnpicklerMemoProxyObject *)self); return _pickle_UnpicklerMemoProxy_copy_impl(self);
} }
static PyObject * static PyObject *
_pickle_UnpicklerMemoProxy_copy_impl(UnpicklerMemoProxyObject *self) _pickle_UnpicklerMemoProxy_copy_impl(UnpicklerMemoProxyObject *self)
/*[clinic end generated code: checksum=47b9f0cc12c5a54004252e1b4916822cdfa8a881]*/ /*[clinic end generated code: checksum=ac3da80efc3b2548aa8b5c5358d0e82e615fce1d]*/
{ {
Py_ssize_t i; Py_ssize_t i;
PyObject *new_memo = PyDict_New(); PyObject *new_memo = PyDict_New();
@ -6789,7 +6789,7 @@ Implement pickling support.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(_pickle_UnpicklerMemoProxy___reduce____doc__, PyDoc_STRVAR(_pickle_UnpicklerMemoProxy___reduce____doc__,
"__reduce__()\n" "__reduce__(self)\n"
"Implement pickling support."); "Implement pickling support.");
#define _PICKLE_UNPICKLERMEMOPROXY___REDUCE___METHODDEF \ #define _PICKLE_UNPICKLERMEMOPROXY___REDUCE___METHODDEF \
@ -6799,14 +6799,14 @@ static PyObject *
_pickle_UnpicklerMemoProxy___reduce___impl(UnpicklerMemoProxyObject *self); _pickle_UnpicklerMemoProxy___reduce___impl(UnpicklerMemoProxyObject *self);
static PyObject * static PyObject *
_pickle_UnpicklerMemoProxy___reduce__(PyObject *self, PyObject *Py_UNUSED(ignored)) _pickle_UnpicklerMemoProxy___reduce__(UnpicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored))
{ {
return _pickle_UnpicklerMemoProxy___reduce___impl((UnpicklerMemoProxyObject *)self); return _pickle_UnpicklerMemoProxy___reduce___impl(self);
} }
static PyObject * static PyObject *
_pickle_UnpicklerMemoProxy___reduce___impl(UnpicklerMemoProxyObject *self) _pickle_UnpicklerMemoProxy___reduce___impl(UnpicklerMemoProxyObject *self)
/*[clinic end generated code: checksum=2f061bb9ecd9ee8500184c135148a131c46a3b88]*/ /*[clinic end generated code: checksum=2373102b7c87d99ba4c4a56b6813d2c84dd61865]*/
{ {
PyObject *reduce_value; PyObject *reduce_value;
PyObject *constructor_args; PyObject *constructor_args;
@ -7115,7 +7115,7 @@ to map the new Python 3 names to the old module names used in Python
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(_pickle_dump__doc__, PyDoc_STRVAR(_pickle_dump__doc__,
"dump(obj, file, protocol=None, *, fix_imports=True)\n" "dump(module, obj, file, protocol=None, *, fix_imports=True)\n"
"Write a pickled representation of obj to the open file object file.\n" "Write a pickled representation of obj to the open file object file.\n"
"\n" "\n"
"This is equivalent to ``Pickler(file, protocol).dump(obj)``, but may\n" "This is equivalent to ``Pickler(file, protocol).dump(obj)``, but may\n"
@ -7166,7 +7166,7 @@ exit:
static PyObject * static PyObject *
_pickle_dump_impl(PyModuleDef *module, PyObject *obj, PyObject *file, PyObject *protocol, int fix_imports) _pickle_dump_impl(PyModuleDef *module, PyObject *obj, PyObject *file, PyObject *protocol, int fix_imports)
/*[clinic end generated code: checksum=eb5c23e64da34477178230b704d2cc9c6b6650ea]*/ /*[clinic end generated code: checksum=1d4ff873e13eb840ff275d716d8d4c5554af087c]*/
{ {
PicklerObject *pickler = _Pickler_New(); PicklerObject *pickler = _Pickler_New();
@ -7218,7 +7218,7 @@ Python 2, so that the pickle data stream is readable with Python 2.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(_pickle_dumps__doc__, PyDoc_STRVAR(_pickle_dumps__doc__,
"dumps(obj, protocol=None, *, fix_imports=True)\n" "dumps(module, obj, protocol=None, *, fix_imports=True)\n"
"Return the pickled representation of the object as a bytes object.\n" "Return the pickled representation of the object as a bytes object.\n"
"\n" "\n"
"The optional *protocol* argument tells the pickler to use the given\n" "The optional *protocol* argument tells the pickler to use the given\n"
@ -7260,7 +7260,7 @@ exit:
static PyObject * static PyObject *
_pickle_dumps_impl(PyModuleDef *module, PyObject *obj, PyObject *protocol, int fix_imports) _pickle_dumps_impl(PyModuleDef *module, PyObject *obj, PyObject *protocol, int fix_imports)
/*[clinic end generated code: checksum=e9b915d61202a9692cb6c6718db74fe54fc9c4d1]*/ /*[clinic end generated code: checksum=9c6c0291ef2d2b0856b7d4caecdcb7bad13a23b3]*/
{ {
PyObject *result; PyObject *result;
PicklerObject *pickler = _Pickler_New(); PicklerObject *pickler = _Pickler_New();
@ -7319,7 +7319,7 @@ string instances as bytes objects.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(_pickle_load__doc__, PyDoc_STRVAR(_pickle_load__doc__,
"load(file, *, fix_imports=True, encoding=\'ASCII\', errors=\'strict\')\n" "load(module, file, *, fix_imports=True, encoding=\'ASCII\', errors=\'strict\')\n"
"Read and return an object from the pickle data stored in a file.\n" "Read and return an object from the pickle data stored in a file.\n"
"\n" "\n"
"This is equivalent to ``Unpickler(file).load()``, but may be more\n" "This is equivalent to ``Unpickler(file).load()``, but may be more\n"
@ -7372,7 +7372,7 @@ exit:
static PyObject * static PyObject *
_pickle_load_impl(PyModuleDef *module, PyObject *file, int fix_imports, const char *encoding, const char *errors) _pickle_load_impl(PyModuleDef *module, PyObject *file, int fix_imports, const char *encoding, const char *errors)
/*[clinic end generated code: checksum=b41f06970e57acf2fd602e4b7f88e3f3e1e53087]*/ /*[clinic end generated code: checksum=2b5b7e5e3a836cf1c53377ce9274a84a8bceef67]*/
{ {
PyObject *result; PyObject *result;
UnpicklerObject *unpickler = _Unpickler_New(); UnpicklerObject *unpickler = _Unpickler_New();
@ -7424,7 +7424,7 @@ string instances as bytes objects.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(_pickle_loads__doc__, PyDoc_STRVAR(_pickle_loads__doc__,
"loads(data, *, fix_imports=True, encoding=\'ASCII\', errors=\'strict\')\n" "loads(module, data, *, fix_imports=True, encoding=\'ASCII\', errors=\'strict\')\n"
"Read and return an object from the given pickle data.\n" "Read and return an object from the given pickle data.\n"
"\n" "\n"
"The protocol version of the pickle is detected automatically, so no\n" "The protocol version of the pickle is detected automatically, so no\n"
@ -7468,7 +7468,7 @@ exit:
static PyObject * static PyObject *
_pickle_loads_impl(PyModuleDef *module, PyObject *data, int fix_imports, const char *encoding, const char *errors) _pickle_loads_impl(PyModuleDef *module, PyObject *data, int fix_imports, const char *encoding, const char *errors)
/*[clinic end generated code: checksum=0663de43aca6c21508a777e29d98c9c3a6e7f72d]*/ /*[clinic end generated code: checksum=7b21a75997c8f6636e4bf48c663b28f2bfd4eb6a]*/
{ {
PyObject *result; PyObject *result;
UnpicklerObject *unpickler = _Unpickler_New(); UnpicklerObject *unpickler = _Unpickler_New();

View File

@ -541,7 +541,7 @@ Matches zero or more characters at the beginning of the string.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(pattern_match__doc__, PyDoc_STRVAR(pattern_match__doc__,
"match(pattern, pos=0, endpos=sys.maxsize)\n" "match(self, pattern, pos=0, endpos=sys.maxsize)\n"
"Matches zero or more characters at the beginning of the string."); "Matches zero or more characters at the beginning of the string.");
#define PATTERN_MATCH_METHODDEF \ #define PATTERN_MATCH_METHODDEF \
@ -551,7 +551,7 @@ static PyObject *
pattern_match_impl(PatternObject *self, PyObject *pattern, Py_ssize_t pos, Py_ssize_t endpos); pattern_match_impl(PatternObject *self, PyObject *pattern, Py_ssize_t pos, Py_ssize_t endpos);
static PyObject * static PyObject *
pattern_match(PyObject *self, PyObject *args, PyObject *kwargs) pattern_match(PatternObject *self, PyObject *args, PyObject *kwargs)
{ {
PyObject *return_value = NULL; PyObject *return_value = NULL;
static char *_keywords[] = {"pattern", "pos", "endpos", NULL}; static char *_keywords[] = {"pattern", "pos", "endpos", NULL};
@ -563,7 +563,7 @@ pattern_match(PyObject *self, PyObject *args, PyObject *kwargs)
"O|nn:match", _keywords, "O|nn:match", _keywords,
&pattern, &pos, &endpos)) &pattern, &pos, &endpos))
goto exit; goto exit;
return_value = pattern_match_impl((PatternObject *)self, pattern, pos, endpos); return_value = pattern_match_impl(self, pattern, pos, endpos);
exit: exit:
return return_value; return return_value;
@ -571,7 +571,7 @@ exit:
static PyObject * static PyObject *
pattern_match_impl(PatternObject *self, PyObject *pattern, Py_ssize_t pos, Py_ssize_t endpos) pattern_match_impl(PatternObject *self, PyObject *pattern, Py_ssize_t pos, Py_ssize_t endpos)
/*[clinic end generated code: checksum=63e59c5f3019efe6c1f3acdec42b2d3595e14a09]*/ /*[clinic end generated code: checksum=4a3865d13638cb7c13dcae1fe58c1a9c35071998]*/
{ {
SRE_STATE state; SRE_STATE state;
Py_ssize_t status; Py_ssize_t status;

View File

@ -2851,18 +2851,18 @@ PyDoc_STRVAR(docstring_no_signature,
); );
PyDoc_STRVAR(docstring_with_invalid_signature, PyDoc_STRVAR(docstring_with_invalid_signature,
"docstring_with_invalid_signature (boo)\n" "docstring_with_invalid_signature (module, boo)\n"
"\n" "\n"
"This docstring has an invalid signature." "This docstring has an invalid signature."
); );
PyDoc_STRVAR(docstring_with_signature, PyDoc_STRVAR(docstring_with_signature,
"docstring_with_signature(sig)\n" "docstring_with_signature(module, sig)\n"
"This docstring has a valid signature." "This docstring has a valid signature."
); );
PyDoc_STRVAR(docstring_with_signature_and_extra_newlines, PyDoc_STRVAR(docstring_with_signature_and_extra_newlines,
"docstring_with_signature_and_extra_newlines(parameter)\n" "docstring_with_signature_and_extra_newlines(module, parameter)\n"
"\n" "\n"
"\n" "\n"
"\n" "\n"
@ -2870,7 +2870,7 @@ PyDoc_STRVAR(docstring_with_signature_and_extra_newlines,
); );
PyDoc_STRVAR(docstring_with_signature_with_defaults, PyDoc_STRVAR(docstring_with_signature_with_defaults,
"docstring_with_signature_with_defaults(s='avocado', b=b'bytes', d=3.14, i=35, n=None, t=True, f=False, local=the_number_three, sys=sys.maxsize, exp=sys.maxsize - 1)\n" "docstring_with_signature_with_defaults(module, s='avocado', b=b'bytes', d=3.14, i=35, n=None, t=True, f=False, local=the_number_three, sys=sys.maxsize, exp=sys.maxsize - 1)\n"
"\n" "\n"
"\n" "\n"
"\n" "\n"

View File

@ -20,7 +20,7 @@ Return the number of weak references to 'object'.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(_weakref_getweakrefcount__doc__, PyDoc_STRVAR(_weakref_getweakrefcount__doc__,
"getweakrefcount(object)\n" "getweakrefcount(module, object)\n"
"Return the number of weak references to \'object\'."); "Return the number of weak references to \'object\'.");
#define _WEAKREF_GETWEAKREFCOUNT_METHODDEF \ #define _WEAKREF_GETWEAKREFCOUNT_METHODDEF \
@ -46,7 +46,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 end generated code: checksum=744fa73ba68c0ee89567e9cb9bea11863270d516]*/ /*[clinic end generated code: checksum=dd8ba0730babf263d3db78d260ea7eacf6eb3735]*/
{ {
PyWeakReference **list; PyWeakReference **list;

View File

@ -2430,7 +2430,7 @@ It's an error to use dir_fd or follow_symlinks when specifying path as
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(os_stat__doc__, PyDoc_STRVAR(os_stat__doc__,
"stat(path, *, dir_fd=None, follow_symlinks=True)\n" "stat(module, 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"
" path\n" " path\n"
@ -2481,7 +2481,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 end generated code: checksum=85a71ad602e89f8e280118da976f70cd2f9abdf1]*/ /*[clinic end generated code: checksum=09cc91b4947f9e3b9335c8be998bb7c56f7f8b40]*/
{ {
return posix_do_stat("stat", path, dir_fd, follow_symlinks); return posix_do_stat("stat", path, dir_fd, follow_symlinks);
} }
@ -2562,7 +2562,7 @@ Note that most operations will use the effective uid/gid, therefore this
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(os_access__doc__, PyDoc_STRVAR(os_access__doc__,
"access(path, mode, *, dir_fd=None, effective_ids=False, follow_symlinks=True)\n" "access(module, 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"
" path\n" " path\n"
@ -2622,7 +2622,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 end generated code: checksum=636e835c36562a2fc11acab75314634127fdf769]*/ /*[clinic end generated code: checksum=6483a51e1fee83da4f8e41cbc8054a701cfed1c5]*/
{ {
PyObject *return_value = NULL; PyObject *return_value = NULL;
@ -2718,7 +2718,7 @@ Return the name of the terminal device connected to 'fd'.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(os_ttyname__doc__, PyDoc_STRVAR(os_ttyname__doc__,
"ttyname(fd)\n" "ttyname(module, 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"
" fd\n" " fd\n"
@ -2752,7 +2752,7 @@ exit:
static char * static char *
os_ttyname_impl(PyModuleDef *module, int fd) os_ttyname_impl(PyModuleDef *module, int fd)
/*[clinic end generated code: checksum=0f368134dc0a7f21f25185e2e6bacf7675fb473a]*/ /*[clinic end generated code: checksum=11bbb8b7969155f54bb8a1ec35ac1ebdfd4b0fec]*/
{ {
char *ret; char *ret;

View File

@ -129,7 +129,7 @@ not given, ValueError is raised.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(unicodedata_UCD_decimal__doc__, PyDoc_STRVAR(unicodedata_UCD_decimal__doc__,
"decimal(unichr, default=None)\n" "decimal(self, 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"
"Returns the decimal value assigned to the Unicode character unichr\n" "Returns the decimal value assigned to the Unicode character unichr\n"
@ -161,7 +161,7 @@ exit:
static PyObject * static PyObject *
unicodedata_UCD_decimal_impl(PyObject *self, PyUnicodeObject *unichr, PyObject *default_value) unicodedata_UCD_decimal_impl(PyObject *self, PyUnicodeObject *unichr, PyObject *default_value)
/*[clinic end generated code: checksum=73edde0e9cd5913ea174c4fa81504369761b7426]*/ /*[clinic end generated code: checksum=01826b179d497d8fd3842c56679ecbd4faddaa95]*/
{ {
PyUnicodeObject *v = (PyUnicodeObject *)unichr; PyUnicodeObject *v = (PyUnicodeObject *)unichr;
int have_old = 0; int have_old = 0;

View File

@ -180,7 +180,7 @@ Returns compressed string.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(zlib_compress__doc__, PyDoc_STRVAR(zlib_compress__doc__,
"compress(bytes, [level])\n" "compress(module, bytes, [level])\n"
"Returns compressed string.\n" "Returns compressed string.\n"
"\n" "\n"
" bytes\n" " bytes\n"
@ -228,7 +228,7 @@ exit:
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 end generated code: checksum=74648f97e6b9d3cc9cd568d47262d462bded7ed0]*/ /*[clinic end generated code: checksum=ce8d4c0a17ecd79c3ffcc032dcdf8ac6830ded1e]*/
{ {
PyObject *ReturnVal = NULL; PyObject *ReturnVal = NULL;
Byte *input, *output = NULL; Byte *input, *output = NULL;
@ -766,7 +766,7 @@ Call the flush() method to clear these buffers.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(zlib_Decompress_decompress__doc__, PyDoc_STRVAR(zlib_Decompress_decompress__doc__,
"decompress(data, max_length=0)\n" "decompress(self, 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"
" data\n" " data\n"
@ -787,7 +787,7 @@ static PyObject *
zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, unsigned int max_length); zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, unsigned int max_length);
static PyObject * static PyObject *
zlib_Decompress_decompress(PyObject *self, PyObject *args) zlib_Decompress_decompress(compobject *self, PyObject *args)
{ {
PyObject *return_value = NULL; PyObject *return_value = NULL;
Py_buffer data = {NULL, NULL}; Py_buffer data = {NULL, NULL};
@ -797,7 +797,7 @@ zlib_Decompress_decompress(PyObject *self, PyObject *args)
"y*|O&:decompress", "y*|O&:decompress",
&data, uint_converter, &max_length)) &data, uint_converter, &max_length))
goto exit; goto exit;
return_value = zlib_Decompress_decompress_impl((compobject *)self, &data, max_length); return_value = zlib_Decompress_decompress_impl(self, &data, max_length);
exit: exit:
/* Cleanup for data */ /* Cleanup for data */
@ -809,7 +809,7 @@ exit:
static PyObject * static PyObject *
zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, unsigned int max_length) zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, unsigned int max_length)
/*[clinic end generated code: checksum=e0058024c4a97b411d2e2197791b89fde175f76f]*/ /*[clinic end generated code: checksum=b7fd2e3b23430f57f5a84817189575bc46464901]*/
{ {
int err; int err;
unsigned int old_length, length = DEFAULTALLOC; unsigned int old_length, length = DEFAULTALLOC;
@ -1036,7 +1036,7 @@ Return a copy of the compression object.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(zlib_Compress_copy__doc__, PyDoc_STRVAR(zlib_Compress_copy__doc__,
"copy()\n" "copy(self)\n"
"Return a copy of the compression object."); "Return a copy of the compression object.");
#define ZLIB_COMPRESS_COPY_METHODDEF \ #define ZLIB_COMPRESS_COPY_METHODDEF \
@ -1046,14 +1046,14 @@ static PyObject *
zlib_Compress_copy_impl(compobject *self); zlib_Compress_copy_impl(compobject *self);
static PyObject * static PyObject *
zlib_Compress_copy(PyObject *self, PyObject *Py_UNUSED(ignored)) zlib_Compress_copy(compobject *self, PyObject *Py_UNUSED(ignored))
{ {
return zlib_Compress_copy_impl((compobject *)self); return zlib_Compress_copy_impl(self);
} }
static PyObject * static PyObject *
zlib_Compress_copy_impl(compobject *self) zlib_Compress_copy_impl(compobject *self)
/*[clinic end generated code: checksum=d57a7911deb7940e85a8d7e65af20b6e2df69000]*/ /*[clinic end generated code: checksum=7aa841ad51297eb83250f511a76872e88fdc737e]*/
{ {
compobject *retval = NULL; compobject *retval = NULL;
int err; int err;

View File

@ -353,11 +353,17 @@ wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
static PyObject * static PyObject *
method_get_doc(PyMethodDescrObject *descr, void *closure) method_get_doc(PyMethodDescrObject *descr, void *closure)
{ {
if (descr->d_method->ml_doc == NULL) { const char *name = descr->d_method->ml_name;
Py_INCREF(Py_None); const char *doc = descr->d_method->ml_doc;
return Py_None; return _PyType_GetDocFromInternalDoc(name, doc);
} }
return PyUnicode_FromString(descr->d_method->ml_doc);
static PyObject *
method_get_text_signature(PyMethodDescrObject *descr, void *closure)
{
const char *name = descr->d_method->ml_name;
const char *doc = descr->d_method->ml_doc;
return _PyType_GetTextSignatureFromInternalDoc(name, doc);
} }
static PyObject * static PyObject *
@ -425,6 +431,7 @@ static PyMemberDef descr_members[] = {
static PyGetSetDef method_getset[] = { static PyGetSetDef method_getset[] = {
{"__doc__", (getter)method_get_doc}, {"__doc__", (getter)method_get_doc},
{"__qualname__", (getter)descr_get_qualname}, {"__qualname__", (getter)descr_get_qualname},
{"__text_signature__", (getter)method_get_text_signature},
{0} {0}
}; };
@ -463,16 +470,23 @@ static PyGetSetDef getset_getset[] = {
static PyObject * static PyObject *
wrapperdescr_get_doc(PyWrapperDescrObject *descr, void *closure) wrapperdescr_get_doc(PyWrapperDescrObject *descr, void *closure)
{ {
if (descr->d_base->doc == NULL) { const char *name = descr->d_base->name;
Py_INCREF(Py_None); const char *doc = descr->d_base->doc;
return Py_None; return _PyType_GetDocFromInternalDoc(name, doc);
} }
return PyUnicode_FromString(descr->d_base->doc);
static PyObject *
wrapperdescr_get_text_signature(PyWrapperDescrObject *descr, void *closure)
{
const char *name = descr->d_base->name;
const char *doc = descr->d_base->doc;
return _PyType_GetTextSignatureFromInternalDoc(name, doc);
} }
static PyGetSetDef wrapperdescr_getset[] = { static PyGetSetDef wrapperdescr_getset[] = {
{"__doc__", (getter)wrapperdescr_get_doc}, {"__doc__", (getter)wrapperdescr_get_doc},
{"__qualname__", (getter)descr_get_qualname}, {"__qualname__", (getter)descr_get_qualname},
{"__text_signature__", (getter)wrapperdescr_get_text_signature},
{0} {0}
}; };
@ -1143,17 +1157,19 @@ wrapper_name(wrapperobject *wp)
} }
static PyObject * static PyObject *
wrapper_doc(wrapperobject *wp) wrapper_doc(wrapperobject *wp, void *closure)
{ {
const char *s = wp->descr->d_base->doc; const char *name = wp->descr->d_base->name;
const char *doc = wp->descr->d_base->doc;
return _PyType_GetDocFromInternalDoc(name, doc);
}
if (s == NULL) { static PyObject *
Py_INCREF(Py_None); wrapper_text_signature(wrapperobject *wp, void *closure)
return Py_None; {
} const char *name = wp->descr->d_base->name;
else { const char *doc = wp->descr->d_base->doc;
return PyUnicode_FromString(s); return _PyType_GetTextSignatureFromInternalDoc(name, doc);
}
} }
static PyObject * static PyObject *
@ -1167,6 +1183,7 @@ static PyGetSetDef wrapper_getsets[] = {
{"__name__", (getter)wrapper_name}, {"__name__", (getter)wrapper_name},
{"__qualname__", (getter)wrapper_qualname}, {"__qualname__", (getter)wrapper_qualname},
{"__doc__", (getter)wrapper_doc}, {"__doc__", (getter)wrapper_doc},
{"__text_signature__", (getter)wrapper_text_signature},
{0} {0}
}; };

View File

@ -1691,37 +1691,71 @@ dict_items(PyDictObject *mp)
return v; return v;
} }
/*[clinic input]
@classmethod
dict.fromkeys
iterable: object
value: object=None
/
Returns a new dict with keys from iterable and values equal to value.
[clinic start generated code]*/
PyDoc_STRVAR(dict_fromkeys__doc__,
"fromkeys(type, iterable, value=None)\n"
"Returns a new dict with keys from iterable and values equal to value.");
#define DICT_FROMKEYS_METHODDEF \
{"fromkeys", (PyCFunction)dict_fromkeys, METH_VARARGS|METH_CLASS, dict_fromkeys__doc__},
static PyObject * static PyObject *
dict_fromkeys(PyObject *cls, PyObject *args) dict_fromkeys_impl(PyTypeObject *type, PyObject *iterable, PyObject *value);
static PyObject *
dict_fromkeys(PyTypeObject *type, PyObject *args)
{ {
PyObject *seq; PyObject *return_value = NULL;
PyObject *iterable;
PyObject *value = Py_None; PyObject *value = Py_None;
if (!PyArg_UnpackTuple(args, "fromkeys",
1, 2,
&iterable, &value))
goto exit;
return_value = dict_fromkeys_impl(type, iterable, value);
exit:
return return_value;
}
static PyObject *
dict_fromkeys_impl(PyTypeObject *type, PyObject *iterable, PyObject *value)
/*[clinic end generated code: checksum=008269e1774a379b356841548c04061fd78a9542]*/
{
PyObject *it; /* iter(seq) */ PyObject *it; /* iter(seq) */
PyObject *key; PyObject *key;
PyObject *d; PyObject *d;
int status; int status;
if (!PyArg_UnpackTuple(args, "fromkeys", 1, 2, &seq, &value)) d = PyObject_CallObject((PyObject *)type, NULL);
return NULL;
d = PyObject_CallObject(cls, NULL);
if (d == NULL) if (d == NULL)
return NULL; return NULL;
if (PyDict_CheckExact(d) && ((PyDictObject *)d)->ma_used == 0) { if (PyDict_CheckExact(d) && ((PyDictObject *)d)->ma_used == 0) {
if (PyDict_CheckExact(seq)) { if (PyDict_CheckExact(iterable)) {
PyDictObject *mp = (PyDictObject *)d; PyDictObject *mp = (PyDictObject *)d;
PyObject *oldvalue; PyObject *oldvalue;
Py_ssize_t pos = 0; Py_ssize_t pos = 0;
PyObject *key; PyObject *key;
Py_hash_t hash; Py_hash_t hash;
if (dictresize(mp, Py_SIZE(seq))) { if (dictresize(mp, Py_SIZE(iterable))) {
Py_DECREF(d); Py_DECREF(d);
return NULL; return NULL;
} }
while (_PyDict_Next(seq, &pos, &key, &oldvalue, &hash)) { while (_PyDict_Next(iterable, &pos, &key, &oldvalue, &hash)) {
if (insertdict(mp, key, hash, value)) { if (insertdict(mp, key, hash, value)) {
Py_DECREF(d); Py_DECREF(d);
return NULL; return NULL;
@ -1729,18 +1763,18 @@ dict_fromkeys(PyObject *cls, PyObject *args)
} }
return d; return d;
} }
if (PyAnySet_CheckExact(seq)) { if (PyAnySet_CheckExact(iterable)) {
PyDictObject *mp = (PyDictObject *)d; PyDictObject *mp = (PyDictObject *)d;
Py_ssize_t pos = 0; Py_ssize_t pos = 0;
PyObject *key; PyObject *key;
Py_hash_t hash; Py_hash_t hash;
if (dictresize(mp, PySet_GET_SIZE(seq))) { if (dictresize(mp, PySet_GET_SIZE(iterable))) {
Py_DECREF(d); Py_DECREF(d);
return NULL; return NULL;
} }
while (_PySet_NextEntry(seq, &pos, &key, &hash)) { while (_PySet_NextEntry(iterable, &pos, &key, &hash)) {
if (insertdict(mp, key, hash, value)) { if (insertdict(mp, key, hash, value)) {
Py_DECREF(d); Py_DECREF(d);
return NULL; return NULL;
@ -1750,7 +1784,7 @@ dict_fromkeys(PyObject *cls, PyObject *args)
} }
} }
it = PyObject_GetIter(seq); it = PyObject_GetIter(iterable);
if (it == NULL){ if (it == NULL){
Py_DECREF(d); Py_DECREF(d);
return NULL; return NULL;
@ -2176,7 +2210,7 @@ True if D has a key k, else False.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(dict___contains____doc__, PyDoc_STRVAR(dict___contains____doc__,
"__contains__(key)\n" "__contains__(self, key)\n"
"True if D has a key k, else False."); "True if D has a key k, else False.");
#define DICT___CONTAINS___METHODDEF \ #define DICT___CONTAINS___METHODDEF \
@ -2184,7 +2218,7 @@ PyDoc_STRVAR(dict___contains____doc__,
static PyObject * static PyObject *
dict___contains__(PyObject *self, PyObject *key) dict___contains__(PyObject *self, PyObject *key)
/*[clinic end generated code: checksum=402ddb624ba1e4db764bfdfbbee6c1c59d1a11fa]*/ /*[clinic end generated code: checksum=c4f85a39baac4776c4275ad5f072f7732c5f0806]*/
{ {
register PyDictObject *mp = (PyDictObject *)self; register PyDictObject *mp = (PyDictObject *)self;
Py_hash_t hash; Py_hash_t hash;
@ -2496,10 +2530,6 @@ If E is present and has a .keys() method, then does: for k in E: D[k] = E[k]\n\
If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v\n\ If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v\n\
In either case, this is followed by: for k in F: D[k] = F[k]"); In either case, this is followed by: for k in F: D[k] = F[k]");
PyDoc_STRVAR(fromkeys__doc__,
"dict.fromkeys(S[,v]) -> New dict with keys from S and values equal to v.\n\
v defaults to None.");
PyDoc_STRVAR(clear__doc__, PyDoc_STRVAR(clear__doc__,
"D.clear() -> None. Remove all items from D."); "D.clear() -> None. Remove all items from D.");
@ -2540,8 +2570,7 @@ static PyMethodDef mapp_methods[] = {
values__doc__}, values__doc__},
{"update", (PyCFunction)dict_update, METH_VARARGS | METH_KEYWORDS, {"update", (PyCFunction)dict_update, METH_VARARGS | METH_KEYWORDS,
update__doc__}, update__doc__},
{"fromkeys", (PyCFunction)dict_fromkeys, METH_VARARGS | METH_CLASS, DICT_FROMKEYS_METHODDEF
fromkeys__doc__},
{"clear", (PyCFunction)dict_clear, METH_NOARGS, {"clear", (PyCFunction)dict_clear, METH_NOARGS,
clear__doc__}, clear__doc__},
{"copy", (PyCFunction)dict_copy, METH_NOARGS, {"copy", (PyCFunction)dict_copy, METH_NOARGS,

View File

@ -179,75 +179,20 @@ static PyMethodDef meth_methods[] = {
{NULL, NULL} {NULL, NULL}
}; };
/*
* 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 * static PyObject *
meth_get__text_signature__(PyCFunctionObject *m, void *closure) meth_get__text_signature__(PyCFunctionObject *m, void *closure)
{ {
const char *start = find_signature(m); const char *name = m->m_ml->ml_name;
const char *trace; const char *doc = m->m_ml->ml_doc;
return _PyType_GetTextSignatureFromInternalDoc(name, doc);
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 = find_signature(m); const char *name = m->m_ml->ml_name;
const char *doc = m->m_ml->ml_doc;
if (doc) return _PyType_GetDocFromInternalDoc(name, doc);
doc = skip_eols(skip_signature(doc));
else
doc = m->m_ml->ml_doc;
if (!doc) {
Py_INCREF(Py_None);
return Py_None;
}
return PyUnicode_FromString(doc);
} }
static PyObject * static PyObject *

View File

@ -54,6 +54,83 @@ _Py_IDENTIFIER(builtins);
static PyObject * static PyObject *
slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds); slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
/*
* finds the docstring's introspection signature.
* if present, returns a pointer pointing to the first '('.
* otherwise returns NULL.
*/
static const char *
find_signature(const char *name, const char *doc)
{
size_t length;
if (!doc || !name)
return NULL;
length = strlen(name);
if (strncmp(doc, name, length))
return NULL;
doc += length;
if (*doc != '(')
return NULL;
return doc;
}
/*
* skips to the end of the docstring's instrospection signature.
*/
static const char *
skip_signature(const char *doc)
{
while (*doc && *doc != '\n')
doc++;
return doc;
}
static const char *
skip_eols(const char *trace)
{
while (*trace == '\n')
trace++;
return trace;
}
static const char *
_PyType_DocWithoutSignature(const char *name, const char *internal_doc)
{
const char *signature = find_signature(name, internal_doc);
if (signature)
return skip_eols(skip_signature(signature));
return internal_doc;
}
PyObject *
_PyType_GetDocFromInternalDoc(const char *name, const char *internal_doc)
{
const char *doc = _PyType_DocWithoutSignature(name, internal_doc);
if (!doc) {
Py_INCREF(Py_None);
return Py_None;
}
return PyUnicode_FromString(doc);
}
PyObject *
_PyType_GetTextSignatureFromInternalDoc(const char *name, const char *internal_doc)
{
const char *signature = find_signature(name, internal_doc);
const char *doc;
if (!signature) {
Py_INCREF(Py_None);
return Py_None;
}
doc = skip_signature(signature);
return PyUnicode_FromStringAndSize(signature, doc - signature);
}
unsigned int unsigned int
PyType_ClearCache(void) PyType_ClearCache(void)
{ {
@ -628,8 +705,11 @@ static PyObject *
type_get_doc(PyTypeObject *type, void *context) type_get_doc(PyTypeObject *type, void *context)
{ {
PyObject *result; PyObject *result;
if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE) && type->tp_doc != NULL) if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE) && type->tp_doc != NULL) {
return PyUnicode_FromString(type->tp_doc); const char *name = type->tp_name;
const char *doc = type->tp_doc;
return _PyType_GetDocFromInternalDoc(name, doc);
}
result = _PyDict_GetItemId(type->tp_dict, &PyId___doc__); result = _PyDict_GetItemId(type->tp_dict, &PyId___doc__);
if (result == NULL) { if (result == NULL) {
result = Py_None; result = Py_None;
@ -645,6 +725,14 @@ type_get_doc(PyTypeObject *type, void *context)
return result; return result;
} }
static PyObject *
type_get_text_signature(PyTypeObject *type, void *context)
{
const char *name = type->tp_name;
const char *doc = type->tp_doc;
return _PyType_GetTextSignatureFromInternalDoc(name, doc);
}
static int static int
type_set_doc(PyTypeObject *type, PyObject *value, void *context) type_set_doc(PyTypeObject *type, PyObject *value, void *context)
{ {
@ -691,6 +779,7 @@ static PyGetSetDef type_getsets[] = {
(setter)type_set_abstractmethods, NULL}, (setter)type_set_abstractmethods, NULL},
{"__dict__", (getter)type_dict, NULL, NULL}, {"__dict__", (getter)type_dict, NULL, NULL},
{"__doc__", (getter)type_get_doc, (setter)type_set_doc, NULL}, {"__doc__", (getter)type_get_doc, (setter)type_set_doc, NULL},
{"__text_signature__", (getter)type_get_text_signature, NULL, NULL},
{0} {0}
}; };
@ -2519,13 +2608,14 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
/* need to make a copy of the docstring slot, which usually /* need to make a copy of the docstring slot, which usually
points to a static string literal */ points to a static string literal */
if (slot->slot == Py_tp_doc) { if (slot->slot == Py_tp_doc) {
size_t len = strlen(slot->pfunc)+1; const char *old_doc = _PyType_DocWithoutSignature(spec->name, slot->pfunc);
size_t len = strlen(old_doc)+1;
char *tp_doc = PyObject_MALLOC(len); char *tp_doc = PyObject_MALLOC(len);
if (tp_doc == NULL) { if (tp_doc == NULL) {
PyErr_NoMemory(); PyErr_NoMemory();
goto fail; goto fail;
} }
memcpy(tp_doc, slot->pfunc, len); memcpy(tp_doc, old_doc, len);
type->tp_doc = tp_doc; type->tp_doc = tp_doc;
} }
} }
@ -2909,6 +2999,8 @@ static PyMethodDef type_methods[] = {
}; };
PyDoc_STRVAR(type_doc, PyDoc_STRVAR(type_doc,
/* this text signature cannot be accurate yet. will fix. --larry */
"type(object_or_name, bases, dict)\n"
"type(object) -> the object's type\n" "type(object) -> the object's type\n"
"type(name, bases, dict) -> a new type"); "type(name, bases, dict) -> a new type");
@ -3480,7 +3572,7 @@ _PyObject_GetState(PyObject *obj)
{ {
PyObject **dict; PyObject **dict;
dict = _PyObject_GetDictPtr(obj); dict = _PyObject_GetDictPtr(obj);
/* It is possible that the object's dict is not initialized /* It is possible that the object's dict is not initialized
yet. In this case, we will return None for the state. yet. In this case, we will return None for the state.
We also return None if the dict is empty to make the behavior We also return None if the dict is empty to make the behavior
consistent regardless whether the dict was initialized or not. consistent regardless whether the dict was initialized or not.
@ -3788,7 +3880,7 @@ reduce_4(PyObject *obj)
Py_DECREF(state); Py_DECREF(state);
Py_DECREF(listitems); Py_DECREF(listitems);
Py_DECREF(dictitems); Py_DECREF(dictitems);
return result; return result;
} }
static PyObject * static PyObject *
@ -3813,7 +3905,7 @@ reduce_2(PyObject *obj)
} }
else if (kwargs != NULL) { else if (kwargs != NULL) {
if (PyDict_Size(kwargs) > 0) { if (PyDict_Size(kwargs) > 0) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"must use protocol 4 or greater to copy this " "must use protocol 4 or greater to copy this "
"object; since __getnewargs_ex__ returned " "object; since __getnewargs_ex__ returned "
"keyword arguments."); "keyword arguments.");
@ -4103,8 +4195,8 @@ PyTypeObject PyBaseObject_Type = {
PyObject_GenericGetAttr, /* tp_getattro */ PyObject_GenericGetAttr, /* tp_getattro */
PyObject_GenericSetAttr, /* tp_setattro */ PyObject_GenericSetAttr, /* tp_setattro */
0, /* tp_as_buffer */ 0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
PyDoc_STR("The most base type"), /* tp_doc */ PyDoc_STR("object()\nThe most base type"), /* tp_doc */
0, /* tp_traverse */ 0, /* tp_traverse */
0, /* tp_clear */ 0, /* tp_clear */
object_richcompare, /* tp_richcompare */ object_richcompare, /* tp_richcompare */
@ -4571,7 +4663,8 @@ PyType_Ready(PyTypeObject *type)
*/ */
if (_PyDict_GetItemId(type->tp_dict, &PyId___doc__) == NULL) { if (_PyDict_GetItemId(type->tp_dict, &PyId___doc__) == NULL) {
if (type->tp_doc != NULL) { if (type->tp_doc != NULL) {
PyObject *doc = PyUnicode_FromString(type->tp_doc); const char *old_doc = _PyType_DocWithoutSignature(type->tp_name, type->tp_doc);
PyObject *doc = PyUnicode_FromString(old_doc);
if (doc == NULL) if (doc == NULL)
goto error; goto error;
if (_PyDict_SetItemId(type->tp_dict, &PyId___doc__, doc) < 0) { if (_PyDict_SetItemId(type->tp_dict, &PyId___doc__, doc) < 0) {
@ -6005,22 +6098,22 @@ typedef struct wrapperbase slotdef;
ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, DOC) ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, DOC)
#define UNSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ #define UNSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \ ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \
"x." NAME "() <==> " DOC) NAME "(self)\n" DOC)
#define IBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ #define IBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \ ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \
"x." NAME "(y) <==> x" DOC "y") NAME "(self, value)\nReturns self" DOC "value.")
#define BINSLOT(NAME, SLOT, FUNCTION, DOC) \ #define BINSLOT(NAME, SLOT, FUNCTION, DOC) \
ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \ ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \
"x." NAME "(y) <==> x" DOC "y") NAME "(self, value)\nReturns self" DOC "value.")
#define RBINSLOT(NAME, SLOT, FUNCTION, DOC) \ #define RBINSLOT(NAME, SLOT, FUNCTION, DOC) \
ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \ ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \
"x." NAME "(y) <==> y" DOC "x") NAME "(self, value)\nReturns value" DOC "self.")
#define BINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \ #define BINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \
ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \ ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \
"x." NAME "(y) <==> " DOC) NAME "(self, value)\n" DOC)
#define RBINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \ #define RBINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \
ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \ ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \
"x." NAME "(y) <==> " DOC) NAME "(self, value)\n" DOC)
static slotdef slotdefs[] = { static slotdef slotdefs[] = {
TPSLOT("__getattribute__", tp_getattr, NULL, NULL, ""), TPSLOT("__getattribute__", tp_getattr, NULL, NULL, ""),
@ -6028,80 +6121,85 @@ static slotdef slotdefs[] = {
TPSLOT("__setattr__", tp_setattr, NULL, NULL, ""), TPSLOT("__setattr__", tp_setattr, NULL, NULL, ""),
TPSLOT("__delattr__", tp_setattr, NULL, NULL, ""), TPSLOT("__delattr__", tp_setattr, NULL, NULL, ""),
TPSLOT("__repr__", tp_repr, slot_tp_repr, wrap_unaryfunc, TPSLOT("__repr__", tp_repr, slot_tp_repr, wrap_unaryfunc,
"x.__repr__() <==> repr(x)"), "__repr__(self)\nReturns repr(self)."),
TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc, TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc,
"x.__hash__() <==> hash(x)"), "__hash__(self)\nReturns hash(self)."),
FLSLOT("__call__", tp_call, slot_tp_call, (wrapperfunc)wrap_call, FLSLOT("__call__", tp_call, slot_tp_call, (wrapperfunc)wrap_call,
"x.__call__(...) <==> x(...)", PyWrapperFlag_KEYWORDS), "__call__(self, *args, **kwargs)\nCalls self as a function.",
PyWrapperFlag_KEYWORDS),
TPSLOT("__str__", tp_str, slot_tp_str, wrap_unaryfunc, TPSLOT("__str__", tp_str, slot_tp_str, wrap_unaryfunc,
"x.__str__() <==> str(x)"), "__str__(self)\nReturns str(self)."),
TPSLOT("__getattribute__", tp_getattro, slot_tp_getattr_hook, TPSLOT("__getattribute__", tp_getattro, slot_tp_getattr_hook,
wrap_binaryfunc, "x.__getattribute__('name') <==> x.name"), wrap_binaryfunc,
"__getattribute__(self, name)\nReturns getattr(self, name)."),
TPSLOT("__getattr__", tp_getattro, slot_tp_getattr_hook, NULL, ""), TPSLOT("__getattr__", tp_getattro, slot_tp_getattr_hook, NULL, ""),
TPSLOT("__setattr__", tp_setattro, slot_tp_setattro, wrap_setattr, TPSLOT("__setattr__", tp_setattro, slot_tp_setattro, wrap_setattr,
"x.__setattr__('name', value) <==> x.name = value"), "__setattr__(self, name, value)\nImplements setattr(self, name, value)."),
TPSLOT("__delattr__", tp_setattro, slot_tp_setattro, wrap_delattr, TPSLOT("__delattr__", tp_setattro, slot_tp_setattro, wrap_delattr,
"x.__delattr__('name') <==> del x.name"), "__delattr__(self, name)\nImplements delattr(self, name)."),
TPSLOT("__lt__", tp_richcompare, slot_tp_richcompare, richcmp_lt, TPSLOT("__lt__", tp_richcompare, slot_tp_richcompare, richcmp_lt,
"x.__lt__(y) <==> x<y"), "__lt__(self, value)\nReturns self<value."),
TPSLOT("__le__", tp_richcompare, slot_tp_richcompare, richcmp_le, TPSLOT("__le__", tp_richcompare, slot_tp_richcompare, richcmp_le,
"x.__le__(y) <==> x<=y"), "__le__(self, value)\nReturns self<=value."),
TPSLOT("__eq__", tp_richcompare, slot_tp_richcompare, richcmp_eq, TPSLOT("__eq__", tp_richcompare, slot_tp_richcompare, richcmp_eq,
"x.__eq__(y) <==> x==y"), "__eq__(self, value)\nReturns self==value."),
TPSLOT("__ne__", tp_richcompare, slot_tp_richcompare, richcmp_ne, TPSLOT("__ne__", tp_richcompare, slot_tp_richcompare, richcmp_ne,
"x.__ne__(y) <==> x!=y"), "__ne__(self, value)\nReturns self!=value."),
TPSLOT("__gt__", tp_richcompare, slot_tp_richcompare, richcmp_gt, TPSLOT("__gt__", tp_richcompare, slot_tp_richcompare, richcmp_gt,
"x.__gt__(y) <==> x>y"), "__gt__(self, value)\nReturns self>value."),
TPSLOT("__ge__", tp_richcompare, slot_tp_richcompare, richcmp_ge, TPSLOT("__ge__", tp_richcompare, slot_tp_richcompare, richcmp_ge,
"x.__ge__(y) <==> x>=y"), "__ge__(self, value)\nReturns self>=value."),
TPSLOT("__iter__", tp_iter, slot_tp_iter, wrap_unaryfunc, TPSLOT("__iter__", tp_iter, slot_tp_iter, wrap_unaryfunc,
"x.__iter__() <==> iter(x)"), "__iter__(self)\nImplements iter(self)."),
TPSLOT("__next__", tp_iternext, slot_tp_iternext, wrap_next, TPSLOT("__next__", tp_iternext, slot_tp_iternext, wrap_next,
"x.__next__() <==> next(x)"), "__next__(self)\nImplements next(self)."),
TPSLOT("__get__", tp_descr_get, slot_tp_descr_get, wrap_descr_get, TPSLOT("__get__", tp_descr_get, slot_tp_descr_get, wrap_descr_get,
"descr.__get__(obj[, type]) -> value"), "__get__(self, instance, owner)\nCalled to get an attribute of instance, which is of type owner."),
TPSLOT("__set__", tp_descr_set, slot_tp_descr_set, wrap_descr_set, TPSLOT("__set__", tp_descr_set, slot_tp_descr_set, wrap_descr_set,
"descr.__set__(obj, value)"), "__set__(self, instance, value)\nSets an attribute of instance to value."),
TPSLOT("__delete__", tp_descr_set, slot_tp_descr_set, TPSLOT("__delete__", tp_descr_set, slot_tp_descr_set,
wrap_descr_delete, "descr.__delete__(obj)"), wrap_descr_delete,
"__delete__(instance)\nDeletes an attribute of instance."),
FLSLOT("__init__", tp_init, slot_tp_init, (wrapperfunc)wrap_init, FLSLOT("__init__", tp_init, slot_tp_init, (wrapperfunc)wrap_init,
"x.__init__(...) initializes x; " "__init__(self, *args, **kwargs)\n"
"see help(type(x)) for signature", "Initializes self. See help(type(self)) for accurate signature.",
PyWrapperFlag_KEYWORDS), PyWrapperFlag_KEYWORDS),
TPSLOT("__new__", tp_new, slot_tp_new, NULL, ""), TPSLOT("__new__", tp_new, slot_tp_new, NULL,
"__new__(cls, *args, **kwargs)\n"
"Creates new object. See help(cls) for accurate signature."),
TPSLOT("__del__", tp_finalize, slot_tp_finalize, (wrapperfunc)wrap_del, ""), TPSLOT("__del__", tp_finalize, slot_tp_finalize, (wrapperfunc)wrap_del, ""),
BINSLOT("__add__", nb_add, slot_nb_add, BINSLOT("__add__", nb_add, slot_nb_add,
"+"), "+"),
RBINSLOT("__radd__", nb_add, slot_nb_add, RBINSLOT("__radd__", nb_add, slot_nb_add,
"+"), "+"),
BINSLOT("__sub__", nb_subtract, slot_nb_subtract, BINSLOT("__sub__", nb_subtract, slot_nb_subtract,
"-"), "-"),
RBINSLOT("__rsub__", nb_subtract, slot_nb_subtract, RBINSLOT("__rsub__", nb_subtract, slot_nb_subtract,
"-"), "-"),
BINSLOT("__mul__", nb_multiply, slot_nb_multiply, BINSLOT("__mul__", nb_multiply, slot_nb_multiply,
"*"), "*"),
RBINSLOT("__rmul__", nb_multiply, slot_nb_multiply, RBINSLOT("__rmul__", nb_multiply, slot_nb_multiply,
"*"), "*"),
BINSLOT("__mod__", nb_remainder, slot_nb_remainder, BINSLOT("__mod__", nb_remainder, slot_nb_remainder,
"%"), "%"),
RBINSLOT("__rmod__", nb_remainder, slot_nb_remainder, RBINSLOT("__rmod__", nb_remainder, slot_nb_remainder,
"%"), "%"),
BINSLOTNOTINFIX("__divmod__", nb_divmod, slot_nb_divmod, BINSLOTNOTINFIX("__divmod__", nb_divmod, slot_nb_divmod,
"divmod(x, y)"), "__divmod__(self, value)\nReturns divmod(self, value)."),
RBINSLOTNOTINFIX("__rdivmod__", nb_divmod, slot_nb_divmod, RBINSLOTNOTINFIX("__rdivmod__", nb_divmod, slot_nb_divmod,
"divmod(y, x)"), "__rdivmod__(self, value)\nReturns divmod(value, self)."),
NBSLOT("__pow__", nb_power, slot_nb_power, wrap_ternaryfunc, NBSLOT("__pow__", nb_power, slot_nb_power, wrap_ternaryfunc,
"x.__pow__(y[, z]) <==> pow(x, y[, z])"), "__pow__(self, value, mod=None)\nReturns pow(self, value, mod)."),
NBSLOT("__rpow__", nb_power, slot_nb_power, wrap_ternaryfunc_r, NBSLOT("__rpow__", nb_power, slot_nb_power, wrap_ternaryfunc_r,
"y.__rpow__(x[, z]) <==> pow(x, y[, z])"), "__rpow__(self, value, mod=None)\nReturns pow(value, self, mod)."),
UNSLOT("__neg__", nb_negative, slot_nb_negative, wrap_unaryfunc, "-x"), UNSLOT("__neg__", nb_negative, slot_nb_negative, wrap_unaryfunc, "-self"),
UNSLOT("__pos__", nb_positive, slot_nb_positive, wrap_unaryfunc, "+x"), UNSLOT("__pos__", nb_positive, slot_nb_positive, wrap_unaryfunc, "+self"),
UNSLOT("__abs__", nb_absolute, slot_nb_absolute, wrap_unaryfunc, UNSLOT("__abs__", nb_absolute, slot_nb_absolute, wrap_unaryfunc,
"abs(x)"), "abs(self)"),
UNSLOT("__bool__", nb_bool, slot_nb_bool, wrap_inquirypred, UNSLOT("__bool__", nb_bool, slot_nb_bool, wrap_inquirypred,
"x != 0"), "self != 0"),
UNSLOT("__invert__", nb_invert, slot_nb_invert, wrap_unaryfunc, "~x"), UNSLOT("__invert__", nb_invert, slot_nb_invert, wrap_unaryfunc, "~self"),
BINSLOT("__lshift__", nb_lshift, slot_nb_lshift, "<<"), BINSLOT("__lshift__", nb_lshift, slot_nb_lshift, "<<"),
RBINSLOT("__rlshift__", nb_lshift, slot_nb_lshift, "<<"), RBINSLOT("__rlshift__", nb_lshift, slot_nb_lshift, "<<"),
BINSLOT("__rshift__", nb_rshift, slot_nb_rshift, ">>"), BINSLOT("__rshift__", nb_rshift, slot_nb_rshift, ">>"),
@ -6113,9 +6211,9 @@ static slotdef slotdefs[] = {
BINSLOT("__or__", nb_or, slot_nb_or, "|"), BINSLOT("__or__", nb_or, slot_nb_or, "|"),
RBINSLOT("__ror__", nb_or, slot_nb_or, "|"), RBINSLOT("__ror__", nb_or, slot_nb_or, "|"),
UNSLOT("__int__", nb_int, slot_nb_int, wrap_unaryfunc, UNSLOT("__int__", nb_int, slot_nb_int, wrap_unaryfunc,
"int(x)"), "int(self)"),
UNSLOT("__float__", nb_float, slot_nb_float, wrap_unaryfunc, UNSLOT("__float__", nb_float, slot_nb_float, wrap_unaryfunc,
"float(x)"), "float(self)"),
IBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add, IBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add,
wrap_binaryfunc, "+="), wrap_binaryfunc, "+="),
IBSLOT("__isub__", nb_inplace_subtract, slot_nb_inplace_subtract, IBSLOT("__isub__", nb_inplace_subtract, slot_nb_inplace_subtract,
@ -6145,45 +6243,48 @@ static slotdef slotdefs[] = {
IBSLOT("__itruediv__", nb_inplace_true_divide, IBSLOT("__itruediv__", nb_inplace_true_divide,
slot_nb_inplace_true_divide, wrap_binaryfunc, "/"), slot_nb_inplace_true_divide, wrap_binaryfunc, "/"),
NBSLOT("__index__", nb_index, slot_nb_index, wrap_unaryfunc, NBSLOT("__index__", nb_index, slot_nb_index, wrap_unaryfunc,
"x[y:z] <==> x[y.__index__():z.__index__()]"), "__index__(self)\n"
"Returns self converted to an integer, if self is suitable"
"for use as an index into a list."),
MPSLOT("__len__", mp_length, slot_mp_length, wrap_lenfunc, MPSLOT("__len__", mp_length, slot_mp_length, wrap_lenfunc,
"x.__len__() <==> len(x)"), "__len__(self)\nReturns len(self)."),
MPSLOT("__getitem__", mp_subscript, slot_mp_subscript, MPSLOT("__getitem__", mp_subscript, slot_mp_subscript,
wrap_binaryfunc, wrap_binaryfunc,
"x.__getitem__(y) <==> x[y]"), "__getitem__(self, key)\nReturns self[key]."),
MPSLOT("__setitem__", mp_ass_subscript, slot_mp_ass_subscript, MPSLOT("__setitem__", mp_ass_subscript, slot_mp_ass_subscript,
wrap_objobjargproc, wrap_objobjargproc,
"x.__setitem__(i, y) <==> x[i]=y"), "__setitem__(self, key, value)\nSets self[key] to value."),
MPSLOT("__delitem__", mp_ass_subscript, slot_mp_ass_subscript, MPSLOT("__delitem__", mp_ass_subscript, slot_mp_ass_subscript,
wrap_delitem, wrap_delitem,
"x.__delitem__(y) <==> del x[y]"), "__delitem__(key)\nDeletes self[key]."),
SQSLOT("__len__", sq_length, slot_sq_length, wrap_lenfunc, SQSLOT("__len__", sq_length, slot_sq_length, wrap_lenfunc,
"x.__len__() <==> len(x)"), "__len__(self)\nReturns len(self)."),
/* Heap types defining __add__/__mul__ have sq_concat/sq_repeat == NULL. /* Heap types defining __add__/__mul__ have sq_concat/sq_repeat == NULL.
The logic in abstract.c always falls back to nb_add/nb_multiply in The logic in abstract.c always falls back to nb_add/nb_multiply in
this case. Defining both the nb_* and the sq_* slots to call the this case. Defining both the nb_* and the sq_* slots to call the
user-defined methods has unexpected side-effects, as shown by user-defined methods has unexpected side-effects, as shown by
test_descr.notimplemented() */ test_descr.notimplemented() */
SQSLOT("__add__", sq_concat, NULL, wrap_binaryfunc, SQSLOT("__add__", sq_concat, NULL, wrap_binaryfunc,
"x.__add__(y) <==> x+y"), "__add__(self, value)\nReturns self+value."),
SQSLOT("__mul__", sq_repeat, NULL, wrap_indexargfunc, SQSLOT("__mul__", sq_repeat, NULL, wrap_indexargfunc,
"x.__mul__(n) <==> x*n"), "__mul__(self, value)\nReturns self*value.n"),
SQSLOT("__rmul__", sq_repeat, NULL, wrap_indexargfunc, SQSLOT("__rmul__", sq_repeat, NULL, wrap_indexargfunc,
"x.__rmul__(n) <==> n*x"), "__rmul__(self, value)\nReturns self*value."),
SQSLOT("__getitem__", sq_item, slot_sq_item, wrap_sq_item, SQSLOT("__getitem__", sq_item, slot_sq_item, wrap_sq_item,
"x.__getitem__(y) <==> x[y]"), "__getitem__(self, key)\nReturns self[key]."),
SQSLOT("__setitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_setitem, SQSLOT("__setitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_setitem,
"x.__setitem__(i, y) <==> x[i]=y"), "__setitem__(self, key, value)\nSets self[key] to value."),
SQSLOT("__delitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_delitem, SQSLOT("__delitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_delitem,
"x.__delitem__(y) <==> del x[y]"), "__delitem__(self, key)\nDeletes self[key]."),
SQSLOT("__contains__", sq_contains, slot_sq_contains, wrap_objobjproc, SQSLOT("__contains__", sq_contains, slot_sq_contains, wrap_objobjproc,
"x.__contains__(y) <==> y in x"), "__contains__(self, key)\nReturns key in self."),
SQSLOT("__iadd__", sq_inplace_concat, NULL, SQSLOT("__iadd__", sq_inplace_concat, NULL,
wrap_binaryfunc, "x.__iadd__(y) <==> x+=y"), wrap_binaryfunc,
"__iadd__(self, value)\nImplements self+=value."),
SQSLOT("__imul__", sq_inplace_repeat, NULL, SQSLOT("__imul__", sq_inplace_repeat, NULL,
wrap_indexargfunc, "x.__imul__(y) <==> x*=y"), wrap_indexargfunc,
"__imul__(self, value)\nImplements self*=value."),
{NULL} {NULL}
}; };

View File

@ -12900,7 +12900,7 @@ PyDoc_STRVAR(unicode_maketrans__doc__,
{"maketrans", (PyCFunction)unicode_maketrans, METH_VARARGS|METH_STATIC, unicode_maketrans__doc__}, {"maketrans", (PyCFunction)unicode_maketrans, METH_VARARGS|METH_STATIC, unicode_maketrans__doc__},
static PyObject * static PyObject *
unicode_maketrans_impl(void *null, PyObject *x, PyObject *y, PyObject *z); unicode_maketrans_impl(PyObject *x, PyObject *y, PyObject *z);
static PyObject * static PyObject *
unicode_maketrans(void *null, PyObject *args) unicode_maketrans(void *null, PyObject *args)
@ -12914,15 +12914,15 @@ unicode_maketrans(void *null, PyObject *args)
"O|UU:maketrans", "O|UU:maketrans",
&x, &y, &z)) &x, &y, &z))
goto exit; goto exit;
return_value = unicode_maketrans_impl(null, x, y, z); return_value = unicode_maketrans_impl(x, y, z);
exit: exit:
return return_value; return return_value;
} }
static PyObject * static PyObject *
unicode_maketrans_impl(void *null, PyObject *x, PyObject *y, PyObject *z) unicode_maketrans_impl(PyObject *x, PyObject *y, PyObject *z)
/*[clinic end generated code: checksum=7f76f414a0dfd0c614e0d4717872eeb520516da7]*/ /*[clinic end generated code: checksum=90a3de8c494b304687e1e0d7e5fa8ba78eac6533]*/
{ {
PyObject *new = NULL, *key, *value; PyObject *new = NULL, *key, *value;
Py_ssize_t i = 0; Py_ssize_t i = 0;

View File

@ -1325,7 +1325,7 @@ builtin_len(PyObject *self, PyObject *v)
} }
PyDoc_STRVAR(len_doc, PyDoc_STRVAR(len_doc,
"len(object) -> integer\n\ "len(module, object)\n\
\n\ \n\
Return the number of items of a sequence or mapping."); Return the number of items of a sequence or mapping.");

View File

@ -232,7 +232,7 @@ On platforms without threads, return False.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(_imp_lock_held__doc__, PyDoc_STRVAR(_imp_lock_held__doc__,
"lock_held()\n" "lock_held(module)\n"
"Return True if the import lock is currently held, else False.\n" "Return True if the import lock is currently held, else False.\n"
"\n" "\n"
"On platforms without threads, return False."); "On platforms without threads, return False.");
@ -251,7 +251,7 @@ _imp_lock_held(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
static PyObject * static PyObject *
_imp_lock_held_impl(PyModuleDef *module) _imp_lock_held_impl(PyModuleDef *module)
/*[clinic end generated code: checksum=ede1cafb78eb22e3009602f684c8b780e2b82d62]*/ /*[clinic end generated code: checksum=17172a9917d389dd1564e2108fec34d23aecb6c2]*/
{ {
#ifdef WITH_THREAD #ifdef WITH_THREAD
return PyBool_FromLong(import_lock_thread != -1); return PyBool_FromLong(import_lock_thread != -1);
@ -270,7 +270,7 @@ modules. On platforms without threads, this function does nothing.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(_imp_acquire_lock__doc__, PyDoc_STRVAR(_imp_acquire_lock__doc__,
"acquire_lock()\n" "acquire_lock(module)\n"
"Acquires the interpreter\'s import lock for the current thread.\n" "Acquires the interpreter\'s import lock for the current thread.\n"
"\n" "\n"
"This lock should be used by import hooks to ensure thread-safety when importing\n" "This lock should be used by import hooks to ensure thread-safety when importing\n"
@ -290,7 +290,7 @@ _imp_acquire_lock(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
static PyObject * static PyObject *
_imp_acquire_lock_impl(PyModuleDef *module) _imp_acquire_lock_impl(PyModuleDef *module)
/*[clinic end generated code: checksum=5b520b2416c5954a7cf0ed30955d68abe20b5868]*/ /*[clinic end generated code: checksum=20db30e18f6b8758386fe06907edb3f8e43080d7]*/
{ {
#ifdef WITH_THREAD #ifdef WITH_THREAD
_PyImport_AcquireLock(); _PyImport_AcquireLock();
@ -308,7 +308,7 @@ On platforms without threads, this function does nothing.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(_imp_release_lock__doc__, PyDoc_STRVAR(_imp_release_lock__doc__,
"release_lock()\n" "release_lock(module)\n"
"Release the interpreter\'s import lock.\n" "Release the interpreter\'s import lock.\n"
"\n" "\n"
"On platforms without threads, this function does nothing."); "On platforms without threads, this function does nothing.");
@ -327,7 +327,7 @@ _imp_release_lock(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
static PyObject * static PyObject *
_imp_release_lock_impl(PyModuleDef *module) _imp_release_lock_impl(PyModuleDef *module)
/*[clinic end generated code: checksum=efcd9d2923294c04371596e7f6d66a706d43fcac]*/ /*[clinic end generated code: checksum=17749fd7752d2c392447a1f83c5d371f54d7ebd3]*/
{ {
#ifdef WITH_THREAD #ifdef WITH_THREAD
if (_PyImport_ReleaseLock() < 0) { if (_PyImport_ReleaseLock() < 0) {
@ -927,7 +927,7 @@ Changes code.co_filename to specify the passed-in file path.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(_imp__fix_co_filename__doc__, PyDoc_STRVAR(_imp__fix_co_filename__doc__,
"_fix_co_filename(code, path)\n" "_fix_co_filename(module, code, path)\n"
"Changes code.co_filename to specify the passed-in file path.\n" "Changes code.co_filename to specify the passed-in file path.\n"
"\n" "\n"
" code\n" " code\n"
@ -960,7 +960,7 @@ exit:
static PyObject * static PyObject *
_imp__fix_co_filename_impl(PyModuleDef *module, PyCodeObject *code, PyObject *path) _imp__fix_co_filename_impl(PyModuleDef *module, PyCodeObject *code, PyObject *path)
/*[clinic end generated code: checksum=4f55bad308072b30ad1921068fc4ce85bd2b39bf]*/ /*[clinic end generated code: checksum=d32cf2b2e0480c714f909921cc9e55d763b39dd5]*/
{ {
update_compiled_module(code, path); update_compiled_module(code, path);
@ -1823,7 +1823,7 @@ Returns the list of file suffixes used to identify extension modules.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(_imp_extension_suffixes__doc__, PyDoc_STRVAR(_imp_extension_suffixes__doc__,
"extension_suffixes()\n" "extension_suffixes(module)\n"
"Returns the list of file suffixes used to identify extension modules."); "Returns the list of file suffixes used to identify extension modules.");
#define _IMP_EXTENSION_SUFFIXES_METHODDEF \ #define _IMP_EXTENSION_SUFFIXES_METHODDEF \
@ -1840,7 +1840,7 @@ _imp_extension_suffixes(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
static PyObject * static PyObject *
_imp_extension_suffixes_impl(PyModuleDef *module) _imp_extension_suffixes_impl(PyModuleDef *module)
/*[clinic end generated code: checksum=82fb35d8429a429a4dc80c84b45b1aad73ff1de7]*/ /*[clinic end generated code: checksum=625c8f11a5bbd4b85373f0a54f7f3ef19c55beb4]*/
{ {
PyObject *list; PyObject *list;
const char *suffix; const char *suffix;
@ -1878,7 +1878,7 @@ Initializes a built-in module.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(_imp_init_builtin__doc__, PyDoc_STRVAR(_imp_init_builtin__doc__,
"init_builtin(name)\n" "init_builtin(module, name)\n"
"Initializes a built-in module."); "Initializes a built-in module.");
#define _IMP_INIT_BUILTIN_METHODDEF \ #define _IMP_INIT_BUILTIN_METHODDEF \
@ -1905,7 +1905,7 @@ exit:
static PyObject * static PyObject *
_imp_init_builtin_impl(PyModuleDef *module, PyObject *name) _imp_init_builtin_impl(PyModuleDef *module, PyObject *name)
/*[clinic end generated code: checksum=59239206e5b2fb59358066e72fd0e72e55a7baf5]*/ /*[clinic end generated code: checksum=a4e4805a523757cd3ddfeec6e5b16740678fed6a]*/
{ {
int ret; int ret;
PyObject *m; PyObject *m;
@ -1932,7 +1932,7 @@ Initializes a frozen module.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(_imp_init_frozen__doc__, PyDoc_STRVAR(_imp_init_frozen__doc__,
"init_frozen(name)\n" "init_frozen(module, name)\n"
"Initializes a frozen module."); "Initializes a frozen module.");
#define _IMP_INIT_FROZEN_METHODDEF \ #define _IMP_INIT_FROZEN_METHODDEF \
@ -1959,7 +1959,7 @@ exit:
static PyObject * static PyObject *
_imp_init_frozen_impl(PyModuleDef *module, PyObject *name) _imp_init_frozen_impl(PyModuleDef *module, PyObject *name)
/*[clinic end generated code: checksum=503fcc3de9961263e4d9484259af357a7d287a0b]*/ /*[clinic end generated code: checksum=2a58c119dd3e121cf5a9924f936cfd7b40253c12]*/
{ {
int ret; int ret;
PyObject *m; PyObject *m;
@ -1986,7 +1986,7 @@ Create a code object for a frozen module.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(_imp_get_frozen_object__doc__, PyDoc_STRVAR(_imp_get_frozen_object__doc__,
"get_frozen_object(name)\n" "get_frozen_object(module, name)\n"
"Create a code object for a frozen module."); "Create a code object for a frozen module.");
#define _IMP_GET_FROZEN_OBJECT_METHODDEF \ #define _IMP_GET_FROZEN_OBJECT_METHODDEF \
@ -2013,7 +2013,7 @@ exit:
static PyObject * static PyObject *
_imp_get_frozen_object_impl(PyModuleDef *module, PyObject *name) _imp_get_frozen_object_impl(PyModuleDef *module, PyObject *name)
/*[clinic end generated code: checksum=7a6423a4daf139496b9a394ff3ac6130089d1cba]*/ /*[clinic end generated code: checksum=94c9108b58dda80d187fef21275a009bd0f91e96]*/
{ {
return get_frozen_object(name); return get_frozen_object(name);
} }
@ -2028,7 +2028,7 @@ Returns True if the module name is of a frozen package.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(_imp_is_frozen_package__doc__, PyDoc_STRVAR(_imp_is_frozen_package__doc__,
"is_frozen_package(name)\n" "is_frozen_package(module, name)\n"
"Returns True if the module name is of a frozen package."); "Returns True if the module name is of a frozen package.");
#define _IMP_IS_FROZEN_PACKAGE_METHODDEF \ #define _IMP_IS_FROZEN_PACKAGE_METHODDEF \
@ -2055,7 +2055,7 @@ exit:
static PyObject * static PyObject *
_imp_is_frozen_package_impl(PyModuleDef *module, PyObject *name) _imp_is_frozen_package_impl(PyModuleDef *module, PyObject *name)
/*[clinic end generated code: checksum=dc7e361ea30b6945b8bbe7266d7b9a5ea433b510]*/ /*[clinic end generated code: checksum=17a342b94dbe859cdfc361bc8a6bc1b3cb163364]*/
{ {
return is_frozen_package(name); return is_frozen_package(name);
} }
@ -2070,7 +2070,7 @@ Returns True if the module name corresponds to a built-in module.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(_imp_is_builtin__doc__, PyDoc_STRVAR(_imp_is_builtin__doc__,
"is_builtin(name)\n" "is_builtin(module, name)\n"
"Returns True if the module name corresponds to a built-in module."); "Returns True if the module name corresponds to a built-in module.");
#define _IMP_IS_BUILTIN_METHODDEF \ #define _IMP_IS_BUILTIN_METHODDEF \
@ -2097,7 +2097,7 @@ exit:
static PyObject * static PyObject *
_imp_is_builtin_impl(PyModuleDef *module, PyObject *name) _imp_is_builtin_impl(PyModuleDef *module, PyObject *name)
/*[clinic end generated code: checksum=353938c1d55210a1e3850d3ccba7539d02165cac]*/ /*[clinic end generated code: checksum=51c6139dcfd9bee1f40980ea68b7797f8489d69a]*/
{ {
return PyLong_FromLong(is_builtin(name)); return PyLong_FromLong(is_builtin(name));
} }
@ -2112,7 +2112,7 @@ Returns True if the module name corresponds to a frozen module.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(_imp_is_frozen__doc__, PyDoc_STRVAR(_imp_is_frozen__doc__,
"is_frozen(name)\n" "is_frozen(module, name)\n"
"Returns True if the module name corresponds to a frozen module."); "Returns True if the module name corresponds to a frozen module.");
#define _IMP_IS_FROZEN_METHODDEF \ #define _IMP_IS_FROZEN_METHODDEF \
@ -2139,7 +2139,7 @@ exit:
static PyObject * static PyObject *
_imp_is_frozen_impl(PyModuleDef *module, PyObject *name) _imp_is_frozen_impl(PyModuleDef *module, PyObject *name)
/*[clinic end generated code: checksum=978b547ddcb76fa6c4a181ad53569c9acf382c7b]*/ /*[clinic end generated code: checksum=4b079fb45a495835056ea5604735d552d222be5c]*/
{ {
const struct _frozen *p; const struct _frozen *p;
@ -2161,7 +2161,7 @@ Loads an extension module.
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(_imp_load_dynamic__doc__, PyDoc_STRVAR(_imp_load_dynamic__doc__,
"load_dynamic(name, path, file=None)\n" "load_dynamic(module, name, path, file=None)\n"
"Loads an extension module."); "Loads an extension module.");
#define _IMP_LOAD_DYNAMIC_METHODDEF \ #define _IMP_LOAD_DYNAMIC_METHODDEF \
@ -2190,7 +2190,7 @@ exit:
static PyObject * static PyObject *
_imp_load_dynamic_impl(PyModuleDef *module, PyObject *name, PyObject *path, PyObject *file) _imp_load_dynamic_impl(PyModuleDef *module, PyObject *name, PyObject *path, PyObject *file)
/*[clinic end generated code: checksum=6795f65d9ce003ccaf08e4e8eef484dc52e262d0]*/ /*[clinic end generated code: checksum=63e051fd0d0350c785bf185be41b0892f9920622]*/
{ {
PyObject *mod; PyObject *mod;
FILE *fp; FILE *fp;

View File

@ -139,9 +139,9 @@ def is_legal_py_identifier(s):
# so if they're used Argument Clinic will add "_value" to the end # so if they're used Argument Clinic will add "_value" to the end
# of the name in C. # of the name in C.
c_keywords = set(""" c_keywords = set("""
asm auto break case char cls const continue default do double asm auto break case char const continue default do double
else enum extern float for goto if inline int long module null else enum extern float for goto if inline int long
register return self short signed sizeof static struct switch register return short signed sizeof static struct switch
typedef typeof union unsigned void volatile while typedef typeof union unsigned void volatile while
""".strip().split()) """.strip().split())
@ -635,6 +635,9 @@ __________________________________________________
def output_templates(self, f): def output_templates(self, f):
parameters = list(f.parameters.values()) parameters = list(f.parameters.values())
assert parameters
assert isinstance(parameters[0].converter, self_converter)
del parameters[0]
converters = [p.converter for p in parameters] converters = [p.converter for p in parameters]
has_option_groups = parameters and (parameters[0].group or parameters[-1].group) has_option_groups = parameters and (parameters[0].group or parameters[-1].group)
@ -679,8 +682,11 @@ __________________________________________________
return_value_declaration = "PyObject *return_value = NULL;" return_value_declaration = "PyObject *return_value = NULL;"
methoddef_define = templates['methoddef_define'] methoddef_define = templates['methoddef_define']
docstring_prototype = templates['docstring_prototype'] if new_or_init and not f.docstring:
docstring_definition = templates['docstring_definition'] docstring_prototype = docstring_definition = ''
else:
docstring_prototype = templates['docstring_prototype']
docstring_definition = templates['docstring_definition']
impl_definition = templates['impl_definition'] impl_definition = templates['impl_definition']
impl_prototype = parser_prototype = parser_definition = None impl_prototype = parser_prototype = parser_definition = None
@ -858,6 +864,8 @@ __________________________________________________
add, output = text_accumulator() add, output = text_accumulator()
parameters = list(f.parameters.values()) parameters = list(f.parameters.values())
if isinstance(parameters[0].converter, self_converter):
del parameters[0]
groups = [] groups = []
group = None group = None
@ -936,14 +944,69 @@ __________________________________________________
data = CRenderData() data = CRenderData()
parameters = list(f.parameters.values()) parameters = list(f.parameters.values())
assert parameters, "We should always have a 'self' at this point!"
converters = [p.converter for p in parameters] converters = [p.converter for p in parameters]
templates = self.output_templates(f)
f_self = parameters[0]
selfless = parameters[1:]
assert isinstance(f_self.converter, self_converter), "No self parameter in " + repr(f.full_name) + "!"
last_group = 0
first_optional = len(selfless)
positional = selfless and selfless[-1].kind == inspect.Parameter.POSITIONAL_ONLY
new_or_init = f.kind in (METHOD_NEW, METHOD_INIT)
default_return_converter = (not f.return_converter or
f.return_converter.type == 'PyObject *')
has_option_groups = False
# offset i by -1 because first_optional needs to ignore self
for i, p in enumerate(parameters, -1):
c = p.converter
if (i != -1) and (p.default is not unspecified):
first_optional = min(first_optional, i)
# insert group variable
group = p.group
if last_group != group:
last_group = group
if group:
group_name = self.group_to_variable_name(group)
data.impl_arguments.append(group_name)
data.declarations.append("int " + group_name + " = 0;")
data.impl_parameters.append("int " + group_name)
has_option_groups = True
c.render(p, data)
if has_option_groups and (not positional):
fail("You cannot use optional groups ('[' and ']')\nunless all parameters are positional-only ('/').")
# HACK
# when we're METH_O, but have a custom return converter,
# we use "impl_parameters" for the parsing function
# because that works better. but that means we must
# supress actually declaring the impl's parameters
# as variables in the parsing function. but since it's
# METH_O, we have exactly one anyway, so we know exactly
# where it is.
if ("METH_O" in templates['methoddef_define'] and
not default_return_converter):
data.declarations.pop(0)
template_dict = {} template_dict = {}
full_name = f.full_name full_name = f.full_name
template_dict['full_name'] = full_name template_dict['full_name'] = full_name
name = full_name.rpartition('.')[2] if new_or_init:
name = f.cls.name
else:
name = f.name
template_dict['name'] = name template_dict['name'] = name
if f.c_basename: if f.c_basename:
@ -953,6 +1016,7 @@ __________________________________________________
if fields[-1] == '__new__': if fields[-1] == '__new__':
fields.pop() fields.pop()
c_basename = "_".join(fields) c_basename = "_".join(fields)
template_dict['c_basename'] = c_basename template_dict['c_basename'] = c_basename
methoddef_name = "{}_METHODDEF".format(c_basename.upper()) methoddef_name = "{}_METHODDEF".format(c_basename.upper())
@ -960,67 +1024,7 @@ __________________________________________________
template_dict['docstring'] = self.docstring_for_c_string(f) template_dict['docstring'] = self.docstring_for_c_string(f)
positional = has_option_groups = False f_self.converter.set_template_dict(template_dict)
first_optional = len(parameters)
if parameters:
last_group = 0
for i, p in enumerate(parameters):
c = p.converter
if p.default is not unspecified:
first_optional = min(first_optional, i)
# insert group variable
group = p.group
if last_group != group:
last_group = group
if group:
group_name = self.group_to_variable_name(group)
data.impl_arguments.append(group_name)
data.declarations.append("int " + group_name + " = 0;")
data.impl_parameters.append("int " + group_name)
has_option_groups = True
c.render(p, data)
positional = parameters[-1].kind == inspect.Parameter.POSITIONAL_ONLY
if has_option_groups and (not positional):
fail("You cannot use optional groups ('[' and ']')\nunless all parameters are positional-only ('/').")
# HACK
# when we're METH_O, but have a custom
# return converter, we use
# "impl_parameters" for the parsing
# function because that works better.
# but that means we must supress actually
# declaring the impl's parameters as variables
# in the parsing function. but since it's
# METH_O, we only have one anyway, so we don't
# have any problem finding it.
default_return_converter = (not f.return_converter or
f.return_converter.type == 'PyObject *')
if (len(parameters) == 1 and
parameters[0].kind == inspect.Parameter.POSITIONAL_ONLY and
not converters[0].is_optional() and
isinstance(converters[0], object_converter) and
converters[0].format_unit == 'O' and
not default_return_converter):
data.declarations.pop(0)
# now insert our "self" (or whatever) parameters
# (we deliberately don't call render on self converters)
stock_self = self_converter('self', f)
template_dict['self_name'] = stock_self.name
template_dict['self_type'] = stock_self.type
data.impl_parameters.insert(0, f.self_converter.type + ("" if f.self_converter.type.endswith('*') else " ") + f.self_converter.name)
if f.self_converter.type != stock_self.type:
self_cast = '(' + f.self_converter.type + ')'
else:
self_cast = ''
data.impl_arguments.insert(0, self_cast + stock_self.name)
f.return_converter.render(f, data) f.return_converter.render(f, data)
template_dict['impl_return_type'] = f.return_converter.type template_dict['impl_return_type'] = f.return_converter.type
@ -1036,15 +1040,16 @@ __________________________________________________
template_dict['cleanup'] = "".join(data.cleanup) template_dict['cleanup'] = "".join(data.cleanup)
template_dict['return_value'] = data.return_value template_dict['return_value'] = data.return_value
# used by unpack tuple # used by unpack tuple code generator
template_dict['unpack_min'] = str(first_optional) ignore_self = -1 if isinstance(converters[0], self_converter) else 0
template_dict['unpack_max'] = str(len(parameters)) unpack_min = first_optional
unpack_max = len(selfless)
template_dict['unpack_min'] = str(unpack_min)
template_dict['unpack_max'] = str(unpack_max)
if has_option_groups: if has_option_groups:
self.render_option_group_parsing(f, template_dict) self.render_option_group_parsing(f, template_dict)
templates = self.output_templates(f)
for name, destination in clinic.field_destinations.items(): for name, destination in clinic.field_destinations.items():
template = templates[name] template = templates[name]
if has_option_groups: if has_option_groups:
@ -1077,6 +1082,7 @@ __________________________________________________
@contextlib.contextmanager @contextlib.contextmanager
def OverrideStdioWith(stdout): def OverrideStdioWith(stdout):
saved_stdout = sys.stdout saved_stdout = sys.stdout
@ -1775,7 +1781,9 @@ __xor__
""".strip().split()) """.strip().split())
INVALID, CALLABLE, STATIC_METHOD, CLASS_METHOD, METHOD_INIT, METHOD_NEW = range(6) INVALID, CALLABLE, STATIC_METHOD, CLASS_METHOD, METHOD_INIT, METHOD_NEW = """
INVALID, CALLABLE, STATIC_METHOD, CLASS_METHOD, METHOD_INIT, METHOD_NEW
""".replace(",", "").strip().split()
class Function: class Function:
""" """
@ -1969,6 +1977,19 @@ class CConverter(metaclass=CConverterAutoRegister):
# Only used by format units ending with '#'. # Only used by format units ending with '#'.
length = False length = False
# Should we show this parameter in the generated
# __text_signature__? This is *almost* always True.
show_in_signature = True
# Overrides the name used in a text signature.
# The name used for a "self" parameter must be one of
# self, type, or module; however users can set their own.
# This lets the self_converter overrule the user-settable
# name, *just* for the text signature.
# Only set by self_converter.
signature_name = None
# keep in sync with self_converter.__init__!
def __init__(self, name, function, default=unspecified, *, c_default=None, py_default=None, annotation=unspecified, **kwargs): def __init__(self, name, function, default=unspecified, *, c_default=None, py_default=None, annotation=unspecified, **kwargs):
self.function = function self.function = function
self.name = name self.name = name
@ -1998,11 +2019,23 @@ class CConverter(metaclass=CConverterAutoRegister):
def is_optional(self): def is_optional(self):
return (self.default is not unspecified) return (self.default is not unspecified)
def render(self, parameter, data): def _render_self(self, parameter, data):
""" self.parameter = parameter
parameter is a clinic.Parameter instance. original_name = self.name
data is a CRenderData instance. name = ensure_legal_c_identifier(original_name)
"""
# impl_arguments
s = ("&" if self.impl_by_reference else "") + name
data.impl_arguments.append(s)
if self.length:
data.impl_arguments.append(self.length_name())
# impl_parameters
data.impl_parameters.append(self.simple_declaration(by_reference=self.impl_by_reference))
if self.length:
data.impl_parameters.append("Py_ssize_clean_t " + self.length_name())
def _render_non_self(self, parameter, data):
self.parameter = parameter self.parameter = parameter
original_name = self.name original_name = self.name
name = ensure_legal_c_identifier(original_name) name = ensure_legal_c_identifier(original_name)
@ -2016,12 +2049,6 @@ class CConverter(metaclass=CConverterAutoRegister):
if initializers: if initializers:
data.initializers.append('/* initializers for ' + name + ' */\n' + initializers.rstrip()) data.initializers.append('/* initializers for ' + name + ' */\n' + initializers.rstrip())
# impl_arguments
s = ("&" if self.impl_by_reference else "") + name
data.impl_arguments.append(s)
if self.length:
data.impl_arguments.append(self.length_name())
# keywords # keywords
data.keywords.append(original_name) data.keywords.append(original_name)
@ -2035,16 +2062,19 @@ class CConverter(metaclass=CConverterAutoRegister):
# parse_arguments # parse_arguments
self.parse_argument(data.parse_arguments) self.parse_argument(data.parse_arguments)
# impl_parameters
data.impl_parameters.append(self.simple_declaration(by_reference=self.impl_by_reference))
if self.length:
data.impl_parameters.append("Py_ssize_clean_t " + self.length_name())
# cleanup # cleanup
cleanup = self.cleanup() cleanup = self.cleanup()
if cleanup: if cleanup:
data.cleanup.append('/* Cleanup for ' + name + ' */\n' + cleanup.rstrip() + "\n") data.cleanup.append('/* Cleanup for ' + name + ' */\n' + cleanup.rstrip() + "\n")
def render(self, parameter, data):
"""
parameter is a clinic.Parameter instance.
data is a CRenderData instance.
"""
self._render_self(parameter, data)
self._render_non_self(parameter, data)
def length_name(self): def length_name(self):
"""Computes the name of the associated "length" variable.""" """Computes the name of the associated "length" variable."""
if not self.length: if not self.length:
@ -2318,7 +2348,7 @@ class str_converter(CConverter):
format_unit = 'et#' format_unit = 'et#'
if format_unit.endswith('#'): if format_unit.endswith('#'):
print("Warning: code using format unit ", repr(format_unit), "probably doesn't work properly.") fail("Sorry: code using format unit ", repr(format_unit), "probably doesn't work properly yet.\nGive Larry your test case and he'll it.")
# TODO set pointer to NULL # TODO set pointer to NULL
# TODO add cleanup for buffer # TODO add cleanup for buffer
pass pass
@ -2421,35 +2451,108 @@ class Py_buffer_converter(CConverter):
return "".join(["if (", name, ".obj)\n PyBuffer_Release(&", name, ");\n"]) return "".join(["if (", name, ".obj)\n PyBuffer_Release(&", name, ");\n"])
def correct_name_for_self(f):
if f.kind in (CALLABLE, METHOD_INIT):
if f.cls:
return "PyObject *", "self"
return "PyModuleDef *", "module"
if f.kind == STATIC_METHOD:
return "void *", "null"
if f.kind in (CLASS_METHOD, METHOD_NEW):
return "PyTypeObject *", "type"
raise RuntimeError("Unhandled type of function f: " + repr(f.kind))
class self_converter(CConverter): class self_converter(CConverter):
""" """
A special-case converter: A special-case converter:
this is the default converter used for "self". this is the default converter used for "self".
""" """
type = "PyObject *" type = None
format_unit = ''
def converter_init(self, *, type=None): def converter_init(self, *, type=None):
f = self.function f = self.function
if f.kind in (CALLABLE, METHOD_INIT): default_type, default_name = correct_name_for_self(f)
if f.cls: self.signature_name = default_name
self.name = "self" self.type = type or self.type or default_type
else:
self.name = "module"
self.type = "PyModuleDef *"
elif f.kind == STATIC_METHOD:
self.name = "null"
self.type = "void *"
elif f.kind == CLASS_METHOD:
self.name = "cls"
self.type = "PyTypeObject *"
elif f.kind == METHOD_NEW:
self.name = "type"
self.type = "PyTypeObject *"
if type: kind = self.function.kind
self.type = type new_or_init = kind in (METHOD_NEW, METHOD_INIT)
if (kind == STATIC_METHOD) or new_or_init:
self.show_in_signature = False
# tp_new (METHOD_NEW) functions are of type newfunc:
# typedef PyObject *(*newfunc)(struct _typeobject *, PyObject *, PyObject *);
# PyTypeObject is a typedef for struct _typeobject.
#
# tp_init (METHOD_INIT) functions are of type initproc:
# typedef int (*initproc)(PyObject *, PyObject *, PyObject *);
#
# All other functions generated by Argument Clinic are stored in
# PyMethodDef structures, in the ml_meth slot, which is of type PyCFunction:
# typedef PyObject *(*PyCFunction)(PyObject *, PyObject *);
# However! We habitually cast these functions to PyCFunction,
# since functions that accept keyword arguments don't fit this signature
# but are stored there anyway. So strict type equality isn't important
# for these functions.
#
# So:
#
# * The name of the first parameter to the impl and the parsing function will always
# be self.name.
#
# * The type of the first parameter to the impl will always be of self.type.
#
# * If the function is neither tp_new (METHOD_NEW) nor tp_init (METHOD_INIT):
# * The type of the first parameter to the parsing function is also self.type.
# This means that if you step into the parsing function, your "self" parameter
# is of the correct type, which may make debugging more pleasant.
#
# * Else if the function is tp_new (METHOD_NEW):
# * The type of the first parameter to the parsing function is "PyTypeObject *",
# so the type signature of the function call is an exact match.
# * If self.type != "PyTypeObject *", we cast the first parameter to self.type
# in the impl call.
#
# * Else if the function is tp_init (METHOD_INIT):
# * The type of the first parameter to the parsing function is "PyObject *",
# so the type signature of the function call is an exact match.
# * If self.type != "PyObject *", we cast the first parameter to self.type
# in the impl call.
@property
def parser_type(self):
kind = self.function.kind
if kind == METHOD_NEW:
return "PyTypeObject *"
if kind == METHOD_INIT:
return "PyObject *"
return self.type
def render(self, parameter, data): def render(self, parameter, data):
fail("render() should never be called on self_converter instances") """
parameter is a clinic.Parameter instance.
data is a CRenderData instance.
"""
if self.function.kind == STATIC_METHOD:
return
self._render_self(parameter, data)
if self.type != self.parser_type:
# insert cast to impl_argument[0], aka self.
# we know we're in the first slot in all the CRenderData lists,
# because we render parameters in order, and self is always first.
assert len(data.impl_arguments) == 1
assert data.impl_arguments[0] == self.name
data.impl_arguments[0] = '(' + self.type + ")" + data.impl_arguments[0]
def set_template_dict(self, template_dict):
template_dict['self_name'] = self.name
template_dict['self_type'] = self.parser_type
@ -2997,7 +3100,7 @@ class DSLParser:
if not return_converter: if not return_converter:
return_converter = init_return_converter() return_converter = init_return_converter()
elif fields[-1] in unsupported_special_methods: elif fields[-1] in unsupported_special_methods:
fail(fields[-1] + " should not be converted to Argument Clinic! (Yet.)") fail(fields[-1] + " is a special method and cannot be converted to Argument Clinic! (Yet.)")
if not return_converter: if not return_converter:
return_converter = CReturnConverter() return_converter = CReturnConverter()
@ -3007,6 +3110,13 @@ class DSLParser:
self.function = Function(name=function_name, full_name=full_name, module=module, cls=cls, c_basename=c_basename, self.function = Function(name=function_name, full_name=full_name, module=module, cls=cls, c_basename=c_basename,
return_converter=return_converter, kind=self.kind, coexist=self.coexist) return_converter=return_converter, kind=self.kind, coexist=self.coexist)
self.block.signatures.append(self.function) self.block.signatures.append(self.function)
# insert a self converter automatically
_, name = correct_name_for_self(self.function)
sc = self.function.self_converter = self_converter(name, self.function)
p_self = Parameter(sc.name, inspect.Parameter.POSITIONAL_ONLY, function=self.function, converter=sc)
self.function.parameters[sc.name] = p_self
(cls or module).functions.append(self.function) (cls or module).functions.append(self.function)
self.next(self.state_parameters_start) self.next(self.state_parameters_start)
@ -3173,34 +3283,43 @@ class DSLParser:
try: try:
module = ast.parse(ast_input) module = ast.parse(ast_input)
# blacklist of disallowed ast nodes bad = False
class DetectBadNodes(ast.NodeVisitor): if 'c_default' not in kwargs:
bad = False # we can only represent very simple data values in C.
def bad_node(self, node): # detect whether default is okay, via a blacklist
self.bad = True # of disallowed ast nodes.
class DetectBadNodes(ast.NodeVisitor):
bad = False
def bad_node(self, node):
self.bad = True
# inline function call # inline function call
visit_Call = bad_node visit_Call = bad_node
# inline if statement ("x = 3 if y else z") # inline if statement ("x = 3 if y else z")
visit_IfExp = bad_node visit_IfExp = bad_node
# comprehensions and generator expressions # comprehensions and generator expressions
visit_ListComp = visit_SetComp = bad_node visit_ListComp = visit_SetComp = bad_node
visit_DictComp = visit_GeneratorExp = bad_node visit_DictComp = visit_GeneratorExp = bad_node
# literals for advanced types # literals for advanced types
visit_Dict = visit_Set = bad_node visit_Dict = visit_Set = bad_node
visit_List = visit_Tuple = bad_node visit_List = visit_Tuple = bad_node
# "starred": "a = [1, 2, 3]; *a" # "starred": "a = [1, 2, 3]; *a"
visit_Starred = bad_node visit_Starred = bad_node
# allow ellipsis, for now # allow ellipsis, for now
# visit_Ellipsis = bad_node # visit_Ellipsis = bad_node
blacklist = DetectBadNodes() blacklist = DetectBadNodes()
blacklist.visit(module) blacklist.visit(module)
if blacklist.bad: bad = blacklist.bad
else:
# if they specify a c_default, we can be more lenient about the default value.
# but at least ensure that we can turn it into text and reconstitute it correctly.
bad = default != repr(eval(default))
if bad:
fail("Unsupported expression as default value: " + repr(default)) fail("Unsupported expression as default value: " + repr(default))
expr = module.body[0].value expr = module.body[0].value
@ -3263,18 +3382,22 @@ class DSLParser:
fail('{} is not a valid {}converter'.format(name, legacy_str)) fail('{} is not a valid {}converter'.format(name, legacy_str))
converter = dict[name](parameter_name, self.function, value, **kwargs) converter = dict[name](parameter_name, self.function, value, **kwargs)
# special case: if it's the self converter,
# don't actually add it to the parameter list
if isinstance(converter, self_converter):
if self.function.parameters or (self.parameter_state != self.ps_required):
fail("The 'self' parameter, if specified, must be the very first thing in the parameter block.")
if self.function.self_converter:
fail("You can't specify the 'self' parameter more than once.")
self.function.self_converter = converter
self.parameter_state = self.ps_start
return
kind = inspect.Parameter.KEYWORD_ONLY if self.keyword_only else inspect.Parameter.POSITIONAL_OR_KEYWORD kind = inspect.Parameter.KEYWORD_ONLY if self.keyword_only else inspect.Parameter.POSITIONAL_OR_KEYWORD
if isinstance(converter, self_converter):
if len(self.function.parameters) == 1:
if (self.parameter_state != self.ps_required):
fail("A 'self' parameter cannot be marked optional.")
if value is not unspecified:
fail("A 'self' parameter cannot have a default value.")
if self.group:
fail("A 'self' parameter cannot be in an optional group.")
kind = inspect.Parameter.POSITIONAL_ONLY
self.parameter_state = self.ps_start
self.function.parameters.clear()
else:
fail("A 'self' parameter, if specified, must be the very first thing in the parameter block.")
p = Parameter(parameter_name, kind, function=self.function, converter=converter, default=value, group=self.group) p = Parameter(parameter_name, kind, function=self.function, converter=converter, default=value, group=self.group)
if parameter_name in self.function.parameters: if parameter_name in self.function.parameters:
@ -3333,7 +3456,7 @@ class DSLParser:
self.parameter_state = self.ps_seen_slash self.parameter_state = self.ps_seen_slash
# fixup preceeding parameters # fixup preceeding parameters
for p in self.function.parameters.values(): for p in self.function.parameters.values():
if p.kind != inspect.Parameter.POSITIONAL_OR_KEYWORD: if (p.kind != inspect.Parameter.POSITIONAL_OR_KEYWORD and not isinstance(p.converter, self_converter)):
fail("Function " + self.function.name + " mixes keyword-only and positional-only parameters, which is unsupported.") fail("Function " + self.function.name + " mixes keyword-only and positional-only parameters, which is unsupported.")
p.kind = inspect.Parameter.POSITIONAL_ONLY p.kind = inspect.Parameter.POSITIONAL_ONLY
@ -3394,6 +3517,11 @@ class DSLParser:
def format_docstring(self): def format_docstring(self):
f = self.function f = self.function
new_or_init = f.kind in (METHOD_NEW, METHOD_INIT)
if new_or_init and not f.docstring:
# don't render a docstring at all, no signature, nothing.
return f.docstring
add, output = text_accumulator() add, output = text_accumulator()
parameters = list(f.parameters.values()) parameters = list(f.parameters.values())
@ -3401,7 +3529,7 @@ class DSLParser:
## docstring first line ## docstring first line
## ##
if f.kind in (METHOD_NEW, METHOD_INIT): if new_or_init:
assert f.cls assert f.cls
add(f.cls.name) add(f.cls.name)
else: else:
@ -3409,17 +3537,24 @@ class DSLParser:
add('(') add('(')
# populate "right_bracket_count" field for every parameter # populate "right_bracket_count" field for every parameter
if parameters: assert parameters, "We should always have a self parameter. " + repr(f)
assert isinstance(parameters[0].converter, self_converter)
parameters[0].right_bracket_count = 0
parameters_after_self = parameters[1:]
if parameters_after_self:
# for now, the only way Clinic supports positional-only parameters # for now, the only way Clinic supports positional-only parameters
# is if all of them are positional-only. # is if all of them are positional-only...
positional_only_parameters = [p.kind == inspect.Parameter.POSITIONAL_ONLY for p in parameters] #
if parameters[0].kind == inspect.Parameter.POSITIONAL_ONLY: # ... except for self! self is always positional-only.
positional_only_parameters = [p.kind == inspect.Parameter.POSITIONAL_ONLY for p in parameters_after_self]
if parameters_after_self[0].kind == inspect.Parameter.POSITIONAL_ONLY:
assert all(positional_only_parameters) assert all(positional_only_parameters)
for p in parameters: for p in parameters:
p.right_bracket_count = abs(p.group) p.right_bracket_count = abs(p.group)
else: else:
# don't put any right brackets around non-positional-only parameters, ever. # don't put any right brackets around non-positional-only parameters, ever.
for p in parameters: for p in parameters_after_self:
p.right_bracket_count = 0 p.right_bracket_count = 0
right_bracket_count = 0 right_bracket_count = 0
@ -3439,6 +3574,9 @@ class DSLParser:
add_comma = False add_comma = False
for p in parameters: for p in parameters:
if not p.converter.show_in_signature:
continue
assert p.name assert p.name
if p.is_keyword_only() and not added_star: if p.is_keyword_only() and not added_star:
@ -3446,8 +3584,10 @@ class DSLParser:
if add_comma: if add_comma:
add(', ') add(', ')
add('*') add('*')
add_comma = True
a = [p.name] name = p.converter.signature_name or p.name
a = [name]
if p.converter.is_optional(): if p.converter.is_optional():
a.append('=') a.append('=')
value = p.converter.py_default value = p.converter.py_default
@ -3560,9 +3700,6 @@ class DSLParser:
if not self.function: if not self.function:
return return
if not self.function.self_converter:
self.function.self_converter = self_converter("self", self.function)
if self.keyword_only: if self.keyword_only:
values = self.function.parameters.values() values = self.function.parameters.values()
if not values: if not values:
@ -3582,6 +3719,8 @@ class DSLParser:
self.function.docstring = self.format_docstring() self.function.docstring = self.format_docstring()
# maps strings to callables. # maps strings to callables.
# the callable should return an object # the callable should return an object
# that implements the clinic parser # that implements the clinic parser
@ -3607,6 +3746,7 @@ def main(argv):
cmdline = argparse.ArgumentParser() cmdline = argparse.ArgumentParser()
cmdline.add_argument("-f", "--force", action='store_true') cmdline.add_argument("-f", "--force", action='store_true')
cmdline.add_argument("-o", "--output", type=str) cmdline.add_argument("-o", "--output", type=str)
cmdline.add_argument("-v", "--verbose", action='store_true')
cmdline.add_argument("--converters", action='store_true') cmdline.add_argument("--converters", action='store_true')
cmdline.add_argument("--make", action='store_true') cmdline.add_argument("--make", action='store_true')
cmdline.add_argument("filename", type=str, nargs="*") cmdline.add_argument("filename", type=str, nargs="*")
@ -3680,13 +3820,15 @@ def main(argv):
cmdline.print_usage() cmdline.print_usage()
sys.exit(-1) sys.exit(-1)
for root, dirs, files in os.walk('.'): for root, dirs, files in os.walk('.'):
for rcs_dir in ('.svn', '.git', '.hg'): for rcs_dir in ('.svn', '.git', '.hg', 'build'):
if rcs_dir in dirs: if rcs_dir in dirs:
dirs.remove(rcs_dir) dirs.remove(rcs_dir)
for filename in files: for filename in files:
if not filename.endswith('.c'): if not (filename.endswith('.c') or filename.endswith('.h')):
continue continue
path = os.path.join(root, filename) path = os.path.join(root, filename)
if ns.verbose:
print(path)
parse_file(path, verify=not ns.force) parse_file(path, verify=not ns.force)
return return
@ -3701,6 +3843,8 @@ def main(argv):
sys.exit(-1) sys.exit(-1)
for filename in ns.filename: for filename in ns.filename:
if ns.verbose:
print(filename)
parse_file(filename, output=ns.output, verify=not ns.force) parse_file(filename, output=ns.output, verify=not ns.force)