[Tutor] Tutor Digest, Vol 139, Issue 29 Calling instance method in IDLE magically calls __len__?

Dino Bektešević ljetibo at gmail.com
Fri Sep 18 13:21:53 CEST 2015


Hello all,

> Hi Dino,
>
>
> I'm afraid I cannot replicate that behaviour. Also the output seems
> strange -- the "len is called" is printed on the same line as the
> prompt, and e.toFile( afterwards.
>
> If you quit idle and restart it, do you get the same behaviour? What's
> the exact version of Python?
>
> import sys
> print sys.version
>
>
>
> --
> Steve

The exact version is 2.7.6 (2.7.6 (default, Jun 22 2015, 17:58:13) [GCC
4.8.2])
The behaviour is replicable even after OS restarts. As you've noticed the
print statement gets executed and pushes the typing command into a
new-line, this behaviour is not replicable when the file is imported as a
module or run the terminal.

I have tried figuring out what was happening by using the inspect module to
see who calls the function __len__  with some radically big context but I
can't seem to interpret the output myself (bit too deep in pythons belly
for my level). Code is shown bellow:

import inspect

class Errors:
    def __init__(self):
        pass
    def toFile(self):
        pass
    def __len__(self):
        curframe = inspect.currentframe()
        calframe = inspect.getouterframes(curframe, context=15)
        for i in range(15):
            print "    caller: ",calframe[i][3]
        print "len is called"
        return 0

What I get as output now:

>>> len(e)
    caller:  __len__
    caller:  <module>
    caller:  runcode
    caller:  main
    caller:  <module>
len is called
0
>>>     caller:  __len__
    caller:  get_arg_text
    caller:  fetch_tip
    caller:  get_the_calltip
    caller:  localcall
    caller:  pollresponse
    caller:  _getresponse
    caller:  getresponse
    caller:  handle
    caller:  __init__
    caller:  __init__
    caller:  finish_request
    caller:  process_request
    caller:  _handle_request_noblock
    caller:  handle_request
    caller:  manage_socket
    caller:  run
    caller:  __bootstrap_inner
    caller:  __bootstrap
len is called
e.toFile(

Maybe that can help? I know it doesn't really, it would be better to print
the class that owns the methods called, however I don't know how to do
that, so here's at least the file names:

>>> len(e)
    caller:  /home/dino/Desktop/bitbucket/refactor/errors/errors.py
    caller:  <pyshell#9>
    caller:  /usr/lib/python2.7/idlelib/run.py
    caller:  /usr/lib/python2.7/idlelib/run.py
    caller:  <string>
len is called
0
>>>     caller:  /home/dino/Desktop/bitbucket/refactor/errors/errors.py
    caller:  /usr/lib/python2.7/idlelib/CallTips.py
    caller:  /usr/lib/python2.7/idlelib/CallTips.py
    caller:  /usr/lib/python2.7/idlelib/run.py
    caller:  /usr/lib/python2.7/idlelib/rpc.py
    caller:  /usr/lib/python2.7/idlelib/rpc.py
    caller:  /usr/lib/python2.7/idlelib/rpc.py
    caller:  /usr/lib/python2.7/idlelib/rpc.py
    caller:  /usr/lib/python2.7/idlelib/run.py
    caller:  /usr/lib/python2.7/SocketServer.py
    caller:  /usr/lib/python2.7/idlelib/rpc.py
    caller:  /usr/lib/python2.7/SocketServer.py
    caller:  /usr/lib/python2.7/SocketServer.py
    caller:  /usr/lib/python2.7/SocketServer.py
    caller:  /usr/lib/python2.7/SocketServer.py
    caller:  /usr/lib/python2.7/idlelib/run.py
    caller:  /usr/lib/python2.7/threading.py
    caller:  /usr/lib/python2.7/threading.py
    caller:  /usr/lib/python2.7/threading.py
len is called
e.toFile(


Thanks for the help,
Dino


More information about the Tutor mailing list