[Python-checkins] cpython: Issue #20189: Four additional builtin types (PyTypeObject,

larry.hastings python-checkins at python.org
Fri Jan 24 15:17:46 CET 2014


http://hg.python.org/cpython/rev/85710aa396ef
changeset:   88668:85710aa396ef
user:        Larry Hastings <larry at hastings.org>
date:        Fri Jan 24 06:17:25 2014 -0800
summary:
  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.

files:
  Doc/library/inspect.rst                |    3 +
  Include/object.h                       |    3 +
  Lib/idlelib/idle_test/test_calltips.py |   15 +-
  Lib/inspect.py                         |   32 +-
  Lib/pydoc.py                           |   13 +-
  Lib/test/test_capi.py                  |    6 +-
  Lib/test/test_generators.py            |    4 +-
  Lib/test/test_genexps.py               |    4 +-
  Lib/test/test_inspect.py               |  100 +-
  Lib/unittest/mock.py                   |   19 +-
  Misc/NEWS                              |   20 +-
  Modules/_cryptmodule.c                 |    4 +-
  Modules/_cursesmodule.c                |    4 +-
  Modules/_datetimemodule.c              |   14 +-
  Modules/_dbmmodule.c                   |   12 +-
  Modules/_opcode.c                      |    4 +-
  Modules/_pickle.c                      |  110 +-
  Modules/_sre.c                         |    8 +-
  Modules/_testcapimodule.c              |    8 +-
  Modules/_weakref.c                     |    4 +-
  Modules/posixmodule.c                  |   12 +-
  Modules/unicodedata.c                  |    4 +-
  Modules/zlibmodule.c                   |   20 +-
  Objects/descrobject.c                  |   55 +-
  Objects/dictobject.c                   |   71 +-
  Objects/methodobject.c                 |   67 +-
  Objects/typeobject.c                   |  245 ++++-
  Objects/unicodeobject.c                |    8 +-
  Python/bltinmodule.c                   |    2 +-
  Python/import.c                        |   48 +-
  Tools/clinic/clinic.py                 |  478 ++++++++----
  31 files changed, 870 insertions(+), 527 deletions(-)


diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst
--- a/Doc/library/inspect.rst
+++ b/Doc/library/inspect.rst
@@ -429,6 +429,9 @@
    Accepts a wide range of python callables, from plain functions and classes to
    :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::
 
       Some callables may not be introspectable in certain implementations of
diff --git a/Include/object.h b/Include/object.h
--- a/Include/object.h
+++ b/Include/object.h
@@ -492,6 +492,9 @@
 PyAPI_FUNC(unsigned int) PyType_ClearCache(void);
 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 */
 struct _Py_Identifier;
 #ifndef Py_LIMITED_API
diff --git a/Lib/idlelib/idle_test/test_calltips.py b/Lib/idlelib/idle_test/test_calltips.py
--- a/Lib/idlelib/idle_test/test_calltips.py
+++ b/Lib/idlelib/idle_test/test_calltips.py
@@ -55,24 +55,27 @@
         gtest(list.__new__,
                'T.__new__(S, ...) -> a new object with type S, a subtype of T')
         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"
         gtest(list.append, append_doc)
         gtest([].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)
 
     def test_multiline_docstring(self):
         # Test fewer lines than max.
-        self.assertEqual(signature(list),
-                "list() -> new empty list\n"
-                "list(iterable) -> new list initialized from iterable's items")
+        self.assertEqual(signature(dict),
+                "dict(mapping) -> new dictionary initialized from a mapping object's\n"
+                "(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.
         self.assertEqual(signature(bytes),
-"bytes(iterable_of_ints) -> bytes\n"
 "bytes(string, encoding[, errors]) -> bytes\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
diff --git a/Lib/inspect.py b/Lib/inspect.py
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -1419,9 +1419,11 @@
 
 _WrapperDescriptor = type(type.__call__)
 _MethodWrapper = type(all.__call__)
+_ClassMethodWrapper = type(int.__dict__['from_bytes'])
 
 _NonUserDefinedCallables = (_WrapperDescriptor,
                             _MethodWrapper,
+                            _ClassMethodWrapper,
                             types.BuiltinFunctionType)
 
 
@@ -1443,6 +1445,13 @@
     if not callable(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):
         # In this case we skip the first parameter of the underlying
         # function (usually `self` or `cls`).
@@ -1460,13 +1469,9 @@
         if sig is not None:
             return sig
 
-
     if isinstance(obj, types.FunctionType):
         return Signature.from_function(obj)
 
-    if isinstance(obj, types.BuiltinFunctionType):
-        return Signature.from_builtin(obj)
-
     if isinstance(obj, functools.partial):
         sig = signature(obj.func)
 
@@ -2033,7 +2038,7 @@
             name = parse_name(name_node)
             if name is invalid:
                 return None
-            if default_node:
+            if default_node and default_node is not _empty:
                 try:
                     default_node = RewriteSymbolics().visit(default_node)
                     o = ast.literal_eval(default_node)
@@ -2066,6 +2071,23 @@
             kind = Parameter.VAR_KEYWORD
             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)
 
 
diff --git a/Lib/pydoc.py b/Lib/pydoc.py
--- a/Lib/pydoc.py
+++ b/Lib/pydoc.py
@@ -925,7 +925,10 @@
                 anchor, name, reallink)
         argspec = None
         if inspect.isfunction(object) or inspect.isbuiltin(object):
-            signature = inspect.signature(object)
+            try:
+                signature = inspect.signature(object)
+            except (ValueError, TypeError):
+                signature = None
             if signature:
                 argspec = str(signature)
                 if realname == '<lambda>':
@@ -1319,8 +1322,12 @@
                 skipdocs = 1
             title = self.bold(name) + ' = ' + realname
         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:
                 argspec = str(signature)
                 if realname == '<lambda>':
diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py
--- a/Lib/test/test_capi.py
+++ b/Lib/test/test_capi.py
@@ -125,7 +125,7 @@
         self.assertEqual(_testcapi.docstring_no_signature.__text_signature__, None)
 
         self.assertEqual(_testcapi.docstring_with_invalid_signature.__doc__,
-            "docstring_with_invalid_signature (boo)\n"
+            "docstring_with_invalid_signature (module, boo)\n"
             "\n"
             "This docstring has an invalid signature."
             )
@@ -133,12 +133,12 @@
 
         self.assertEqual(_testcapi.docstring_with_signature.__doc__,
             "This docstring has a valid signature.")
-        self.assertEqual(_testcapi.docstring_with_signature.__text_signature__, "(sig)")
+        self.assertEqual(_testcapi.docstring_with_signature.__text_signature__, "(module, sig)")
 
         self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__doc__,
             "This docstring has a valid signature and some extra newlines.")
         self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__text_signature__,
-            "(parameter)")
+            "(module, parameter)")
 
 
 @unittest.skipUnless(threading, 'Threading required for this test.')
diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py
--- a/Lib/test/test_generators.py
+++ b/Lib/test/test_generators.py
@@ -436,8 +436,8 @@
 >>> [s for s in dir(i) if not s.startswith('_')]
 ['close', 'gi_code', 'gi_frame', 'gi_running', 'send', 'throw']
 >>> from test.support import HAVE_DOCSTRINGS
->>> print(i.__next__.__doc__ if HAVE_DOCSTRINGS else 'x.__next__() <==> next(x)')
-x.__next__() <==> next(x)
+>>> print(i.__next__.__doc__ if HAVE_DOCSTRINGS else 'Implements next(self).')
+Implements next(self).
 >>> iter(i) is i
 True
 >>> import types
diff --git a/Lib/test/test_genexps.py b/Lib/test/test_genexps.py
--- a/Lib/test/test_genexps.py
+++ b/Lib/test/test_genexps.py
@@ -222,8 +222,8 @@
     True
 
     >>> from test.support import HAVE_DOCSTRINGS
-    >>> print(g.__next__.__doc__ if HAVE_DOCSTRINGS else 'x.__next__() <==> next(x)')
-    x.__next__() <==> next(x)
+    >>> print(g.__next__.__doc__ if HAVE_DOCSTRINGS else 'Implements next(self).')
+    Implements next(self).
     >>> import types
     >>> isinstance(g, types.GeneratorType)
     True
diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py
--- a/Lib/test/test_inspect.py
+++ b/Lib/test/test_inspect.py
@@ -1,21 +1,25 @@
+import _testcapi
+import collections
+import datetime
+import functools
+import importlib
+import inspect
+import io
+import linecache
+import os
+from os.path import normcase
+import _pickle
 import re
+import shutil
 import sys
 import types
+import unicodedata
 import unittest
-import inspect
-import linecache
-import datetime
-import collections
-import os
-import shutil
-import functools
-import importlib
-from os.path import normcase
+
 try:
     from concurrent.futures import ThreadPoolExecutor
 except ImportError:
     ThreadPoolExecutor = None
-import _testcapi
 
 from test.support import run_unittest, TESTFN, DirsOnSysPath
 from test.support import MISSING_C_DOCSTRINGS
@@ -23,8 +27,6 @@
 from test import inspect_fodder as mod
 from test import inspect_fodder2 as mod2
 
-# C module for test_findsource_binary
-import unicodedata
 
 # Functions tested in this suite:
 # ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
