Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!feeder.erje.net!eu.feeder.erje.net!newsfeed.xs4all.nl!newsfeed3.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'interpreter': 0.05; 'url:pipermail': 0.05; 'debugging': 0.07; 'string': 0.09; '*args,': 0.09; 'apis': 0.09; 'data):': 0.09; 'python': 0.11; 'def': 0.12; 'gui': 0.12; 'wrote': 0.14; 'itself.': 0.14; '"..."': 0.16; '(written': 0.16; '**kwargs)': 0.16; '**kwargs):': 0.16; 'accepts': 0.16; 'apis.': 0.16; 'boolean': 0.16; 'customizing': 0.16; 'eric,': 0.16; 'expects': 0.16; 'interpreter,': 0.16; 'line)': 0.16; 'modules.': 0.16; 'self.buffer': 0.16; 'singleton': 0.16; 'stderr': 0.16; 'stdout': 0.16; 'subclass': 0.16; 'sys.stderr': 0.16; 'sys.stdout': 0.16; 'subject:python': 0.16; 'thanks,': 0.17; 'wrote:': 0.18; 'wed,': 0.18; 'trying': 0.19; 'basically': 0.19; '(the': 0.22; 'email addr:gmail.com>': 0.22; 'suggested': 0.26; 'defined': 0.27; 'gets': 0.27; 'to:2**1': 0.27; 'message-id:@mail.gmail.com': 0.30; "i'm": 0.30; 'code': 0.31; 'embed': 0.31; 'inspect': 0.31; 'sep': 0.31; 'yes.': 0.31; 'allows': 0.31; 'class': 0.32; 'figure': 0.32; 'stuff': 0.32; 'url:python': 0.33; 'skip:_ 10': 0.34; "can't": 0.35; 'something': 0.35; 'but': 0.35; 'received:google.com': 0.35; 'controls': 0.36; 'interact': 0.36; 'module.': 0.36; 'method': 0.36; "i'll": 0.36; 'url:org': 0.36; 'should': 0.36; 'application': 0.37; 'requirements': 0.37; 'two': 0.37; 'architecture': 0.38; 'remote': 0.38; 'server': 0.38; 'skip:& 10': 0.38; 'handle': 0.38; 'to:addr :python-list': 0.38; 'pm,': 0.38; 'explain': 0.39; 'skip:& 20': 0.39; '\xa0\xa0\xa0': 0.39; 'sure': 0.39; 'to:addr:python.org': 0.39; 'url:mail': 0.40; 'easy': 0.60; 'took': 0.61; 'show': 0.63; 'more': 0.64; 'different': 0.65; 'to:addr:gmail.com': 0.65; 'within': 0.65; 'services.': 0.70; 'yours': 0.88; 'scott': 0.93; '2013': 0.98 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=IdMkHifNCvHE2gVPwNIv2G5pkwuEFHxyDjaKzV+q+lY=; b=iKf4or4EWQx02KXWgAeGFyrzyM+3c/Lo0A8kZKK2qksUj4aNzEobZ+HKK0JLmTbvyS Vpy2AIS+lIqB/lg/CQx2AgE3feam220zj31RlabpOUVUx172qWT2sJVqpwVeSro/gGwf LnaBsK2Bw4CorwLbqFltRYYqh72D53IYpNwD2idQsqfFuRceR0yRv6MEMdPqw5cio5WW lLMNEIoiRPKsjafx6I1oh4wVI4h9rMa4pzKcDExNhqqXkyZ0OLC9yivAtAqfgw/yCoao k+xopjyZorSkYVLO+MFunqrvrF+8Cngbt4EMGxGHadQxAB1HkwyU5JUSjR0bQXH1B8ZP 012w== MIME-Version: 1.0 X-Received: by 10.58.207.103 with SMTP id lv7mr1398832vec.33.1378923166899; Wed, 11 Sep 2013 11:12:46 -0700 (PDT) Date: Wed, 11 Sep 2013 14:12:46 -0400 Subject: Re: embedding interactive python interpreter From: Eric Frederich To: Scott , python-list@python.org Content-Type: multipart/alternative; boundary=e89a8f923edc8925f204e61f919a X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 142 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1378923584 news.xs4all.nl 15986 [2001:888:2000:d::a6]:59429 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:53983 --e89a8f923edc8925f204e61f919a Content-Type: text/plain; charset=ISO-8859-1 Scott, Yes. As Mark Hammond suggested I took a look into the code/console modules. I wound up using InteractiveConsole from the code module. I'm sure my requirements are completely different from yours but I'll explain what I did anyway... I was working with a client/server architecture where I wanted the client to be able to interact with a server-side Python console. Yes, I know this is a huge security hole. It is only used as a debugging console to be able to interactively inspect the state of the remote server process from within the client application itself. This 3rd party client server application I was customizing allows me to write my own services. So I wrote a service that accepts a string (the python line) and returns two strings and a boolean (stdout, stderr, and whether or not the interpreter expects more input). That boolean basically controls whether the console should show a ">>>" or a "..." and comes from InteractiveConsole.push. To get stdout and stderr I monkey patched sys.stdout and sys.stderr with an instance of MyBuffer. class MyBuffer(object): def __init__(self): self.buffer = [] def write(self, data): self.buffer.append(data) def get(self): ret = ''.join(self.buffer) self.buffer = [] return ret In my subclass of InteractiveConsole I defined the following... def __init__(self, *args, **kwargs): InteractiveConsole.__init__(self, *args, **kwargs) self.mb_out = MyBuffer() self.mb_err = MyBuffer() def process(self, s): sys.stdout, sys.stderr = self.mb_out, self.mb_err more = self.push(s) sys.stdout, sys.stderr = sys.__stdout__, sys.__stderr__ return self.mb_out.get(), self.mb_err.get(), more My service (written in c++), upon initialization gets a handle to a singleton instance of this InteractiveConsole sublcass using the Python C APIs. When the service responds to a request it uses the Python C APIs to call the process method above and returns the two strings and the boolean. The client, which happens to be Java/Eclipse based, then has something that resembles a Python console in the GUI and uses that single service to interact with the remote Python console. Lots of stuff going on but it works very well. On Wed, Sep 11, 2013 at 1:42 PM, Scott wrote: > Eric, > > https://mail.python.org/pipermail/python-list/2011-March/600441.html > > Did you ever figure this out? I'm trying to embed an interactive > interpreter, and I'm sure that python has an easy way to do this, but I > can't seem to find it... > > Thanks, > -C. Scott! Brown > --e89a8f923edc8925f204e61f919a Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable
Scott,

