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?
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.
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.
Those two attributes are used by the inspect.signature() function to retrieve metadata about a function or method's call signature.
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]]).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With