@@ -1582,23 +1584,30 @@
                           ...))
 
     def test_signature_on_unsupported_builtins(self):
-        with self.assertRaisesRegex(ValueError, 'not supported by signature'):
-            inspect.signature(type)
-        with self.assertRaisesRegex(ValueError, 'not supported by signature'):
-            # support for 'wrapper_descriptor'
-            inspect.signature(type.__call__)
-        with self.assertRaisesRegex(ValueError, 'not supported by signature'):
-            # support for 'method-wrapper'
-            inspect.signature(min.__call__)
+        with self.assertRaisesRegex(ValueError, 'no signature found'):
+            # min simply doesn't have a signature (yet)
+            inspect.signature(min)
 
     @unittest.skipIf(MISSING_C_DOCSTRINGS,
                      "Signature information for builtins requires docstrings")
     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)
-        self.assertTrue(isinstance(signature, inspect.Signature))
+
+        def test_unbound_method(o):
+            """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
         self.assertEqual(p('s'), 'avocado')
         self.assertEqual(p('b'), b'bytes')
@@ -1611,6 +1620,41 @@
         self.assertEqual(p('sys'), sys.maxsize)
         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):
         with self.assertRaisesRegex(TypeError, 'is not a callable object'):
             inspect.signature(42)
@@ -1985,12 +2029,6 @@
                          ((('a', ..., ..., "positional_or_keyword"),),
                           ...))
 
-        class ToFail:
-            __call__ = type
-        with self.assertRaisesRegex(ValueError, "not supported by signature"):
-            inspect.signature(ToFail())
-
-
         class Wrapped:
             pass
         Wrapped.__wrapped__ = lambda a: None
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -112,11 +112,24 @@
 def _copy_func_details(func, funcopy):
     funcopy.__name__ = func.__name__
     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
     # expose original attributes that should be mocked
-    funcopy.__module__ = func.__module__
-    funcopy.__defaults__ = func.__defaults__
-    funcopy.__kwdefaults__ = func.__kwdefaults__
+    try:
+        funcopy.__module__ = func.__module__
+    except AttributeError:
+        pass
+    try:
+        funcopy.__defaults__ = func.__defaults__
+    except AttributeError:
+        pass
+    try:
+        funcopy.__kwdefaults__ = func.__kwdefaults__
+    except AttributeError:
+        pass
 
 
 def _callable(obj):
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,10 @@
 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
   IndentationError.
 
@@ -32,6 +36,10 @@
 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
   zero, instead of rounding towards zero. For example, a timeout of one
   microsecond is now rounded to one millisecond, instead of being rounded to
@@ -122,7 +130,7 @@
 
 --Issue #17390: Add Python version to Idle editor window title bar.
   Original patches by Edmond Burnett and Kent Johnson.
-  
+
 - Issue #18960: IDLE now ignores the source encoding declaration on the second
   line if the first line contains anything except a comment.
 
@@ -133,6 +141,16 @@
 
 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
   __init__ functions.
diff --git a/Modules/_cryptmodule.c b/Modules/_cryptmodule.c
--- a/Modules/_cryptmodule.c
+++ b/Modules/_cryptmodule.c
@@ -30,7 +30,7 @@
 [clinic start generated code]*/
 
 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"
 "\n"
 "*word* will usually be a user\'s password.  *salt* (either a random 2 or 16\n"
@@ -63,7 +63,7 @@
 
 static PyObject *
 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
        salt. Return None in that case. XXX Maybe raise an exception?  */
diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c
--- a/Modules/_cursesmodule.c
+++ b/Modules/_cursesmodule.c
@@ -584,7 +584,7 @@
 [clinic start generated code]*/
 
 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"
 "\n"
 "  x\n"
@@ -651,7 +651,7 @@
 
 static PyObject *
 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;
     int coordinates_group = group_left_1;
diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c
--- a/Modules/_datetimemodule.c
+++ b/Modules/_datetimemodule.c
@@ -4159,7 +4159,7 @@
 [clinic start generated code]*/
 
 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"
 "\n"
 "  tz\n"
@@ -4171,10 +4171,10 @@
     {"now", (PyCFunction)datetime_datetime_now, METH_VARARGS|METH_KEYWORDS|METH_CLASS, datetime_datetime_now__doc__},
 
 static PyObject *
-datetime_datetime_now_impl(PyTypeObject *cls, PyObject *tz);
+datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz);
 
 static PyObject *
-datetime_datetime_now(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
+datetime_datetime_now(PyTypeObject *type, PyObject *args, PyObject *kwargs)
 {
     PyObject *return_value = NULL;
     static char *_keywords[] = {"tz", NULL};
@@ -4184,15 +4184,15 @@
         "|O:now", _keywords,
         &tz))
         goto exit;
-    return_value = datetime_datetime_now_impl(cls, tz);
+    return_value = datetime_datetime_now_impl(type, tz);
 
 exit:
     return return_value;
 }
 
 static PyObject *
-datetime_datetime_now_impl(PyTypeObject *cls, PyObject *tz)
-/*[clinic end generated code: checksum=ca3d26a423b3f633b260c7622e303f0915a96f7c]*/
+datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
+/*[clinic end generated code: checksum=a6d3ad2c0ab6389075289af3467f7b8eb13f5f5c]*/
 {
     PyObject *self;
 
@@ -4202,7 +4202,7 @@
     if (check_tzinfo_subclass(tz) < 0)
         return NULL;
 
-    self = datetime_best_possible((PyObject *)cls,
+    self = datetime_best_possible((PyObject *)type,
                                   tz == Py_None ? localtime : gmtime,
                                   tz);
     if (self != NULL && tz != Py_None) {
diff --git a/Modules/_dbmmodule.c b/Modules/_dbmmodule.c
--- a/Modules/_dbmmodule.c
+++ b/Modules/_dbmmodule.c
@@ -279,7 +279,7 @@
 [clinic start generated code]*/
 
 PyDoc_STRVAR(dbm_dbm_get__doc__,
-"get(key, [default])\n"
+"get(self, key, [default])\n"
 "Return the value for key if present, otherwise default.");
 
 #define DBM_DBM_GET_METHODDEF    \
@@ -289,7 +289,7 @@
 dbm_dbm_get_impl(dbmobject *dp, const char *key, Py_ssize_clean_t key_length, int group_right_1, PyObject *default_value);
 
 static PyObject *
-dbm_dbm_get(PyObject *self, PyObject *args)
+dbm_dbm_get(dbmobject *dp, PyObject *args)
 {
     PyObject *return_value = NULL;
     const char *key;
@@ -311,7 +311,7 @@
             PyErr_SetString(PyExc_TypeError, "dbm.dbm.get requires 1 to 2 arguments");
             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:
     return return_value;
@@ -319,7 +319,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)
-/*[clinic end generated code: checksum=ca8bf63ec226e71d3cf390749777f7d5b7361478]*/
+/*[clinic end generated code: checksum=31d5180d6b36f1eafea78ec4391adf3559916379]*/
 {
     datum dbm_key, val;
 
@@ -462,7 +462,7 @@
 [clinic start generated code]*/
 
 PyDoc_STRVAR(dbmopen__doc__,
-"open(filename, flags=\'r\', mode=0o666)\n"
+"open(module, filename, flags=\'r\', mode=0o666)\n"
 "Return a database object.\n"
 "\n"
 "  filename\n"
@@ -499,7 +499,7 @@
 
 static PyObject *
 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;
 
diff --git a/Modules/_opcode.c b/Modules/_opcode.c
--- a/Modules/_opcode.c
+++ b/Modules/_opcode.c
@@ -21,7 +21,7 @@
 [clinic start generated code]*/
 
 PyDoc_STRVAR(_opcode_stack_effect__doc__,
-"stack_effect(opcode, [oparg])\n"
+"stack_effect(module, opcode, [oparg])\n"
 "Compute the stack effect of the opcode.");
 
 #define _OPCODE_STACK_EFFECT_METHODDEF    \
@@ -64,7 +64,7 @@
 
 static int
 _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;
     if (HAS_ARG(opcode)) {
diff --git a/Modules/_pickle.c b/Modules/_pickle.c
--- a/Modules/_pickle.c
+++ b/Modules/_pickle.c
@@ -3889,7 +3889,7 @@
 [clinic start generated code]*/
 
 PyDoc_STRVAR(_pickle_Pickler_clear_memo__doc__,
-"clear_memo()\n"
+"clear_memo(self)\n"
 "Clears the pickler\'s \"memo\".\n"
 "\n"
 "The memo is the data structure that remembers which objects the\n"
@@ -3904,14 +3904,14 @@
 _pickle_Pickler_clear_memo_impl(PicklerObject *self);
 
 static PyObject *
-_pickle_Pickler_clear_memo(PyObject *self, PyObject *Py_UNUSED(ignored))
-{
-    return _pickle_Pickler_clear_memo_impl((PicklerObject *)self);
+_pickle_Pickler_clear_memo(PicklerObject *self, PyObject *Py_UNUSED(ignored))
+{
+    return _pickle_Pickler_clear_memo_impl(self);
 }
 
 static PyObject *
 _pickle_Pickler_clear_memo_impl(PicklerObject *self)
-/*[clinic end generated code: checksum=015cc3c5befea86cb08b9396938477bebbea4157]*/
+/*[clinic end generated code: checksum=17b1165d8dcae5a2e90b1703bf5cbbfc26114c5a]*/
 {
     if (self->memo)
         PyMemoTable_Clear(self->memo);
@@ -3931,7 +3931,7 @@
 [clinic start generated code]*/
 
 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.");
 
 #define _PICKLE_PICKLER_DUMP_METHODDEF    \
@@ -3939,7 +3939,7 @@
 
 static PyObject *
 _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).
        Developers often forget to call __init__() in their subclasses, which
@@ -4077,7 +4077,7 @@
     int fix_imports = 1;
 
     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
-        "O|Op:__init__", _keywords,
+        "O|Op:Pickler", _keywords,
         &file, &protocol, &fix_imports))
         goto exit;
     return_value = _pickle_Pickler___init___impl((PicklerObject *)self, file, protocol, fix_imports);
@@ -4088,7 +4088,7 @@
 
 static int
 _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(dispatch_table);
@@ -4164,7 +4164,7 @@
 [clinic start generated code]*/
 
 PyDoc_STRVAR(_pickle_PicklerMemoProxy_clear__doc__,
-"clear()\n"
+"clear(self)\n"
 "Remove all items from memo.");
 
 #define _PICKLE_PICKLERMEMOPROXY_CLEAR_METHODDEF    \
@@ -4174,14 +4174,14 @@
 _pickle_PicklerMemoProxy_clear_impl(PicklerMemoProxyObject *self);
 
 static PyObject *
-_pickle_PicklerMemoProxy_clear(PyObject *self, PyObject *Py_UNUSED(ignored))
-{
-    return _pickle_PicklerMemoProxy_clear_impl((PicklerMemoProxyObject *)self);
+_pickle_PicklerMemoProxy_clear(PicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored))
+{
+    return _pickle_PicklerMemoProxy_clear_impl(self);
 }
 
 static PyObject *
 _pickle_PicklerMemoProxy_clear_impl(PicklerMemoProxyObject *self)
-/*[clinic end generated code: checksum=bf8dd8c8688d0c0f7a2e59a804c47375b740f2f0]*/
+/*[clinic end generated code: checksum=fb4a5ba40918b3eccc9bc1e9d6875cb2737127a9]*/
 {
     if (self->pickler->memo)
         PyMemoTable_Clear(self->pickler->memo);
@@ -4197,7 +4197,7 @@
 [clinic start generated code]*/
 
 PyDoc_STRVAR(_pickle_PicklerMemoProxy_copy__doc__,
-"copy()\n"
+"copy(self)\n"
 "Copy the memo to a new object.");
 
 #define _PICKLE_PICKLERMEMOPROXY_COPY_METHODDEF    \
@@ -4207,14 +4207,14 @@
 _pickle_PicklerMemoProxy_copy_impl(PicklerMemoProxyObject *self);
 
 static PyObject *
-_pickle_PicklerMemoProxy_copy(PyObject *self, PyObject *Py_UNUSED(ignored))
-{
-    return _pickle_PicklerMemoProxy_copy_impl((PicklerMemoProxyObject *)self);
+_pickle_PicklerMemoProxy_copy(PicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored))
+{
+    return _pickle_PicklerMemoProxy_copy_impl(self);
 }
 
 static PyObject *
 _pickle_PicklerMemoProxy_copy_impl(PicklerMemoProxyObject *self)
-/*[clinic end generated code: checksum=72d46879dc658adbd3d28b5c82dd8dcfa6b9b124]*/
+/*[clinic end generated code: checksum=3d27d3005725f1828c9a92a38197811c54c64abb]*/
 {
     Py_ssize_t i;
     PyMemoTable *memo;
@@ -4260,7 +4260,7 @@
 [clinic start generated code]*/
 
 PyDoc_STRVAR(_pickle_PicklerMemoProxy___reduce____doc__,
-"__reduce__()\n"
+"__reduce__(self)\n"
 "Implement pickle support.");
 
 #define _PICKLE_PICKLERMEMOPROXY___REDUCE___METHODDEF    \
@@ -4270,14 +4270,14 @@
 _pickle_PicklerMemoProxy___reduce___impl(PicklerMemoProxyObject *self);
 
 static PyObject *
-_pickle_PicklerMemoProxy___reduce__(PyObject *self, PyObject *Py_UNUSED(ignored))
-{
-    return _pickle_PicklerMemoProxy___reduce___impl((PicklerMemoProxyObject *)self);
+_pickle_PicklerMemoProxy___reduce__(PicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored))
+{
+    return _pickle_PicklerMemoProxy___reduce___impl(self);
 }
 
 static PyObject *
 _pickle_PicklerMemoProxy___reduce___impl(PicklerMemoProxyObject *self)
-/*[clinic end generated code: checksum=aad71c4d81d1ed8bf0d32362dd80a29b9f3b0d03]*/
+/*[clinic end generated code: checksum=2682cf8a3a5027def6328419001b086b047d47c8]*/
 {
     PyObject *reduce_value, *dict_args;
     PyObject *contents = _pickle_PicklerMemoProxy_copy_impl(self);
@@ -6299,7 +6299,7 @@
 [clinic start generated code]*/
 
 PyDoc_STRVAR(_pickle_Unpickler_load__doc__,
-"load()\n"
+"load(self)\n"
 "Load a pickle.\n"
 "\n"
 "Read a pickled object representation from the open file object given\n"
@@ -6320,7 +6320,7 @@
 
 static PyObject *
 _pickle_Unpickler_load_impl(PyObject *self)
-/*[clinic end generated code: checksum=9477099fe6a90748c13ff1a6dd92ba7ab7a89602]*/
+/*[clinic end generated code: checksum=fb1119422c5e03045d690d1cd6c457f1ca4c585d]*/
 {
     UnpicklerObject *unpickler = (UnpicklerObject*)self;
 
@@ -6363,7 +6363,7 @@
 [clinic start generated code]*/
 
 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"
 "\n"
 "If necessary, the module will be imported. Subclasses may override\n"
@@ -6380,7 +6380,7 @@
 _pickle_Unpickler_find_class_impl(UnpicklerObject *self, PyObject *module_name, PyObject *global_name);
 
 static PyObject *
-_pickle_Unpickler_find_class(PyObject *self, PyObject *args)
+_pickle_Unpickler_find_class(UnpicklerObject *self, PyObject *args)
 {
     PyObject *return_value = NULL;
     PyObject *module_name;
@@ -6390,7 +6390,7 @@
         2, 2,
         &module_name, &global_name))
         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:
     return return_value;
@@ -6398,7 +6398,7 @@
 
 static PyObject *
 _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 *modules_dict;
@@ -6617,7 +6617,7 @@
     const char *errors = "strict";
 
     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
-        "O|$pss:__init__", _keywords,
+        "O|$pss:Unpickler", _keywords,
         &file, &fix_imports, &encoding, &errors))
         goto exit;
     return_value = _pickle_Unpickler___init___impl((UnpicklerObject *)self, file, fix_imports, encoding, errors);
@@ -6628,7 +6628,7 @@
 
 static int
 _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);
 
@@ -6698,7 +6698,7 @@
 [clinic start generated code]*/
 
 PyDoc_STRVAR(_pickle_UnpicklerMemoProxy_clear__doc__,
-"clear()\n"
+"clear(self)\n"
 "Remove all items from memo.");
 
 #define _PICKLE_UNPICKLERMEMOPROXY_CLEAR_METHODDEF    \
@@ -6708,14 +6708,14 @@
 _pickle_UnpicklerMemoProxy_clear_impl(UnpicklerMemoProxyObject *self);
 
 static PyObject *
-_pickle_UnpicklerMemoProxy_clear(PyObject *self, PyObject *Py_UNUSED(ignored))
-{
-    return _pickle_UnpicklerMemoProxy_clear_impl((UnpicklerMemoProxyObject *)self);
+_pickle_UnpicklerMemoProxy_clear(UnpicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored))
+{
+    return _pickle_UnpicklerMemoProxy_clear_impl(self);
 }
 
 static PyObject *
 _pickle_UnpicklerMemoProxy_clear_impl(UnpicklerMemoProxyObject *self)
-/*[clinic end generated code: checksum=07adecee2181e5e268b2ff184360b1d88ad947f2]*/
+/*[clinic end generated code: checksum=32f6ee47e44405dd587f768f3690d47947bb5a8e]*/
 {
     _Unpickler_MemoCleanup(self->unpickler);
     self->unpickler->memo = _Unpickler_NewMemo(self->unpickler->memo_size);
@@ -6733,7 +6733,7 @@
 [clinic start generated code]*/
 
 PyDoc_STRVAR(_pickle_UnpicklerMemoProxy_copy__doc__,
-"copy()\n"
+"copy(self)\n"
 "Copy the memo to a new object.");
 
 #define _PICKLE_UNPICKLERMEMOPROXY_COPY_METHODDEF    \
@@ -6743,14 +6743,14 @@
 _pickle_UnpicklerMemoProxy_copy_impl(UnpicklerMemoProxyObject *self);
 
 static PyObject *
-_pickle_UnpicklerMemoProxy_copy(PyObject *self, PyObject *Py_UNUSED(ignored))
-{
-    return _pickle_UnpicklerMemoProxy_copy_impl((UnpicklerMemoProxyObject *)self);
+_pickle_UnpicklerMemoProxy_copy(UnpicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored))
+{
+    return _pickle_UnpicklerMemoProxy_copy_impl(self);
 }
 
 static PyObject *
 _pickle_UnpicklerMemoProxy_copy_impl(UnpicklerMemoProxyObject *self)
-/*[clinic end generated code: checksum=47b9f0cc12c5a54004252e1b4916822cdfa8a881]*/
+/*[clinic end generated code: checksum=ac3da80efc3b2548aa8b5c5358d0e82e615fce1d]*/
 {
     Py_ssize_t i;
     PyObject *new_memo = PyDict_New();
@@ -6789,7 +6789,7 @@
 [clinic start generated code]*/
 
 PyDoc_STRVAR(_pickle_UnpicklerMemoProxy___reduce____doc__,
-"__reduce__()\n"
+"__reduce__(self)\n"
 "Implement pickling support.");
 
 #define _PICKLE_UNPICKLERMEMOPROXY___REDUCE___METHODDEF    \
@@ -6799,14 +6799,14 @@
 _pickle_UnpicklerMemoProxy___reduce___impl(UnpicklerMemoProxyObject *self);
 
 static PyObject *
-_pickle_UnpicklerMemoProxy___reduce__(PyObject *self, PyObject *Py_UNUSED(ignored))
-{
-    return _pickle_UnpicklerMemoProxy___reduce___impl((UnpicklerMemoProxyObject *)self);
+_pickle_UnpicklerMemoProxy___reduce__(UnpicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored))
+{
+    return _pickle_UnpicklerMemoProxy___reduce___impl(self);
 }
 
 static PyObject *
 _pickle_UnpicklerMemoProxy___reduce___impl(UnpicklerMemoProxyObject *self)
-/*[clinic end generated code: checksum=2f061bb9ecd9ee8500184c135148a131c46a3b88]*/
+/*[clinic end generated code: checksum=2373102b7c87d99ba4c4a56b6813d2c84dd61865]*/
 {
     PyObject *reduce_value;
     PyObject *constructor_args;
@@ -7115,7 +7115,7 @@
 [clinic start generated code]*/
 
 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"
 "\n"
 "This is equivalent to ``Pickler(file, protocol).dump(obj)``, but may\n"
@@ -7166,7 +7166,7 @@
 
 static PyObject *
 _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();
 
@@ -7218,7 +7218,7 @@
 [clinic start generated code]*/
 
 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"
 "\n"
 "The optional *protocol* argument tells the pickler to use the given\n"
@@ -7260,7 +7260,7 @@
 
 static PyObject *
 _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;
     PicklerObject *pickler = _Pickler_New();
@@ -7319,7 +7319,7 @@
 [clinic start generated code]*/
 
 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"
 "\n"
 "This is equivalent to ``Unpickler(file).load()``, but may be more\n"
@@ -7372,7 +7372,7 @@
 
 static PyObject *
 _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;
     UnpicklerObject *unpickler = _Unpickler_New();
@@ -7424,7 +7424,7 @@
 [clinic start generated code]*/
 
 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"
 "\n"
 "The protocol version of the pickle is detected automatically, so no\n"
@@ -7468,7 +7468,7 @@
 
 static PyObject *
 _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;
     UnpicklerObject *unpickler = _Unpickler_New();
diff --git a/Modules/_sre.c b/Modules/_sre.c
--- a/Modules/_sre.c
+++ b/Modules/_sre.c
@@ -541,7 +541,7 @@
 [clinic start generated code]*/
 
 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.");
 
 #define PATTERN_MATCH_METHODDEF    \
@@ -551,7 +551,7 @@
 pattern_match_impl(PatternObject *self, PyObject *pattern, Py_ssize_t pos, Py_ssize_t endpos);
 
 static PyObject *
-pattern_match(PyObject *self, PyObject *args, PyObject *kwargs)
+pattern_match(PatternObject *self, PyObject *args, PyObject *kwargs)
 {
     PyObject *return_value = NULL;
     static char *_keywords[] = {"pattern", "pos", "endpos", NULL};
@@ -563,7 +563,7 @@
         "O|nn:match", _keywords,
         &pattern, &pos, &endpos))
         goto exit;
-    return_value = pattern_match_impl((PatternObject *)self, pattern, pos, endpos);
+    return_value = pattern_match_impl(self, pattern, pos, endpos);
 
 exit:
     return return_value;
@@ -571,7 +571,7 @@
 
 static PyObject *
 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;
     Py_ssize_t status;
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -2851,18 +2851,18 @@
 );
 
 PyDoc_STRVAR(docstring_with_invalid_signature,
-"docstring_with_invalid_signature (boo)\n"
+"docstring_with_invalid_signature (module, boo)\n"
 "\n"
 "This docstring has an invalid signature."
 );
 
 PyDoc_STRVAR(docstring_with_signature,
-"docstring_with_signature(sig)\n"
+"docstring_with_signature(module, sig)\n"
 "This docstring has a valid signature."
 );
 
 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"
@@ -2870,7 +2870,7 @@
 );
 
 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"
diff --git a/Modules/_weakref.c b/Modules/_weakref.c
--- a/Modules/_weakref.c
+++ b/Modules/_weakref.c
@@ -20,7 +20,7 @@
 [clinic start generated code]*/
 
 PyDoc_STRVAR(_weakref_getweakrefcount__doc__,
-"getweakrefcount(object)\n"
+"getweakrefcount(module, object)\n"
 "Return the number of weak references to \'object\'.");
 
 #define _WEAKREF_GETWEAKREFCOUNT_METHODDEF    \
@@ -46,7 +46,7 @@
 
 static Py_ssize_t
 _weakref_getweakrefcount_impl(PyModuleDef *module, PyObject *object)
-/*[clinic end generated code: checksum=744fa73ba68c0ee89567e9cb9bea11863270d516]*/
+/*[clinic end generated code: checksum=dd8ba0730babf263d3db78d260ea7eacf6eb3735]*/
 {
     PyWeakReference **list;
 
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -2430,7 +2430,7 @@
 [clinic start generated code]*/
 
 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"
 "\n"
 "  path\n"
@@ -2481,7 +2481,7 @@
 
 static PyObject *
 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);
 }
@@ -2562,7 +2562,7 @@
 [clinic start generated code]*/
 
 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"
 "\n"
 "  path\n"
@@ -2622,7 +2622,7 @@
 
 static PyObject *
 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;
 
@@ -2718,7 +2718,7 @@
 [clinic start generated code]*/
 
 PyDoc_STRVAR(os_ttyname__doc__,
-"ttyname(fd)\n"
+"ttyname(module, fd)\n"
 "Return the name of the terminal device connected to \'fd\'.\n"
 "\n"
 "  fd\n"
@@ -2752,7 +2752,7 @@
 
 static char *
 os_ttyname_impl(PyModuleDef *module, int fd)
-/*[clinic end generated code: checksum=0f368134dc0a7f21f25185e2e6bacf7675fb473a]*/
+/*[clinic end generated code: checksum=11bbb8b7969155f54bb8a1ec35ac1ebdfd4b0fec]*/
 {
     char *ret;
 
diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c
--- a/Modules/unicodedata.c
+++ b/Modules/unicodedata.c
@@ -129,7 +129,7 @@
 [clinic start generated code]*/
 
 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"
 "\n"
 "Returns the decimal value assigned to the Unicode character unichr\n"
@@ -161,7 +161,7 @@
 
 static PyObject *
 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;
     int have_old = 0;
diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c
--- a/Modules/zlibmodule.c
+++ b/Modules/zlibmodule.c
@@ -180,7 +180,7 @@
 [clinic start generated code]*/
 
 PyDoc_STRVAR(zlib_compress__doc__,
-"compress(bytes, [level])\n"
+"compress(module, bytes, [level])\n"
 "Returns compressed string.\n"
 "\n"
 "  bytes\n"
@@ -228,7 +228,7 @@
 
 static PyObject *
 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;
     Byte *input, *output = NULL;
@@ -766,7 +766,7 @@
 [clinic start generated code]*/
 
 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"
 "\n"
 "  data\n"
@@ -787,7 +787,7 @@
 zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, unsigned int max_length);
 
 static PyObject *
-zlib_Decompress_decompress(PyObject *self, PyObject *args)
+zlib_Decompress_decompress(compobject *self, PyObject *args)
 {
     PyObject *return_value = NULL;
     Py_buffer data = {NULL, NULL};
@@ -797,7 +797,7 @@
         "y*|O&:decompress",
         &data, uint_converter, &max_length))
         goto exit;
-    return_value = zlib_Decompress_decompress_impl((compobject *)self, &data, max_length);
+    return_value = zlib_Decompress_decompress_impl(self, &data, max_length);
 
 exit:
     /* Cleanup for data */
@@ -809,7 +809,7 @@
 
 static PyObject *
 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;
     unsigned int old_length, length = DEFAULTALLOC;
@@ -1036,7 +1036,7 @@
 [clinic start generated code]*/
 
 PyDoc_STRVAR(zlib_Compress_copy__doc__,
-"copy()\n"
+"copy(self)\n"
 "Return a copy of the compression object.");
 
 #define ZLIB_COMPRESS_COPY_METHODDEF    \
@@ -1046,14 +1046,14 @@
 zlib_Compress_copy_impl(compobject *self);
 
 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 *
 zlib_Compress_copy_impl(compobject *self)
-/*[clinic end generated code: checksum=d57a7911deb7940e85a8d7e65af20b6e2df69000]*/
+/*[clinic end generated code: checksum=7aa841ad51297eb83250f511a76872e88fdc737e]*/
 {
     compobject *retval = NULL;
     int err;
diff --git a/Objects/descrobject.c b/Objects/descrobject.c
--- a/Objects/descrobject.c
+++ b/Objects/descrobject.c
@@ -353,11 +353,17 @@
 static PyObject *
 method_get_doc(PyMethodDescrObject *descr, void *closure)
 {
-    if (descr->d_method->ml_doc == NULL) {
-        Py_INCREF(Py_None);
-        return Py_None;
-    }
-    return PyUnicode_FromString(descr->d_method->ml_doc);
+    const char *name = descr->d_method->ml_name;
+    const char *doc = descr->d_method->ml_doc;
+    return _PyType_GetDocFromInternalDoc(name, 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 *
@@ -425,6 +431,7 @@
 static PyGetSetDef method_getset[] = {
     {"__doc__", (getter)method_get_doc},
     {"__qualname__", (getter)descr_get_qualname},
+    {"__text_signature__", (getter)method_get_text_signature},
     {0}
 };
 
@@ -463,16 +470,23 @@
 static PyObject *
 wrapperdescr_get_doc(PyWrapperDescrObject *descr, void *closure)
 {
-    if (descr->d_base->doc == NULL) {
-        Py_INCREF(Py_None);
-        return Py_None;
-    }
-    return PyUnicode_FromString(descr->d_base->doc);
+    const char *name = descr->d_base->name;
+    const char *doc = descr->d_base->doc;
+    return _PyType_GetDocFromInternalDoc(name, 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[] = {
     {"__doc__", (getter)wrapperdescr_get_doc},
     {"__qualname__", (getter)descr_get_qualname},
+    {"__text_signature__", (getter)wrapperdescr_get_text_signature},
     {0}
 };
 
@@ -1143,17 +1157,19 @@
 }
 
 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) {
-        Py_INCREF(Py_None);
-        return Py_None;
-    }
-    else {
-        return PyUnicode_FromString(s);
-    }
+static PyObject *
+wrapper_text_signature(wrapperobject *wp, void *closure)
+{
+    const char *name = wp->descr->d_base->name;
+    const char *doc = wp->descr->d_base->doc;
+    return _PyType_GetTextSignatureFromInternalDoc(name, doc);
 }
 
 static PyObject *
@@ -1167,6 +1183,7 @@
     {"__name__", (getter)wrapper_name},
     {"__qualname__", (getter)wrapper_qualname},
     {"__doc__", (getter)wrapper_doc},
+    {"__text_signature__", (getter)wrapper_text_signature},
     {0}
 };
 
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -1691,37 +1691,71 @@
     return v;
 }
 
+/*[clinic input]
+ at 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 *
-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;
+
+    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 *key;
     PyObject *d;
     int status;
 
-    if (!PyArg_UnpackTuple(args, "fromkeys", 1, 2, &seq, &value))
-        return NULL;
-
-    d = PyObject_CallObject(cls, NULL);
+    d = PyObject_CallObject((PyObject *)type, NULL);
     if (d == NULL)
         return NULL;
 
     if (PyDict_CheckExact(d) && ((PyDictObject *)d)->ma_used == 0) {
-        if (PyDict_CheckExact(seq)) {
+        if (PyDict_CheckExact(iterable)) {
             PyDictObject *mp = (PyDictObject *)d;
             PyObject *oldvalue;
             Py_ssize_t pos = 0;
             PyObject *key;
             Py_hash_t hash;
 
-            if (dictresize(mp, Py_SIZE(seq))) {
+            if (dictresize(mp, Py_SIZE(iterable))) {
                 Py_DECREF(d);
                 return NULL;
             }
 
-            while (_PyDict_Next(seq, &pos, &key, &oldvalue, &hash)) {
+            while (_PyDict_Next(iterable, &pos, &key, &oldvalue, &hash)) {
                 if (insertdict(mp, key, hash, value)) {
                     Py_DECREF(d);
                     return NULL;
@@ -1729,18 +1763,18 @@
             }
             return d;
         }
-        if (PyAnySet_CheckExact(seq)) {
+        if (PyAnySet_CheckExact(iterable)) {
             PyDictObject *mp = (PyDictObject *)d;
             Py_ssize_t pos = 0;
             PyObject *key;
             Py_hash_t hash;
 
-            if (dictresize(mp, PySet_GET_SIZE(seq))) {
+            if (dictresize(mp, PySet_GET_SIZE(iterable))) {
                 Py_DECREF(d);
                 return NULL;
             }
 
-            while (_PySet_NextEntry(seq, &pos, &key, &hash)) {
+            while (_PySet_NextEntry(iterable, &pos, &key, &hash)) {
                 if (insertdict(mp, key, hash, value)) {
                     Py_DECREF(d);
                     return NULL;
@@ -1750,7 +1784,7 @@
         }
     }
 
-    it = PyObject_GetIter(seq);
+    it = PyObject_GetIter(iterable);
     if (it == NULL){
         Py_DECREF(d);
         return NULL;
@@ -2176,7 +2210,7 @@
 [clinic start generated code]*/
 
 PyDoc_STRVAR(dict___contains____doc__,
-"__contains__(key)\n"
+"__contains__(self, key)\n"
 "True if D has a key k, else False.");
 
 #define DICT___CONTAINS___METHODDEF    \
@@ -2184,7 +2218,7 @@
 
 static PyObject *
 dict___contains__(PyObject *self, PyObject *key)
-/*[clinic end generated code: checksum=402ddb624ba1e4db764bfdfbbee6c1c59d1a11fa]*/
+/*[clinic end generated code: checksum=c4f85a39baac4776c4275ad5f072f7732c5f0806]*/
 {
     register PyDictObject *mp = (PyDictObject *)self;
     Py_hash_t hash;
@@ -2496,10 +2530,6 @@
 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]");
 
-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__,
 "D.clear() -> None.  Remove all items from D.");
 
@@ -2540,8 +2570,7 @@
     values__doc__},
     {"update",          (PyCFunction)dict_update,       METH_VARARGS | METH_KEYWORDS,
      update__doc__},
-    {"fromkeys",        (PyCFunction)dict_fromkeys,     METH_VARARGS | METH_CLASS,
-     fromkeys__doc__},
+    DICT_FROMKEYS_METHODDEF
     {"clear",           (PyCFunction)dict_clear,        METH_NOARGS,
      clear__doc__},
     {"copy",            (PyCFunction)dict_copy,         METH_NOARGS,
diff --git a/Objects/methodobject.c b/Objects/methodobject.c
--- a/Objects/methodobject.c
+++ b/Objects/methodobject.c
@@ -179,75 +179,20 @@
     {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 *
 meth_get__text_signature__(PyCFunctionObject *m, void *closure)
 {
-    const char *start = find_signature(m);
-    const char *trace;
-
-    if (!start) {
-        Py_INCREF(Py_None);
-        return Py_None;
-    }
-
-    trace = skip_signature(start);
-    return PyUnicode_FromStringAndSize(start, trace - start);
+    const char *name = m->m_ml->ml_name;
+    const char *doc = m->m_ml->ml_doc;
+    return _PyType_GetTextSignatureFromInternalDoc(name, doc);
 }
 
 static PyObject *
 meth_get__doc__(PyCFunctionObject *m, void *closure)
 {
-    const char *doc = find_signature(m);
-
-    if (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);
+    const char *name = m->m_ml->ml_name;
+    const char *doc = m->m_ml->ml_doc;
+    return _PyType_GetDocFromInternalDoc(name, doc);
 }
 
 static PyObject *
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -54,6 +54,83 @@
 static PyObject *
 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
 PyType_ClearCache(void)
 {
@@ -628,8 +705,11 @@
 type_get_doc(PyTypeObject *type, void *context)
 {
     PyObject *result;
-    if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE) && type->tp_doc != NULL)
-        return PyUnicode_FromString(type->tp_doc);
+    if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE) && type->tp_doc != NULL) {
+        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__);
     if (result == NULL) {
         result = Py_None;
@@ -645,6 +725,14 @@
     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
 type_set_doc(PyTypeObject *type, PyObject *value, void *context)
 {
@@ -691,6 +779,7 @@
      (setter)type_set_abstractmethods, NULL},
     {"__dict__",  (getter)type_dict,  NULL, NULL},
     {"__doc__", (getter)type_get_doc, (setter)type_set_doc, NULL},
+    {"__text_signature__", (getter)type_get_text_signature, NULL, NULL},
     {0}
 };
 
@@ -2519,13 +2608,14 @@
         /* need to make a copy of the docstring slot, which usually
            points to a static string literal */
         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);
             if (tp_doc == NULL) {
                 PyErr_NoMemory();
                 goto fail;
             }
-            memcpy(tp_doc, slot->pfunc, len);
+            memcpy(tp_doc, old_doc, len);
             type->tp_doc = tp_doc;
         }
     }
@@ -2909,6 +2999,8 @@
 };
 
 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(name, bases, dict) -> a new type");
 
@@ -3480,7 +3572,7 @@
         {
             PyObject **dict;
             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.
                We also return None if the dict is empty to make the behavior
                consistent regardless whether the dict was initialized or not.
@@ -3788,7 +3880,7 @@
     Py_DECREF(state);
     Py_DECREF(listitems);
     Py_DECREF(dictitems);
-    return result;    
+    return result;
 }
 
 static PyObject *
@@ -3813,7 +3905,7 @@
     }
     else if (kwargs != NULL) {
         if (PyDict_Size(kwargs) > 0) {
-            PyErr_SetString(PyExc_ValueError, 
+            PyErr_SetString(PyExc_ValueError,
                             "must use protocol 4 or greater to copy this "
                             "object; since __getnewargs_ex__ returned "
                             "keyword arguments.");
@@ -4103,8 +4195,8 @@
     PyObject_GenericGetAttr,                    /* tp_getattro */
     PyObject_GenericSetAttr,                    /* tp_setattro */
     0,                                          /* tp_as_buffer */
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
-    PyDoc_STR("The most base type"),            /* tp_doc */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,   /* tp_flags */
+    PyDoc_STR("object()\nThe most base type"),  /* tp_doc */
     0,                                          /* tp_traverse */
     0,                                          /* tp_clear */
     object_richcompare,                         /* tp_richcompare */
@@ -4571,7 +4663,8 @@
      */
     if (_PyDict_GetItemId(type->tp_dict, &PyId___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)
                 goto error;
             if (_PyDict_SetItemId(type->tp_dict, &PyId___doc__, doc) < 0) {
@@ -6005,22 +6098,22 @@
     ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, DOC)
 #define UNSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
     ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \
-           "x." NAME "() <==> " DOC)
+           NAME "(self)\n" DOC)
 #define IBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
     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) \
     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) \
     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) \
     ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \
-           "x." NAME "(y) <==> " DOC)
+           NAME "(self, value)\n" DOC)
 #define RBINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \
     ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \
-           "x." NAME "(y) <==> " DOC)
+           NAME "(self, value)\n" DOC)
 
 static slotdef slotdefs[] = {
     TPSLOT("__getattribute__", tp_getattr, NULL, NULL, ""),
@@ -6028,80 +6121,85 @@
     TPSLOT("__setattr__", tp_setattr, NULL, NULL, ""),
     TPSLOT("__delattr__", tp_setattr, NULL, NULL, ""),
     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,
-           "x.__hash__() <==> hash(x)"),
+           "__hash__(self)\nReturns hash(self)."),
     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,
-           "x.__str__() <==> str(x)"),
+           "__str__(self)\nReturns str(self)."),
     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("__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,
-           "x.__delattr__('name') <==> del x.name"),
+           "__delattr__(self, name)\nImplements delattr(self, name)."),
     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,
-           "x.__le__(y) <==> x<=y"),
+           "__le__(self, value)\nReturns self<=value."),
     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,
-           "x.__ne__(y) <==> x!=y"),
+           "__ne__(self, value)\nReturns self!=value."),
     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,
-           "x.__ge__(y) <==> x>=y"),
+           "__ge__(self, value)\nReturns self>=value."),
     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,
-           "x.__next__() <==> next(x)"),
+           "__next__(self)\nImplements next(self)."),
     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,
-           "descr.__set__(obj, value)"),
+           "__set__(self, instance, value)\nSets an attribute of instance to value."),
     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,
-           "x.__init__(...) initializes x; "
-           "see help(type(x)) for signature",
+           "__init__(self, *args, **kwargs)\n"
+           "Initializes self.  See help(type(self)) for accurate signature.",
            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, ""),
 
     BINSLOT("__add__", nb_add, slot_nb_add,
-        "+"),
+           "+"),
     RBINSLOT("__radd__", nb_add, slot_nb_add,
-             "+"),
+           "+"),
     BINSLOT("__sub__", nb_subtract, slot_nb_subtract,
-        "-"),
+           "-"),
     RBINSLOT("__rsub__", nb_subtract, slot_nb_subtract,
-             "-"),
+           "-"),
     BINSLOT("__mul__", nb_multiply, slot_nb_multiply,
-        "*"),
+           "*"),
     RBINSLOT("__rmul__", nb_multiply, slot_nb_multiply,
-             "*"),
+           "*"),
     BINSLOT("__mod__", nb_remainder, slot_nb_remainder,
-        "%"),
+           "%"),
     RBINSLOT("__rmod__", nb_remainder, slot_nb_remainder,
-             "%"),
+           "%"),
     BINSLOTNOTINFIX("__divmod__", nb_divmod, slot_nb_divmod,
-        "divmod(x, y)"),
+           "__divmod__(self, value)\nReturns divmod(self, value)."),
     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,
-           "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,
-           "y.__rpow__(x[, z]) <==> pow(x, y[, z])"),
-    UNSLOT("__neg__", nb_negative, slot_nb_negative, wrap_unaryfunc, "-x"),
-    UNSLOT("__pos__", nb_positive, slot_nb_positive, wrap_unaryfunc, "+x"),
+           "__rpow__(self, value, mod=None)\nReturns pow(value, self, mod)."),
+    UNSLOT("__neg__", nb_negative, slot_nb_negative, wrap_unaryfunc, "-self"),
+    UNSLOT("__pos__", nb_positive, slot_nb_positive, wrap_unaryfunc, "+self"),
     UNSLOT("__abs__", nb_absolute, slot_nb_absolute, wrap_unaryfunc,
-           "abs(x)"),
+           "abs(self)"),
     UNSLOT("__bool__", nb_bool, slot_nb_bool, wrap_inquirypred,
-           "x != 0"),
-    UNSLOT("__invert__", nb_invert, slot_nb_invert, wrap_unaryfunc, "~x"),
+           "self != 0"),
+    UNSLOT("__invert__", nb_invert, slot_nb_invert, wrap_unaryfunc, "~self"),
     BINSLOT("__lshift__", nb_lshift, slot_nb_lshift, "<<"),
     RBINSLOT("__rlshift__", nb_lshift, slot_nb_lshift, "<<"),
     BINSLOT("__rshift__", nb_rshift, slot_nb_rshift, ">>"),
@@ -6113,9 +6211,9 @@
     BINSLOT("__or__", nb_or, slot_nb_or, "|"),
     RBINSLOT("__ror__", nb_or, slot_nb_or, "|"),
     UNSLOT("__int__", nb_int, slot_nb_int, wrap_unaryfunc,
-           "int(x)"),
+           "int(self)"),
     UNSLOT("__float__", nb_float, slot_nb_float, wrap_unaryfunc,
-           "float(x)"),
+           "float(self)"),
     IBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add,
            wrap_binaryfunc, "+="),
     IBSLOT("__isub__", nb_inplace_subtract, slot_nb_inplace_subtract,
@@ -6145,45 +6243,48 @@
     IBSLOT("__itruediv__", nb_inplace_true_divide,
            slot_nb_inplace_true_divide, wrap_binaryfunc, "/"),
     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,
-           "x.__len__() <==> len(x)"),
+           "__len__(self)\nReturns len(self)."),
     MPSLOT("__getitem__", mp_subscript, slot_mp_subscript,
            wrap_binaryfunc,
-           "x.__getitem__(y) <==> x[y]"),
+           "__getitem__(self, key)\nReturns self[key]."),
     MPSLOT("__setitem__", mp_ass_subscript, slot_mp_ass_subscript,
            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,
            wrap_delitem,
-           "x.__delitem__(y) <==> del x[y]"),
+           "__delitem__(key)\nDeletes self[key]."),
 
     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.
        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
        user-defined methods has unexpected side-effects, as shown by
        test_descr.notimplemented() */
     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,
-      "x.__mul__(n) <==> x*n"),
+           "__mul__(self, value)\nReturns self*value.n"),
     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,
-           "x.__getitem__(y) <==> x[y]"),
+           "__getitem__(self, key)\nReturns self[key]."),
     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,
-           "x.__delitem__(y) <==> del x[y]"),
+           "__delitem__(self, key)\nDeletes self[key]."),
     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,
-      wrap_binaryfunc, "x.__iadd__(y) <==> x+=y"),
+           wrap_binaryfunc,
+           "__iadd__(self, value)\nImplements self+=value."),
     SQSLOT("__imul__", sq_inplace_repeat, NULL,
-      wrap_indexargfunc, "x.__imul__(y) <==> x*=y"),
+           wrap_indexargfunc,
+           "__imul__(self, value)\nImplements self*=value."),
 
     {NULL}
 };
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -12900,7 +12900,7 @@
     {"maketrans", (PyCFunction)unicode_maketrans, METH_VARARGS|METH_STATIC, unicode_maketrans__doc__},
 
 static PyObject *
-unicode_maketrans_impl(void *null, PyObject *x, PyObject *y, PyObject *z);
+unicode_maketrans_impl(PyObject *x, PyObject *y, PyObject *z);
 
 static PyObject *
 unicode_maketrans(void *null, PyObject *args)
@@ -12914,15 +12914,15 @@
         "O|UU:maketrans",
         &x, &y, &z))
         goto exit;
-    return_value = unicode_maketrans_impl(null, x, y, z);
+    return_value = unicode_maketrans_impl(x, y, z);
 
 exit:
     return return_value;
 }
 
 static PyObject *
-unicode_maketrans_impl(void *null, PyObject *x, PyObject *y, PyObject *z)
-/*[clinic end generated code: checksum=7f76f414a0dfd0c614e0d4717872eeb520516da7]*/
+unicode_maketrans_impl(PyObject *x, PyObject *y, PyObject *z)
+/*[clinic end generated code: checksum=90a3de8c494b304687e1e0d7e5fa8ba78eac6533]*/
 {
     PyObject *new = NULL, *key, *value;
     Py_ssize_t i = 0;
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -1325,7 +1325,7 @@
 }
 
 PyDoc_STRVAR(len_doc,
-"len(object) -> integer\n\
+"len(module, object)\n\
 \n\
 Return the number of items of a sequence or mapping.");
 
diff --git a/Python/import.c b/Python/import.c
--- a/Python/import.c
+++ b/Python/import.c
@@ -232,7 +232,7 @@
 [clinic start generated code]*/
 
 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"
 "\n"
 "On platforms without threads, return False.");
@@ -251,7 +251,7 @@
 
 static PyObject *
 _imp_lock_held_impl(PyModuleDef *module)
-/*[clinic end generated code: checksum=ede1cafb78eb22e3009602f684c8b780e2b82d62]*/
+/*[clinic end generated code: checksum=17172a9917d389dd1564e2108fec34d23aecb6c2]*/
 {
 #ifdef WITH_THREAD
     return PyBool_FromLong(import_lock_thread != -1);
@@ -270,7 +270,7 @@
 [clinic start generated code]*/
 
 PyDoc_STRVAR(_imp_acquire_lock__doc__,
-"acquire_lock()\n"
+"acquire_lock(module)\n"
 "Acquires the interpreter\'s import lock for the current thread.\n"
 "\n"
 "This lock should be used by import hooks to ensure thread-safety when importing\n"
@@ -290,7 +290,7 @@
 
 static PyObject *
 _imp_acquire_lock_impl(PyModuleDef *module)
-/*[clinic end generated code: checksum=5b520b2416c5954a7cf0ed30955d68abe20b5868]*/
+/*[clinic end generated code: checksum=20db30e18f6b8758386fe06907edb3f8e43080d7]*/
 {
 #ifdef WITH_THREAD
     _PyImport_AcquireLock();
@@ -308,7 +308,7 @@
 [clinic start generated code]*/
 
 PyDoc_STRVAR(_imp_release_lock__doc__,
-"release_lock()\n"
+"release_lock(module)\n"
 "Release the interpreter\'s import lock.\n"
 "\n"
 "On platforms without threads, this function does nothing.");
@@ -327,7 +327,7 @@
 
 static PyObject *
 _imp_release_lock_impl(PyModuleDef *module)
-/*[clinic end generated code: checksum=efcd9d2923294c04371596e7f6d66a706d43fcac]*/
+/*[clinic end generated code: checksum=17749fd7752d2c392447a1f83c5d371f54d7ebd3]*/
 {
 #ifdef WITH_THREAD
     if (_PyImport_ReleaseLock() < 0) {
@@ -927,7 +927,7 @@
 [clinic start generated code]*/
 
 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"
 "\n"
 "  code\n"
@@ -960,7 +960,7 @@
 
 static PyObject *
 _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);
@@ -1823,7 +1823,7 @@
 [clinic start generated code]*/
 
 PyDoc_STRVAR(_imp_extension_suffixes__doc__,
-"extension_suffixes()\n"
+"extension_suffixes(module)\n"
 "Returns the list of file suffixes used to identify extension modules.");
 
 #define _IMP_EXTENSION_SUFFIXES_METHODDEF    \
@@ -1840,7 +1840,7 @@
 
 static PyObject *
 _imp_extension_suffixes_impl(PyModuleDef *module)
-/*[clinic end generated code: checksum=82fb35d8429a429a4dc80c84b45b1aad73ff1de7]*/
+/*[clinic end generated code: checksum=625c8f11a5bbd4b85373f0a54f7f3ef19c55beb4]*/
 {
     PyObject *list;
     const char *suffix;
@@ -1878,7 +1878,7 @@
 [clinic start generated code]*/
 
 PyDoc_STRVAR(_imp_init_builtin__doc__,
-"init_builtin(name)\n"
+"init_builtin(module, name)\n"
 "Initializes a built-in module.");
 
 #define _IMP_INIT_BUILTIN_METHODDEF    \
@@ -1905,7 +1905,7 @@
 
 static PyObject *
 _imp_init_builtin_impl(PyModuleDef *module, PyObject *name)
-/*[clinic end generated code: checksum=59239206e5b2fb59358066e72fd0e72e55a7baf5]*/
+/*[clinic end generated code: checksum=a4e4805a523757cd3ddfeec6e5b16740678fed6a]*/
 {
     int ret;
     PyObject *m;
@@ -1932,7 +1932,7 @@
 [clinic start generated code]*/
 
 PyDoc_STRVAR(_imp_init_frozen__doc__,
-"init_frozen(name)\n"
+"init_frozen(module, name)\n"
 "Initializes a frozen module.");
 
 #define _IMP_INIT_FROZEN_METHODDEF    \
@@ -1959,7 +1959,7 @@
 
 static PyObject *
 _imp_init_frozen_impl(PyModuleDef *module, PyObject *name)
-/*[clinic end generated code: checksum=503fcc3de9961263e4d9484259af357a7d287a0b]*/
+/*[clinic end generated code: checksum=2a58c119dd3e121cf5a9924f936cfd7b40253c12]*/
 {
     int ret;
     PyObject *m;
@@ -1986,7 +1986,7 @@
 [clinic start generated code]*/
 
 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.");
 
 #define _IMP_GET_FROZEN_OBJECT_METHODDEF    \
@@ -2013,7 +2013,7 @@
 
 static PyObject *
 _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);
 }
@@ -2028,7 +2028,7 @@
 [clinic start generated code]*/
 
 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.");
 
 #define _IMP_IS_FROZEN_PACKAGE_METHODDEF    \
@@ -2055,7 +2055,7 @@
 
 static PyObject *
 _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);
 }
@@ -2070,7 +2070,7 @@
 [clinic start generated code]*/
 
 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.");
 
 #define _IMP_IS_BUILTIN_METHODDEF    \
@@ -2097,7 +2097,7 @@
 
 static PyObject *
 _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));
 }
@@ -2112,7 +2112,7 @@
 [clinic start generated code]*/
 
 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.");
 
 #define _IMP_IS_FROZEN_METHODDEF    \
@@ -2139,7 +2139,7 @@
 
 static PyObject *
 _imp_is_frozen_impl(PyModuleDef *module, PyObject *name)
-/*[clinic end generated code: checksum=978b547ddcb76fa6c4a181ad53569c9acf382c7b]*/
+/*[clinic end generated code: checksum=4b079fb45a495835056ea5604735d552d222be5c]*/
 {
     const struct _frozen *p;
 
@@ -2161,7 +2161,7 @@
 [clinic start generated code]*/
 
 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.");
 
 #define _IMP_LOAD_DYNAMIC_METHODDEF    \
@@ -2190,7 +2190,7 @@
 
 static PyObject *
 _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;
     FILE *fp;
diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py
--- a/Tools/clinic/clinic.py
+++ b/Tools/clinic/clinic.py
@@ -139,9 +139,9 @@
 # so if they're used Argument Clinic will add "_value" to the end
 # of the name in C.
 c_keywords = set("""
