What are __signature__ and __text_signature__ used for in Python 3.4

These attributes are there to enable introspection for Python objects defined in C code. The C-API Argument Clinic provides the data, to assist the inspect module when building Signature objects. Introspection of C-API functions was not supported before.

See the internal inspect._signature_fromstr() function on how the __text_signature__ value is used.

Currently, the __text_signature__ attribute is filled from the internal docstring set on objects in the C-API; a simple text search is done for objectname(...)\n--\n\n, where the \n--\n\n is typical of Attribute Clinic-generated documentation strings. Take a look at the type object slots if you wanted to find some examples. Or you could look at the audioop module source to see how the Argument Clinic is being used to define signatures; the Argument Clinic script is run on those when building to generate the docstrings (in the accompanying audioop.c.h file).

The __signature__ attribute, if present, would be a inspect.Signature() object; instead of providing a text version a C-API can provide a fully parsed Signature instance instead.


Quick Summary

Those two attributes are used by the inspect.signature() function to retrieve metadata about a function or method's call signature.

Real-world Application

One use case for manually specifying one of these attributes is to provide useful tooltips for a function that uses *args.

In this example, the randrange() method uses *args to accept a variable number of inputs. However, we want the signature provided to help() and tooltips to show the meaning of each argument so that it matches the corresponding range() function.

import random

class Random(random.Random):
    
    def randrange(self, /, *args):
        'Choose a random value from range(start[, stop[, step]]).'
        return self.choice(range(*args))

    randrange.__text_signature__ = '($self, start, stop=None, step=1, /)'

The __text_signature__ attribute informs the creation of the Signature object:

>>> inspect.signature(Random.randrange)
<Signature (self, start, stop=None, step=1, /)>

This makes the help() output more useful:

>>> help(Random.randrange)
Help on function randrange in module __main__:

randrange(self, start, stop=None, step=1, /)
    Choose a random value from range(start[, stop[, step]]).