Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 ...

like image 640
zondo Avatar asked Feb 27 '16 02:02

zondo


People also ask

What is ellipsis in c++?

Ellipsis in C++ allows the function to accept an indeterminate number of arguments. It is also known as the variable argument list. Ellipsis tells the compiler to not check the type and number of parameters the function should accept which allows the user to pass the variable argument list.

How to pass arguments in function in php?

PHP Function Arguments Information can be passed to functions through arguments. An argument is just like a variable. Arguments are specified after the function name, inside the parentheses. You can add as many arguments as you want, just separate them with a comma.


1 Answers

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)
like image 193
Sebastian Kreft Avatar answered Oct 13 '22 19:10

Sebastian Kreft