-asm auto break case char cls const continue default do double
-else enum extern float for goto if inline int long module null
-register return self short signed sizeof static struct switch
+asm auto break case char const continue default do double
+else enum extern float for goto if inline int long
+register return short signed sizeof static struct switch
 typedef typeof union unsigned void volatile while
 """.strip().split())
 
@@ -635,6 +635,9 @@
 
     def output_templates(self, f):
         parameters = list(f.parameters.values())
+        assert parameters
+        assert isinstance(parameters[0].converter, self_converter)
+        del parameters[0]
         converters = [p.converter for p in parameters]
 
         has_option_groups = parameters and (parameters[0].group or parameters[-1].group)
@@ -679,8 +682,11 @@
         return_value_declaration = "PyObject *return_value = NULL;"
 
         methoddef_define = templates['methoddef_define']
-        docstring_prototype = templates['docstring_prototype']
-        docstring_definition = templates['docstring_definition']
+        if new_or_init and not f.docstring:
+            docstring_prototype = docstring_definition = ''
+        else:
+            docstring_prototype = templates['docstring_prototype']
+            docstring_definition = templates['docstring_definition']
         impl_definition = templates['impl_definition']
         impl_prototype = parser_prototype = parser_definition = None
 
@@ -858,6 +864,8 @@
 
         add, output = text_accumulator()
         parameters = list(f.parameters.values())
+        if isinstance(parameters[0].converter, self_converter):
+            del parameters[0]
 
         groups = []
         group = None
@@ -936,14 +944,69 @@
         data = CRenderData()
 
         parameters = list(f.parameters.values())
+        assert parameters, "We should always have a 'self' at this point!"
+
         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 = {}
 
         full_name = f.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
 
         if f.c_basename:
@@ -953,6 +1016,7 @@
             if fields[-1] == '__new__':
                 fields.pop()
             c_basename = "_".join(fields)
+
         template_dict['c_basename'] = c_basename
 
         methoddef_name = "{}_METHODDEF".format(c_basename.upper())
@@ -960,67 +1024,7 @@
 
         template_dict['docstring'] = self.docstring_for_c_string(f)
 
-        positional = has_option_groups =  False
-
-        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_self.converter.set_template_dict(template_dict)
 
         f.return_converter.render(f, data)
         template_dict['impl_return_type'] = f.return_converter.type
@@ -1036,15 +1040,16 @@
         template_dict['cleanup'] = "".join(data.cleanup)
         template_dict['return_value'] = data.return_value
 
-        # used by unpack tuple
-        template_dict['unpack_min'] = str(first_optional)
-        template_dict['unpack_max'] = str(len(parameters))
+        # used by unpack tuple code generator
+        ignore_self = -1 if isinstance(converters[0], self_converter) else 0
+        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:
             self.render_option_group_parsing(f, template_dict)
 
-        templates = self.output_templates(f)
-
         for name, destination in clinic.field_destinations.items():
             template = templates[name]
             if has_option_groups:
@@ -1077,6 +1082,7 @@
 
 
 
+
 @contextlib.contextmanager
 def OverrideStdioWith(stdout):
     saved_stdout = sys.stdout
@@ -1775,7 +1781,9 @@
 """.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:
     """
@@ -1969,6 +1977,19 @@
     # Only used by format units ending with '#'.
     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):
         self.function = function
         self.name = name
@@ -1998,30 +2019,36 @@
     def is_optional(self):
         return (self.default is not unspecified)
 
-    def render(self, parameter, data):
-        """
-        parameter is a clinic.Parameter instance.
-        data is a CRenderData instance.
-        """
+    def _render_self(self, parameter, data):
         self.parameter = parameter
         original_name = self.name
         name = ensure_legal_c_identifier(original_name)
 
-        # declarations
-        d = self.declaration()
-        data.declarations.append(d)
-
-        # initializers
-        initializers = self.initialize()
-        if initializers:
-            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())
 
+        # 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
+        original_name = self.name
+        name = ensure_legal_c_identifier(original_name)
+
+        # declarations
+        d = self.declaration()
+        data.declarations.append(d)
+
+        # initializers
+        initializers = self.initialize()
+        if initializers:
+            data.initializers.append('/* initializers for ' + name + ' */\n' + initializers.rstrip())
+
         # keywords
         data.keywords.append(original_name)
 
@@ -2035,16 +2062,19 @@
         # 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 = self.cleanup()
         if cleanup:
             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):
         """Computes the name of the associated "length" variable."""
         if not self.length:
@@ -2318,7 +2348,7 @@
                 format_unit = 'et#'
 
             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 add cleanup for buffer
                 pass
@@ -2421,35 +2451,108 @@
         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):
     """
     A special-case converter:
     this is the default converter used for "self".
     """
-    type = "PyObject *"
+    type = None
+    format_unit = ''
+
+
     def converter_init(self, *, type=None):
         f = self.function
-        if f.kind in (CALLABLE, METHOD_INIT):
-            if f.cls:
-                self.name = "self"
-            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:
-            self.type = type
+        default_type, default_name = correct_name_for_self(f)
+        self.signature_name = default_name
+        self.type = type or self.type or default_type
+
+        kind = self.function.kind
+        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):
-        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 @@
             if not return_converter:
                 return_converter = init_return_converter()
         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:
             return_converter = CReturnConverter()
@@ -3007,6 +3110,13 @@
         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)
         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)
         self.next(self.state_parameters_start)
 
@@ -3173,34 +3283,43 @@
             try:
                 module = ast.parse(ast_input)
 
-                # blacklist of disallowed ast nodes
-                class DetectBadNodes(ast.NodeVisitor):
-                    bad = False
-                    def bad_node(self, node):
-                        self.bad = True
-
-                    # inline function call
-                    visit_Call = bad_node
-                    # inline if statement ("x = 3 if y else z")
-                    visit_IfExp = bad_node
-
-                    # comprehensions and generator expressions
-                    visit_ListComp = visit_SetComp = bad_node
-                    visit_DictComp = visit_GeneratorExp = bad_node
-
-                    # literals for advanced types
-                    visit_Dict = visit_Set = bad_node
-                    visit_List = visit_Tuple = bad_node
-
-                    # "starred": "a = [1, 2, 3]; *a"
-                    visit_Starred = bad_node
-
-                    # allow ellipsis, for now
-                    # visit_Ellipsis = bad_node
-
-                blacklist = DetectBadNodes()
-                blacklist.visit(module)
-                if blacklist.bad:
+                bad = False
+                if 'c_default' not in kwargs:
+                    # we can only represent very simple data values in C.
+                    # detect whether default is okay, via a blacklist
+                    # of disallowed ast nodes.
+                    class DetectBadNodes(ast.NodeVisitor):
+                        bad = False
+                        def bad_node(self, node):
+                            self.bad = True
+
+                        # inline function call
+                        visit_Call = bad_node
+                        # inline if statement ("x = 3 if y else z")
+                        visit_IfExp = bad_node
+
+                        # comprehensions and generator expressions
+                        visit_ListComp = visit_SetComp = bad_node
+                        visit_DictComp = visit_GeneratorExp = bad_node
+
+                        # literals for advanced types
+                        visit_Dict = visit_Set = bad_node
+                        visit_List = visit_Tuple = bad_node
+
+                        # "starred": "a = [1, 2, 3]; *a"
+                        visit_Starred = bad_node
+
+                        # allow ellipsis, for now
+                        # visit_Ellipsis = bad_node
+
+                    blacklist = DetectBadNodes()
+                    blacklist.visit(module)
+                    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))
 
                 expr = module.body[0].value
@@ -3263,18 +3382,22 @@
             fail('{} is not a valid {}converter'.format(name, legacy_str))
         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
+        kind = inspect.Parameter.KEYWORD_ONLY if self.keyword_only else inspect.Parameter.POSITIONAL_OR_KEYWORD
+
         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
+            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)
 
         if parameter_name in self.function.parameters:
@@ -3333,7 +3456,7 @@
             self.parameter_state = self.ps_seen_slash
             # fixup preceeding parameters
             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.")
                 p.kind = inspect.Parameter.POSITIONAL_ONLY
 
@@ -3394,6 +3517,11 @@
     def format_docstring(self):
         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()
         parameters = list(f.parameters.values())
 
@@ -3401,7 +3529,7 @@
         ## docstring first line
         ##
 
-        if f.kind in (METHOD_NEW, METHOD_INIT):
+        if new_or_init:
             assert f.cls
             add(f.cls.name)
         else:
@@ -3409,17 +3537,24 @@
         add('(')
 
         # 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
-            # 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:
+            # is if all of them are 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)
                 for p in parameters:
                     p.right_bracket_count = abs(p.group)
             else:
                 # 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
 
         right_bracket_count = 0
@@ -3439,6 +3574,9 @@
         add_comma = False
 
         for p in parameters:
+            if not p.converter.show_in_signature:
+                continue
+
             assert p.name
 
             if p.is_keyword_only() and not added_star:
@@ -3446,8 +3584,10 @@
                 if add_comma:
                     add(', ')
                 add('*')
-
-            a = [p.name]
+                add_comma = True
+
+            name = p.converter.signature_name or p.name
+            a = [name]
             if p.converter.is_optional():
                 a.append('=')
                 value = p.converter.py_default
@@ -3560,9 +3700,6 @@
         if not self.function:
             return
 
-        if not self.function.self_converter:
-            self.function.self_converter = self_converter("self", self.function)
-
         if self.keyword_only:
             values = self.function.parameters.values()
             if not values:
@@ -3582,6 +3719,8 @@
         self.function.docstring = self.format_docstring()
 
 
+
+
 # maps strings to callables.
 # the callable should return an object
 # that implements the clinic parser
@@ -3607,6 +3746,7 @@
     cmdline = argparse.ArgumentParser()
     cmdline.add_argument("-f", "--force", action='store_true')
     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("--make", action='store_true')
     cmdline.add_argument("filename", type=str, nargs="*")
@@ -3680,13 +3820,15 @@
             cmdline.print_usage()
             sys.exit(-1)
         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:
                     dirs.remove(rcs_dir)
             for filename in files:
-                if not filename.endswith('.c'):
+                if not (filename.endswith('.c') or filename.endswith('.h')):
                     continue
                 path = os.path.join(root, filename)
+                if ns.verbose:
+                    print(path)
                 parse_file(path, verify=not ns.force)
         return
 
@@ -3701,6 +3843,8 @@
         sys.exit(-1)
 
     for filename in ns.filename:
+        if ns.verbose:
+            print(filename)
         parse_file(filename, output=ns.output, verify=not ns.force)
 
 

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list