Yes= .
As Mark Hammond suggested I took a look into the code/console modules.=
I wound up using InteractiveConsole from the code module.
I'm su= re my requirements are completely different from yours but I'll explain= what I did anyway...

I was working with a client/server architecture where I wanted th= e client to be able to interact with a server-side Python console.
Yes, I know this is a huge security hole.
It is only used as a debuggin= g console to be able to interactively inspect the state of the remote serve= r process from within the client application itself.

This 3rd party client server application I was customizing allows= me to write my own services.
So I wrote a service that accepts a = string (the python line) and returns two strings and a boolean (stdout, std= err, and whether or not the interpreter expects more input).
That boolean basically controls whether the console should show a &qu= ot;>>>" or a "..." and comes from InteractiveConsol= e.push.

To get stdout and stderr I monkey patched sys.stdout a= nd sys.stderr with an instance of MyBuffer.

class MyBuffer(object):
=A0=A0=A0 def __init__(self):
=A0=A0= =A0=A0=A0=A0=A0 self.buffer =3D []
=A0=A0=A0 def write(self, data):
= =A0=A0=A0=A0=A0=A0=A0 self.buffer.append(data)
=A0=A0=A0 def get(self):<= br>=A0=A0=A0=A0=A0=A0=A0 ret =3D ''.join(self.buffer)
=A0=A0=A0=A0=A0=A0=A0 self.buffer =3D []
=A0=A0=A0=A0=A0=A0=A0 return re= t

In my subclass of InteractiveConsole I defined the following...
=A0=A0=A0 def __init__(self, *args, **kwargs):
=A0=A0=A0=A0=A0=A0= =A0 InteractiveConsole.__init__(self, *args, **kwargs)
=A0=A0=A0=A0=A0=A0=A0 self.mb_out =3D MyBuffer()
=A0=A0=A0=A0=A0=A0=A0 s= elf.mb_err =3D MyBuffer()

=A0=A0=A0 def process(self, s):
=A0=A0= =A0=A0=A0=A0=A0 sys.stdout, sys.stderr =3D self.mb_out, self.mb_err
=A0= =A0=A0=A0=A0=A0=A0 more =3D self.push(s)
=A0=A0=A0=A0=A0=A0=A0 sys.stdou= t, sys.stderr =3D sys.__stdout__, sys.__stderr__
=A0=A0=A0=A0=A0=A0=A0 return self.mb_out.get(), self.mb_err.get(), more
=
My service (written in c++), upon initialization gets a hand= le to a singleton instance of this InteractiveConsole sublcass using the Py= thon C APIs.
When the service responds to a request it uses the Python C APIs= to call the process method above and returns the two strings and the boole= an.

The client, which happens to be Java/Eclipse based, t= hen has something that resembles a Python console in the GUI and uses that = single service to interact with the remote Python console.

Lots of stuff going on but it works very well.



On Wed, Sep 11, 2013 at 1:42 PM, Scot= t <ihearthonduras@gmail.com> wrote:
Eric,
Did you ever figure this out?=A0 I'm trying to embed an inter= active interpreter, and I'm sure that python has an easy way to do this= , but I can't seem to find it...

Thanks,
-C. Scott! Brown

--e89a8f923edc8925f204e61f919a--