inspected console
castironpi at gmail.com
castironpi at gmail.com
Mon May 7 21:00:52 EDT 2007
On May 7, 7:59 pm, castiro... at gmail.com wrote:
> On May 7, 6:52 pm, castiro... at gmail.com wrote:
>
>
>
> > Presents a console permitting inspection. Input as well as output
> > saved in Python-readable form.
> > Python 2.5.1 memoryconsole4.py logging to My Documents\console.log>>> class A:
>
> > ... def f( self ):
> > ... print 2
> > ...>>> a=A()
> > >>> import inspect
> > >>> inspect.getsource( a.f )
>
> > '\tdef f( self ):\n\t\tprint 2\n'
>
> > This enabled by a log file, optionally set to console.log. Contents
> > are:
>
> > #Mon May 07 2007 06:33:42 PM Python win32 2.5.1 in memoryconsole4.py
> > class A:
> > def f( self ):
> > print 2
>
> > a=A()
> > import inspect
> > inspect.getsource( a.f )
> > #fb: '\tdef f( self ):\n\t\tprint 2\n'
>
> > Line 10 Microsoft Win32 convenience binding; line 49 a little
> > confusing. Give it a shot.
>
> > from code import InteractiveConsole
> > import sys
> > from os import environ
> > from datetime import datetime
> > from StringIO import StringIO
> > from re import sub
> > from os.path import join,split,abspath
>
> > class LoggedStdOut(StringIO):
> > deflog= environ['USERPROFILE']+\
> > '\\My Documents\\console.log'
> > def __init__( self, log=None ):
> > StringIO.__init__( self )
> > self.stdout= None
> > self.trip,self.head= True,''
> > self.logname= log or LoggedStdOut.deflog
> > self.prettyname=join(split(split(abspath(
> > self.logname))[0])[1],split(abspath(self.logname))[1])
> > for x,_ in enumerate( open( self.logname,'r' ) ): continue
> > self._lineno= x #can use linecache
> > self._log= open( self.logname,'a' )
> > def catch( self,head='#fb: ' ):
> > self.stdout= sys.stdout
> > sys.stdout= self
> > self.head= head
> > self.trip= True
> > def throw( self ):
> > sys.stdout= self.stdout
> > self.stdout= None
> > def getlineno( self ):
> > return self._lineno
> > def logwrite( self, data ):
> > self._log.write( data )
> > self._lineno+= data.count('\n')
> > def logflush( self ):
> > self._log.flush()
> > def write( self, data ):
> > datal= sub( '\n([^$])','\n%s\\1'%self.head,data )
> > if self.trip: self.logwrite( self.head )
> > self.logwrite( datal )
> > self.trip= data.endswith('\n')
> > return self.stdout.write( data )
> > def writelines( self, data ):
> > raise 'Branch uncoded'
>
> > class LoggedInteractiveConsole(InteractiveConsole):
> > def __init__( self,log=None,locals=None,filename=None ):
> > self.out= LoggedStdOut( log )
> > if filename is None: filename= split(self.out.logname)[1]
> > InteractiveConsole.__init__( self,locals,filename )
> > self.locals.update( __logname__= abspath(
> > self.out.logname ) )
> > def push( self,line ):
> > self.out.logwrite( '%s\n'%line )
> > self.out.logflush()
> > self.out.catch()
> > more= InteractiveConsole.push( self,line )
> > self.out.throw()
> > return more
> > def write( self,data ):
> > return sys.stdout.write( data )
> > def interact( self,banner=None,*args ):
> > self.out.logwrite( '\n#%s Python %s %s in %s\n'%\
> > ( datetime.now().strftime(
> > '%a %b %d %Y %I:%M:%S %p' ),
> > sys.platform,sys.version.split()[0],
> > split(sys.argv[0])[1] ) )
> > if banner is None: banner=\
> > "Python %s %s logging to %s"%\
> > ( sys.version.split()[0],split(sys.argv[0])[1],
> > self.out.prettyname )
> > return InteractiveConsole.interact( self,banner,*args )
>
> > import compiler
> > import linecache
> > class NotatedConsole(LoggedInteractiveConsole):
> > """-Code object- intercepted in runsource, and rerun with
> > stored source before runsource. Built-in runsource
> > does not modify source between call and runcode."""
> > def runsource( self,sc,filename='<input>',*args ):
> > self._runsourceargs= sc,filename
> > return LoggedInteractiveConsole.runsource( self,sc,
> > filename,*args )
> > def runcode( self,*args ):
> > sc,filename= self._runsourceargs
> > linecache.checkcache( filename )
> > #custom second compile (fourth actually)
> > t= compiler.parse( sc )
> > compiler.misc.set_filename( filename,t )
> > def set_lineno( tree, initlineno ):
> > worklist= [ tree ]
> > while worklist:
> > node= worklist.pop( 0 )
> > if node.lineno is not None:
> > node.lineno+= initlineno
> > worklist.extend( node.getChildNodes() )
> > set_lineno( t,self.out.getlineno()-len( self.buffer )+1 )
> > code= compiler.pycodegen.\
> > InteractiveCodeGenerator( t ).getCode()
> > LoggedInteractiveConsole.runcode( self,code )
> > linecache.checkcache( filename )
>
> > if __name__=='__main__':
> > console= NotatedConsole()
> > console.interact()
>
> Console-defined objects can be pickled as well. ">>>edit()" opens
> console.log. Editor objects are pickled between statements.
>
> Python 2.5.1 furtherconsoles-display.py logging to My Documents
> \console.log>>> class A:
>
> ... b=0
> ...>>> from pickle import loads,dumps
> >>> loads(dumps(A))
>
> <class workmodule.A at 0x00B28030>>>> loads(dumps(A)).b
> 0
> >>> edit()
>
> Loaded ok
>
> and the few lines from console.log:
> #Mon May 07 2007 07:55:30 PM Python win32 2.5.1 in furtherconsoles-
> display.py
> class A:
> b=0
>
> from pickle import loads,dumps
> loads(dumps(A))
> #fb: <class workmodule.A at 0x00B28030>
> loads(dumps(A)).b
> #fb: 0
> edit()
>
> Hard coded paths on lines 24 and 67. Hope that's copy-and-pasteable
>
> import memoryconsole4 as memoryconsole
> from os.path import join,exists,split,abspath
> from os import environ
> from sys import argv
> import sys
> import cPickle as pickle
> from subprocess import Popen
> from datetime import datetime,timedelta
>
> class Editors:
> """Pickled after every statement."""
> def edit( self,filename=None ):
> assert hasattr( self,'_cmdlinestr' ) and hasattr( self,'console' )
> if filename is None: filename= abspath( self.console.out.logname )
> parms= { 'filename': filename, 'loglen': self.console.out.getlineno()
> +len(self.console.buffer)+1 }
> Popen( self._cmdlinestr % parms )
> print >>sys.stderr, "Loaded ok"
> def __repr__( self ):
> return '<%s at %i: %s>'%(self.__class__,id(self),repr( [ x for x in
> dir(self) if not x.startswith('__') ] ))
> def __call__( self,*args ):
> self.edit( *args )#what find default?
>
> class EditorsConsole(memoryconsole.NotatedConsole):
> defdat= join( environ['USERPROFILE'],'My Documents\
> \consoleeditor.pickle' )
> def __init__( self,cmdlinestr,datname=None,*args,**kwargs ):
> memoryconsole.NotatedConsole.__init__( self,*args,**kwargs )
> self._datname= datname or self.defdat
> if exists( self._datname ): self.edit=
> pickle.load( open( self._datname,'rb' ) )
> else: self.edit= Editors()
> self.edit._cmdlinestr= cmdlinestr
> self.locals.update( edit=self.edit )
> self.edit.console= self
> self.lasttimestamp= datetime.now()
> def push( self,*args ):
> more= memoryconsole.NotatedConsole.push( self,*args )
> if not more and datetime.now()- self.lasttimestamp >
> timedelta( minutes= 25 ):
> self.lasttimestamp= datetime.now()
> self.out.logwrite( '#%s in %s\n'%\
> ( self.lasttimestamp.strftime( '%a %b %d %Y %I:%M:%S
> %p' ),split(argv[0])[1] ) )
> del self.edit.console
> pickle.dump( self.edit,open( self._datname,'wb' ) ) #don't pickle me
> self.edit.console= self
> return more
> def __repr__( self ):
> return '<%s at %i: %s>'%(self.__class__,id(self),repr( [ x for x in
> dir(self) if not x.startswith('__') ] ))
>
> import compiler as c
> from memory import Memory
> import imp
> from sys import modules
>
> class ModuleConsole(EditorsConsole):
> def __init__( self,log=None,locals=None,filename=None ):
> EditorsConsole.__init__( self,log,locals,filename )
> self.workmodule= imp.new_module( 'workmodule' )
> self.workmodule.__file__= self.out.logname
> modules[self.workmodule.__name__]= self.workmodule
> self.locals.update( workmodule=self.workmodule,
> __name__=self.workmodule.__name__ )
> self.locals.update( __file__=self.workmodule.__file__ )#may omit
> __logname__
> del self.locals['__logname__']
> def runcode( self,*args ):
> EditorsConsole.runcode( self,*args )
> for k,v in self.locals.iteritems():
> setattr( self.workmodule,k,v )
>
> if __name__=='__main__':
> editorscmdlinestr= '"%s" "%%(filename)s" -cursor %%(loglen)i:
> 1'%join(environ['PROGRAMFILES'],'editplus 2\\editplus.exe')
> console= ModuleConsole(editorscmdlinestr)
> console.interact()
whoops, that line 48 is extraneous.
More information about the Python-list
mailing list