inspected console

C

castironpi

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.... def f( self ):
.... print 2
....'\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()
 
C

castironpi

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()
'\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.... b=0
....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()
 
C

castironpi

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()
'\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
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,039
Messages
2,570,376
Members
47,028
Latest member
IsmaelLans

Latest Threads

Top