Embedding python into PyQt

Jody Winston josephwinston at mac.com
Mon May 3 09:08:26 EDT 2004


"Diez B. Roggisch" <deetsNOSPAM at web.de> writes:

>> What I am trying to do is to embed the python interactive interpreter
>> inside a qt TextEdit.
>> 
>> I could write an event loop myself, but I was wandering if there exists a
>> solution somewhere, or the best way to do it myself.
>> 
>
> I'm quite sure this has been discussed on the pykde mailing list a while ago
> - search the archines. 
>
> A program that actually does do that is eric3.
> -- 
> Regards,
>
> Diez B. Roggisch

"""mainloop.py -- a nearly exact imitation of the Python main loop."""

"""Based on:

http://groups.google.com/groups?q=compile+single+python+exec+syntax&hl=en&lr=&ie=UTF-8&selm=199705282255.SAA23573%40eric.CNRI.Reston.Va.US&rnum=2
"""

import traceback, sys

def run(code, env):
    try:
        exec code in env
    except:
        sys.last_type = sys.exc_type
        sys.last_value = sys.exc_value
        sys.last_traceback = sys.exc_traceback
        traceback.print_exception(sys.last_type,
                                  sys.last_value,
                                  sys.last_traceback)

def mainloop(env):

    print "Fake Python", sys.version
#    print sys.copyright
    print 'Type "help", "copyright", "credits" or "license" for more information.'

    # Set sys.ps1 and sys.ps2 if they are undefined;
    # they are only set in interactive mode
    try:
        sys.ps1
    except AttributeError:
        sys.ps1 = ">>> "
    try:
        sys.ps2
    except AttributeError:
        sys.ps2 = "... "

    # Source collected so far; empty if at start of statement
    source = ""

    while 1:
        if source:
            prompt = sys.ps2
        else:
            prompt = sys.ps1

        try:
            line = raw_input(prompt)
        except EOFError:
            break
        except KeyboardInterrupt:
            source = ""
            print "\nKeyboardInterrupt"
            continue

        if source:
            source = source + "\n" + line
        else:
            source = line
        
        # Compile three times: as is, with \n, and with \n\n appended.
        # If it compiles as is, it's complete.  If it compiles with
        # one \n appended, we expect more.  If it doesn't compile
        # either way, we compare the error we get when compiling with
        # \n or \n\n appended.  If the errors are the same, the code
        # is broken.  But if the errors are different, we expect more.
        # Not intuitive; not even guaranteed to hold in future
        # releases; but this matches the compiler's behavior in Python
        # 1.4 and 1.5.
    
        err = err1 = err2 = None
        code = code1 = code2 = None

        try:
            code = compile(source, "<input>", "single")
        except SyntaxError, err:
            pass

        try:
            code1 = compile(source + "\n", "<input>", "single")
        except SyntaxError, err1:
            pass

        try:
            code2 = compile(source + "\n\n", "<input>", "single")
        except SyntaxError, err2:
            pass

##        print code, code1, code2
##        print 'err = "%s"' % (err)
##        print 'err1 = "%s"' % (err1)
##        print 'err2 = "%s"' % (err2)
##        print "same = ", err1 == err2
        
        if code:
##            print "We got code"
            run(code, env)
            source = ""
        elif code1:
##            print "We got code1"
            pass
        elif str(err1) == str(err2):
##            print "err1 == err2"
            traceback.print_exception(SyntaxError, err1, None)
            source = ""

if __name__ == '__main__':
    mainloop(globals())
    

-- 
Jody Winston



More information about the Python-list mailing list