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