Search code examples
pythondocstring

Make function have ellipsis for arguments in help() function


If you type help(vars), the following is produced:

vars(...)
    vars([object]) -> dictionary

    Without arguments, equivalent to locals().
    With an argument, equivalent to object.__dict__.

When I do the following:

def func(x, y): pass

help(func)

it displays this:

func(x, y)

How can I change it so that it shows up with ... between the parentheses like the built-in function vars()? (That is, func(...))

Edit: It has been suggested to use a docstring, but that won't do what I want. Here is an example:

def func(x, y):
    """func(...) -> None"""

help(func)

result:

func(x, y)
    func(...) -> None

You see, x, y is still being displayed instead of ...


Solution

  • You have (at least) two alternatives to achieve what you want.

    The best alternative would be to override the __str__ method of the inspect.Signature class. However, as it is written in C, it is read only.

    So to do that you need to extend the class as following:

    class MySignature(inspect.Signature):
      def __str__(self):
        return '(...)'
    

    then after defining your function you execute:

    func_signature = inspect.signature(func)
    func.__signature__ = MySignature(func_signature.parameters.values(), 
                                     return_annotation=func_signature.return_annotation)
    

    which would then return the following for help(func):

    Help on function func in module __main__:
    
    func(...)
    (END)
    

    With this approach inspect.signature still works:

    In [1]: inspect.signature(func)
    Out[1]: <MySignature (...)>
    

    Alternatively if you don't really care about being able to properly introspect your function (and probably some other use cases), then you can define the value of your function's __signature__ to an object which is not a Signature instance:

    def func(x, y):
        pass
    
    func.__signature__ = object()
    
    help(func)
    

    generates the result:

    Help on function func in module __main__:
    
    func(...)
    (END)
    

    But now inspect.signature(func) will raise TypeError: unexpected object <object object at 0x10182e200> in __signature__ attribute.

    Note: this last version is quite hacky and I would not recommend it.

    For more info on these two techniques and how the signature works see PEP 0362.

    Update: For python 2.7 you can do the following (probably better using a mock framework):

    In [1]: import inspect
    
    In [2]: def myformatargspec(*args, **kwargs):
       ...:     return '(...)'
       ...:
    
    In [3]: def func(x, y):
       ...:     pass
       ...: 
    
    In [6]: inspect.formatargspec = myformatargspec
    
    In [7]: help(func)
    
    Help on function func in module __main__:
    
    func(...)
    (END)