[IPython-dev] add tab completion for arguments dynamically

G Jones glenn.caltech at gmail.com
Thu Mar 2 23:04:08 EST 2017


Hi,
Unfortunately in py2.7 it looks like I can't assign to
callme.__call__.__signature__

AttributeError: 'instancemethod' object has no attribute '__signature__'

I was surprised that providing __signature__ for the class doesn't work,
since what little documentation I could find for doing this (i.e. PEP362
and the python 3 inspect.signature documentation) all refers to "a callable
object" and PEP362 lists "If the [callable] object has a __signature__
attribute and if it is not None - return it".

Anyway, it looks like I may need to use another trick for python2. I
appreciate any ideas.

Thank you again,
Glenn

On Thu, Mar 2, 2017 at 10:50 PM, Matthias Bussonnier <
bussonniermatthias at gmail.com> wrote:

> Hi Glenn,
>
> Almost there, you need to set signature on __call__ not on the class.
>
> In [3]: import inspect
>    ...: class callme(object):
>    ...:     def __call__(self,**kwargs):
>    ...:         return kwargs
>    ...:
>    ...:
>    ...: callme.__call__.__signature__ = inspect.Signature(parameters={
>    ...:     inspect.Parameter('self',inspect.Parameter.POSITIONAL_
> OR_KEYWORD):1,
>    ...:     inspect.Parameter('long_arg',inspect.Parameter.POSITIONAL_
> OR_KEYWORD):2
>    ...:                                                            })
>    ...:
>
> In [4]: c = callme()
>
> In [5]: c?
> Signature:   c(long_arg)
> Type:        callme
> String form: <__main__.callme object at 0x11020fb00>
> Docstring:   <no docstring>
>
> This seem to work for me on tab completion.
> --
> M
>
> On Thu, Mar 2, 2017 at 7:20 PM, G Jones <glenn.caltech at gmail.com> wrote:
> > Hi Matthias,
> > This seems to be exactly what I'm looking for, and it works fine when I
> > attach a __signature__ attribute to a simple function. I had to install
> > funcsigs because the project I'm working on is stuck with py2.7.
> > However, I am having trouble making it work for a callable class:
> >
> > In [53]: class callme(object):
> >     ...:     def __call__(self,**kwargs):
> >     ...:         return kwargs
> >     ...:     __signature__ =
> > funcsigs.Signature(parameters=[funcsigs.Parameter('long_arg'
> ,funcsigs.Parameter.POSITIONAL_OR_KEYWORD)])
> >
> > In [54]: c = callme()
> >
> > In [55]: c?
> > Type:           callme
> > String form:    <__main__.callme object at 0x7f63e7124350>
> > Signature:      c(long_arg)
> > Docstring:      <no docstring>
> > Call signature: c(**kwargs)
> >
> > So far so good, the signature is seen as expected. However, when I try to
> > tab complete with "c(long<tab>", long_arg is not in the list of
> suggestions.
> >
> > Is there a way to accomplish this for a callable class?
> >
> > Thanks,
> > Glenn
> >
> > On Thu, Mar 2, 2017 at 4:25 PM, Matthias Bussonnier
> > <bussonniermatthias at gmail.com> wrote:
> >>
> >> Hi Glenn,
> >>
> >> You can set the `__signature__` of your object. likely possible with a
> >> decorator.
> >> Here is a short example of how you could do it in a REPL.
> >>
> >>
> >> In [21]: from inspect import Signature, Parameter
> >>
> >> In [22]: def foo(*kwargs):
> >>     ...:     pass
> >>
> >> In [23]: foo?
> >> Signature: foo(*kwargs)
> >> Docstring: <no docstring>
> >> File:      ~/dev/docathon/<ipython-input-22-086da1400d07>
> >> Type:      function
> >>
> >> In [24]: foo.__signature__ = Signature(parameters={Parameter('a',
> >> Parameter.POSITIONAL_OR_KEYWORD):None})
> >>
> >> In [25]: foo?
> >> Signature: foo(a)
> >> Docstring: <no docstring>
> >> File:      ~/dev/docathon/<ipython-input-22-086da1400d07>
> >> Type:      function
> >>
> >>
> >> That should  not only work with IPython, but with anything that use
> >> the Python inspect library.
> >>
> >> Note that what I do above is imperfect as you should use an
> >> OrderedDict instead of a dict for `parameters=...`
> >>
> >> Does that helps ?
> >>
> >> --
> >> M
> >>
> >>
> >> On Thu, Mar 2, 2017 at 12:58 PM, G Jones <glenn.caltech at gmail.com>
> wrote:
> >> > Hi,
> >> > Is it possible to customize the completion list when typing keyword
> >> > arguments?
> >> > For example suppose I have a function like:
> >> > def myfunc(**kwargs):
> >> >     val = kwargs['val']
> >> >
> >> > is there a way to tell ipython that when it sees me type:
> >> > myfunc(va<tab>
> >> >
> >> > it suggests "val="?
> >> >
> >> > Thanks,
> >> > Glenn
> >> >
> >> >
> >> >
> >> > _______________________________________________
> >> > IPython-dev mailing list
> >> > IPython-dev at scipy.org
> >> > https://mail.scipy.org/mailman/listinfo/ipython-dev
> >> >
> >> _______________________________________________
> >> IPython-dev mailing list
> >> IPython-dev at scipy.org
> >> https://mail.scipy.org/mailman/listinfo/ipython-dev
> >
> >
> >
> > _______________________________________________
> > IPython-dev mailing list
> > IPython-dev at scipy.org
> > https://mail.scipy.org/mailman/listinfo/ipython-dev
> >
> _______________________________________________
> IPython-dev mailing list
> IPython-dev at scipy.org
> https://mail.scipy.org/mailman/listinfo/ipython-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/ipython-dev/attachments/20170302/92f946bc/attachment.html>


More information about the IPython-dev mailing list