Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are __signature__ and __text_signature__ used for in Python 3.4

If one does dir() on some builtin callables (class constructors, methods, etc) on CPython 3.4, one finds out that many of them often have a special attribute called __text_signature__, for example:

>>> object.__text_signature__
'()'
>>> int.__text_signature__
>>> # was None

However the documentation for this is nonexistent. Furthermore, googling for the attribute name suggests that there is also another possible special attribute __signature__, though I did not find any built-in functions that would have it.

I do know they are related to the function argument signature, but nothing beyond that, what do their values signify and what is the use of them?

like image 940

People also ask

What are signatures in Python?

Using signature() function We can get function Signature with the help of signature() Function. It takes callable as a parameter and returns the annotation. It raises a value Error if no signature is provided. If the Invalid type object is given then it throws a Type Error.


2 Answers

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.

like image 163
Martijn Pieters Avatar answered Sep 30 '22 16:09

Martijn Pieters


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]]).
like image 37
Raymond Hettinger Avatar answered Sep 30 '22 17:09

Raymond Hettinger