[Idle-dev] Bug in Calltips + patch

Gregor Lingl glingl at aon.at
Thu May 4 01:03:02 CEST 2006


Hello,

I've (re?)-discovered a bug in IDLE call-tips.

If you define a function like:

>>> def f(x=''):
         pass

Idle displays the following calltip:  (x=)

Likewise for

>>> def g(x='abc'):
         pass

the calltip is (x=abc)

for

>>> def h(x=(1,2,3)):
         pass

the calltip remains empty.

I submit a quick patch which shows the reason for this and repairs it.
May be you'll find a better or more universal or more beautiful one. Take
it as a suggestion directing in the (hopefully) right direction.

It's the function get_arg_text() in CallTips.py, which has to be
changed, e.g. in the following way:

def get_arg_text(ob):
     "Get a string describing the arguments for the given object"

     #### --- add helper function stringify --- ####

     def stringify(t):
         if isinstance(t,tuple):
             return str(t)
         elif isinstance(t,str):
             return "'%s'" % t
         else:
             return t

     argText = ""
     if ob is not None:
         argOffset = 0
         if type(ob)==types.ClassType:
             # Look for the highest __init__ in the class chain.
             fob = _find_constructor(ob)
             if fob is None:
                 fob = lambda: None
             else:
                 argOffset = 1
         elif type(ob)==types.MethodType:
             # bit of a hack for methods - turn it into a function
             # but we drop the "self" param.
             fob = ob.im_func
             argOffset = 1
         else:
             fob = ob
         # Try and build one for Python defined functions
         if type(fob) in [types.FunctionType, types.LambdaType]:
             try:
                 realArgs = ob.func_code.co_varnames[argOffset:fob.func_code.co_argcount]
                 defaults = fob.func_defaults or []

                 #### --- ... and use it here --- ####

                 defaults = list(map(lambda name: "=%s" % stringify(name), defaults))
                 defaults = [""] * (len(realArgs)-len(defaults)) + defaults
                 items = map(lambda arg, dflt: arg+dflt, realArgs, defaults)
                 if fob.func_code.co_flags & 0x4:
                     items.append("...")
                 if fob.func_code.co_flags & 0x8:
                     items.append("***")
                 argText = ", ".join(items)
                 argText = "(%s)" % argText
             except:
                 pass
         # See if we can use the docstring
         doc = getattr(ob, "__doc__", "")
         if doc:
             doc = doc.lstrip()
             pos = doc.find("\n")
             if pos < 0 or pos > 70:
                 pos = 70
             if argText:
                 argText += "\n"
             argText += doc[:pos]
     return argText


(Attention: possibly strange linebreaks caused by email client)

If the bug has been corrected already, please ignore this message.
If this is the wrong place to submit a patch like this, please direct me
to the right one.

I've read that there is an alpha release of IDLE v1.2. Where can I get it?

Regards,

Gregor Lingl


-- 
Gregor Lingl
Reisnerstrasse 3/19
A-1030 Wien

Telefon: +43 1 713 33 98
Mobil:   +43 664 140 35 27

Website: python4kids.net



More information about the IDLE-dev mailing list