New PyCrust from Patrick O'Brien
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@15058 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -3,10 +3,10 @@
|
|||||||
|
|
||||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||||
__cvsid__ = "$Id$"
|
__cvsid__ = "$Id$"
|
||||||
__version__ = "$Revision$"[11:-2]
|
__revision__ = "$Revision$"[11:-2]
|
||||||
|
|
||||||
from wxPython.wx import *
|
from wxPython.wx import *
|
||||||
from crust import CrustFrame
|
from PyCrust.crust import CrustFrame
|
||||||
|
|
||||||
|
|
||||||
class App(wxApp):
|
class App(wxApp):
|
||||||
@@ -14,7 +14,7 @@ class App(wxApp):
|
|||||||
|
|
||||||
def OnInit(self):
|
def OnInit(self):
|
||||||
locals = {'__app__': 'PyCrust Standalone Application'}
|
locals = {'__app__': 'PyCrust Standalone Application'}
|
||||||
self.crustFrame = CrustFrame(locals=locals, size=(800,600))
|
self.crustFrame = CrustFrame(locals=locals)
|
||||||
self.crustFrame.Show(true)
|
self.crustFrame.Show(true)
|
||||||
self.SetTopWindow(self.crustFrame)
|
self.SetTopWindow(self.crustFrame)
|
||||||
# Add the application object to the sys module's namespace.
|
# Add the application object to the sys module's namespace.
|
||||||
|
@@ -3,19 +3,19 @@
|
|||||||
|
|
||||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||||
__cvsid__ = "$Id$"
|
__cvsid__ = "$Id$"
|
||||||
__version__ = "$Revision$"[11:-2]
|
__revision__ = "$Revision$"[11:-2]
|
||||||
|
|
||||||
# We use this object to get more introspection when run standalone.
|
# We use this object to get more introspection when run standalone.
|
||||||
application = None
|
application = None
|
||||||
|
|
||||||
import filling
|
from PyCrust import filling
|
||||||
|
|
||||||
# These are imported just to have something interesting to inspect.
|
# These are imported just to have something interesting to inspect.
|
||||||
import crust
|
from PyCrust import crust
|
||||||
import interpreter
|
from PyCrust import interpreter
|
||||||
import introspect
|
from PyCrust import introspect
|
||||||
import pseudo
|
from PyCrust import pseudo
|
||||||
import shell
|
from PyCrust import shell
|
||||||
import sys
|
import sys
|
||||||
from wxPython import wx
|
from wxPython import wx
|
||||||
|
|
||||||
|
@@ -23,12 +23,6 @@ Have you ever tried to bake a pie without one? Well, you
|
|||||||
shouldn't build a Python program without a PyCrust either.
|
shouldn't build a Python program without a PyCrust either.
|
||||||
|
|
||||||
|
|
||||||
Where can I get the latest release of PyCrust?
|
|
||||||
----------------------------------------------
|
|
||||||
The latest PyCrust releases are available at:
|
|
||||||
http://sourceforge.net/project/showfiles.php?group_id=31263
|
|
||||||
|
|
||||||
|
|
||||||
What else do I need to use PyCrust?
|
What else do I need to use PyCrust?
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
PyCrust requires Python 2.1 or later, and wxPython 2.3.1 or later.
|
PyCrust requires Python 2.1 or later, and wxPython 2.3.1 or later.
|
||||||
@@ -37,32 +31,36 @@ Python is available at http://www.python.org/.
|
|||||||
wxPython is available at http://www.wxpython.org/.
|
wxPython is available at http://www.wxpython.org/.
|
||||||
|
|
||||||
|
|
||||||
|
Where can I get the latest version of PyCrust?
|
||||||
|
----------------------------------------------
|
||||||
|
The latest production version ships with wxPython.
|
||||||
|
The latest developer version is available in CVS at:
|
||||||
|
http://sourceforge.net/cvs/?group_id=31263
|
||||||
|
|
||||||
|
|
||||||
Where is the PyCrust project hosted?
|
Where is the PyCrust project hosted?
|
||||||
------------------------------------
|
------------------------------------
|
||||||
At SourceForge, of course. The SourceForge summary page:
|
At SourceForge, of course. The SourceForge summary page:
|
||||||
http://sourceforge.net/projects/pycrust/
|
http://sourceforge.net/projects/pycrust/
|
||||||
|
|
||||||
|
|
||||||
|
I found a bug in PyCrust, what do I do with it?
|
||||||
|
-----------------------------------------------
|
||||||
|
You can send it to me at pobrien@orbtech.com.
|
||||||
|
|
||||||
|
|
||||||
|
I want a new feature added to PyCrust. Will you do it?
|
||||||
|
------------------------------------------------------
|
||||||
|
Flattery and money will get you anything. Short of that, you
|
||||||
|
can send me a request and I'll see what I can do.
|
||||||
|
|
||||||
|
|
||||||
Does PyCrust have a mailing list full of wonderful people?
|
Does PyCrust have a mailing list full of wonderful people?
|
||||||
----------------------------------------------------------
|
----------------------------------------------------------
|
||||||
As a matter of fact, we do. Join the PyCrust mailing lists at:
|
As a matter of fact, we do. Join the PyCrust mailing lists at:
|
||||||
http://sourceforge.net/mail/?group_id=31263
|
http://sourceforge.net/mail/?group_id=31263
|
||||||
|
|
||||||
|
|
||||||
I found a bug in PyCrust, what do I do with it?
|
|
||||||
-----------------------------------------------
|
|
||||||
You can send it to me at pobrien@orbtech.com, or, preferably,
|
|
||||||
submit a bug report on our bug tracker at SourceForge:
|
|
||||||
http://sourceforge.net/tracker/?group_id=31263
|
|
||||||
|
|
||||||
|
|
||||||
I want a new feature added to PyCrust. Will you do it?
|
|
||||||
------------------------------------------------------
|
|
||||||
Flattery and money will get you anything. Short of that, you
|
|
||||||
can try posting a request on our feature tracker at SourceForge:
|
|
||||||
http://sourceforge.net/tracker/?group_id=31263
|
|
||||||
|
|
||||||
|
|
||||||
What is the CVS information for this README file?
|
What is the CVS information for this README file?
|
||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
$Date$
|
$Date$
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||||
__cvsid__ = "$Id$"
|
__cvsid__ = "$Id$"
|
||||||
__version__ = "$Revision$"[11:-2]
|
__revision__ = "$Revision$"[11:-2]
|
||||||
|
|
||||||
from wxPython.wx import *
|
from wxPython.wx import *
|
||||||
from shell import Shell
|
from shell import Shell
|
||||||
@@ -14,7 +14,7 @@ class Crust(wxSplitterWindow):
|
|||||||
"""PyCrust Crust based on wxSplitterWindow."""
|
"""PyCrust Crust based on wxSplitterWindow."""
|
||||||
|
|
||||||
name = 'PyCrust Crust'
|
name = 'PyCrust Crust'
|
||||||
revision = __version__
|
revision = __revision__
|
||||||
|
|
||||||
def __init__(self, parent, id=-1, pos=wxDefaultPosition, \
|
def __init__(self, parent, id=-1, pos=wxDefaultPosition, \
|
||||||
size=wxDefaultSize, style=wxSP_3D, name='Crust Window', \
|
size=wxDefaultSize, style=wxSP_3D, name='Crust Window', \
|
||||||
@@ -42,7 +42,7 @@ class CrustFrame(wxFrame, ShellMenu):
|
|||||||
"""Frame containing all the PyCrust components."""
|
"""Frame containing all the PyCrust components."""
|
||||||
|
|
||||||
name = 'PyCrust Frame'
|
name = 'PyCrust Frame'
|
||||||
revision = __version__
|
revision = __revision__
|
||||||
|
|
||||||
def __init__(self, parent=None, id=-1, title='PyCrust', \
|
def __init__(self, parent=None, id=-1, title='PyCrust', \
|
||||||
pos=wxDefaultPosition, size=wxDefaultSize, \
|
pos=wxDefaultPosition, size=wxDefaultSize, \
|
||||||
@@ -52,7 +52,7 @@ class CrustFrame(wxFrame, ShellMenu):
|
|||||||
"""Create a PyCrust CrustFrame instance."""
|
"""Create a PyCrust CrustFrame instance."""
|
||||||
wxFrame.__init__(self, parent, id, title, pos, size, style)
|
wxFrame.__init__(self, parent, id, title, pos, size, style)
|
||||||
intro = 'Welcome To PyCrust %s - The Flakiest Python Shell' % VERSION
|
intro = 'Welcome To PyCrust %s - The Flakiest Python Shell' % VERSION
|
||||||
intro += '\nSponsored by Orbtech - Your Source For Python Development Services'
|
intro += '\nSponsored by Orbtech - Specializing in Python Application Development'
|
||||||
self.CreateStatusBar()
|
self.CreateStatusBar()
|
||||||
self.SetStatusText(intro.replace('\n', ', '))
|
self.SetStatusText(intro.replace('\n', ', '))
|
||||||
if wxPlatform == '__WXMSW__':
|
if wxPlatform == '__WXMSW__':
|
||||||
|
@@ -3,7 +3,7 @@ the local namespace or any object."""
|
|||||||
|
|
||||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||||
__cvsid__ = "$Id$"
|
__cvsid__ = "$Id$"
|
||||||
__version__ = "$Revision$"[11:-2]
|
__revision__ = "$Revision$"[11:-2]
|
||||||
|
|
||||||
from wxPython.wx import *
|
from wxPython.wx import *
|
||||||
from wxPython.stc import *
|
from wxPython.stc import *
|
||||||
@@ -19,7 +19,7 @@ class FillingTree(wxTreeCtrl):
|
|||||||
"""PyCrust FillingTree based on wxTreeCtrl."""
|
"""PyCrust FillingTree based on wxTreeCtrl."""
|
||||||
|
|
||||||
name = 'PyCrust Filling Tree'
|
name = 'PyCrust Filling Tree'
|
||||||
revision = __version__
|
revision = __revision__
|
||||||
|
|
||||||
def __init__(self, parent, id=-1, pos=wxDefaultPosition, \
|
def __init__(self, parent, id=-1, pos=wxDefaultPosition, \
|
||||||
size=wxDefaultSize, style=wxTR_HAS_BUTTONS, \
|
size=wxDefaultSize, style=wxTR_HAS_BUTTONS, \
|
||||||
@@ -203,7 +203,7 @@ class FillingText(wxStyledTextCtrl):
|
|||||||
"""PyCrust FillingText based on wxStyledTextCtrl."""
|
"""PyCrust FillingText based on wxStyledTextCtrl."""
|
||||||
|
|
||||||
name = 'PyCrust Filling Text'
|
name = 'PyCrust Filling Text'
|
||||||
revision = __version__
|
revision = __revision__
|
||||||
|
|
||||||
def __init__(self, parent, id=-1, pos=wxDefaultPosition, \
|
def __init__(self, parent, id=-1, pos=wxDefaultPosition, \
|
||||||
size=wxDefaultSize, style=wxCLIP_CHILDREN):
|
size=wxDefaultSize, style=wxCLIP_CHILDREN):
|
||||||
@@ -265,7 +265,7 @@ class Filling(wxSplitterWindow):
|
|||||||
"""PyCrust Filling based on wxSplitterWindow."""
|
"""PyCrust Filling based on wxSplitterWindow."""
|
||||||
|
|
||||||
name = 'PyCrust Filling'
|
name = 'PyCrust Filling'
|
||||||
revision = __version__
|
revision = __revision__
|
||||||
|
|
||||||
def __init__(self, parent, id=-1, pos=wxDefaultPosition, \
|
def __init__(self, parent, id=-1, pos=wxDefaultPosition, \
|
||||||
size=wxDefaultSize, style=wxSP_3D, name='Filling Window', \
|
size=wxDefaultSize, style=wxSP_3D, name='Filling Window', \
|
||||||
@@ -288,7 +288,7 @@ class FillingFrame(wxFrame):
|
|||||||
"""Frame containing the PyCrust filling, or namespace tree component."""
|
"""Frame containing the PyCrust filling, or namespace tree component."""
|
||||||
|
|
||||||
name = 'PyCrust Filling Frame'
|
name = 'PyCrust Filling Frame'
|
||||||
revision = __version__
|
revision = __revision__
|
||||||
|
|
||||||
def __init__(self, parent=None, id=-1, title='PyFilling', \
|
def __init__(self, parent=None, id=-1, title='PyFilling', \
|
||||||
pos=wxDefaultPosition, size=wxDefaultSize, \
|
pos=wxDefaultPosition, size=wxDefaultSize, \
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||||
__cvsid__ = "$Id$"
|
__cvsid__ = "$Id$"
|
||||||
__version__ = "$Revision$"[11:-2]
|
__revision__ = "$Revision$"[11:-2]
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
@@ -13,7 +13,7 @@ import introspect
|
|||||||
class Interpreter(InteractiveInterpreter):
|
class Interpreter(InteractiveInterpreter):
|
||||||
"""PyCrust Interpreter based on code.InteractiveInterpreter."""
|
"""PyCrust Interpreter based on code.InteractiveInterpreter."""
|
||||||
|
|
||||||
revision = __version__
|
revision = __revision__
|
||||||
|
|
||||||
def __init__(self, locals=None, rawin=None, \
|
def __init__(self, locals=None, rawin=None, \
|
||||||
stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr):
|
stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr):
|
||||||
|
@@ -3,7 +3,7 @@ like call tips and command auto completion."""
|
|||||||
|
|
||||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||||
__cvsid__ = "$Id$"
|
__cvsid__ = "$Id$"
|
||||||
__version__ = "$Revision$"[11:-2]
|
__revision__ = "$Revision$"[11:-2]
|
||||||
|
|
||||||
import inspect
|
import inspect
|
||||||
import string
|
import string
|
||||||
@@ -14,117 +14,128 @@ def getAutoCompleteList(command='', locals=None, includeMagic=1, \
|
|||||||
"""Return list of auto-completion options for command.
|
"""Return list of auto-completion options for command.
|
||||||
|
|
||||||
The list of options will be based on the locals namespace."""
|
The list of options will be based on the locals namespace."""
|
||||||
|
attributes = []
|
||||||
# Get the proper chunk of code from the command.
|
# Get the proper chunk of code from the command.
|
||||||
root = getRoot(command, terminator='.')
|
root = getRoot(command, terminator='.')
|
||||||
try:
|
try:
|
||||||
object = eval(root, locals)
|
if locals is not None:
|
||||||
|
object = eval(root, locals)
|
||||||
|
else:
|
||||||
|
object = eval(root)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
attributes = getAttributeNames(object, includeMagic, \
|
attributes = getAttributeNames(object, includeMagic, \
|
||||||
includeSingle, includeDouble)
|
includeSingle, includeDouble)
|
||||||
return attributes
|
return attributes
|
||||||
except:
|
|
||||||
return []
|
|
||||||
|
|
||||||
def getAttributeNames(object, includeMagic=1, includeSingle=1, includeDouble=1):
|
def getAttributeNames(object, includeMagic=1, includeSingle=1, includeDouble=1):
|
||||||
"""Return list of unique attributes, including inherited, for an object."""
|
"""Return list of unique attributes, including inherited, for an object."""
|
||||||
attributes = []
|
attributes = []
|
||||||
dict = {}
|
dict = {}
|
||||||
|
if not hasattrAlwaysReturnsTrue(object):
|
||||||
|
# Add some attributes that don't always get picked up.
|
||||||
|
# If they don't apply, they'll get filtered out at the end.
|
||||||
|
attributes += ['__bases__', '__class__', '__dict__', '__name__', \
|
||||||
|
'func_closure', 'func_code', 'func_defaults', \
|
||||||
|
'func_dict', 'func_doc', 'func_globals', 'func_name']
|
||||||
if includeMagic:
|
if includeMagic:
|
||||||
try: attributes += object._getAttributeNames()
|
try: attributes += object._getAttributeNames()
|
||||||
except: pass
|
except: pass
|
||||||
# Get all attribute names, removing duplicates from the attribute list.
|
# Get all attribute names.
|
||||||
for item in getAllAttributeNames(object):
|
attrdict = getAllAttributeNames(object)
|
||||||
|
for attrlist in attrdict.values():
|
||||||
|
attributes += attrlist
|
||||||
|
# Remove duplicates from the attribute list.
|
||||||
|
for item in attributes:
|
||||||
dict[item] = None
|
dict[item] = None
|
||||||
attributes += dict.keys()
|
attributes = dict.keys()
|
||||||
attributes.sort(lambda x, y: cmp(x.upper(), y.upper()))
|
attributes.sort(lambda x, y: cmp(x.upper(), y.upper()))
|
||||||
if not includeSingle:
|
if not includeSingle:
|
||||||
attributes = filter(lambda item: item[0]!='_' or item[1]=='_', attributes)
|
attributes = filter(lambda item: item[0]!='_' \
|
||||||
|
or item[1]=='_', attributes)
|
||||||
if not includeDouble:
|
if not includeDouble:
|
||||||
attributes = filter(lambda item: item[:2]!='__', attributes)
|
attributes = filter(lambda item: item[:2]!='__', attributes)
|
||||||
# Make sure we haven't picked up any bogus attributes somehow.
|
# Make sure we haven't picked up any bogus attributes somehow.
|
||||||
attributes = [attribute for attribute in attributes if hasattr(object, attribute)]
|
attributes = [attribute for attribute in attributes \
|
||||||
|
if hasattr(object, attribute)]
|
||||||
return attributes
|
return attributes
|
||||||
|
|
||||||
|
def hasattrAlwaysReturnsTrue(object):
|
||||||
|
return hasattr(object, 'bogu5_123_aTTri8ute')
|
||||||
|
|
||||||
def getAllAttributeNames(object):
|
def getAllAttributeNames(object):
|
||||||
"""Return list of all attributes, including inherited, for an object.
|
"""Return mapping of all attributes, including inherited, for an object.
|
||||||
|
|
||||||
Recursively walk through a class and all base classes.
|
Recursively walk through a class and all base classes.
|
||||||
"""
|
"""
|
||||||
|
attrdict = {} # (object, technique, count): [list of attributes]
|
||||||
# !!!
|
# !!!
|
||||||
# !!! Do Not use hasattr() as a test anywhere in this function,
|
# !!! Do Not use hasattr() as a test anywhere in this function,
|
||||||
# !!! because it is unreliable with remote objects - xmlrpc, soap, etc.
|
# !!! because it is unreliable with remote objects - xmlrpc, soap, etc.
|
||||||
|
# !!! They always return true for hasattr().
|
||||||
# !!!
|
# !!!
|
||||||
attributes = []
|
key = str(object)
|
||||||
# Wake up sleepy objects - a hack for ZODB objects in "ghost" state.
|
# Wake up sleepy objects - a hack for ZODB objects in "ghost" state.
|
||||||
wakeupcall = dir(object)
|
wakeupcall = dir(object)
|
||||||
del wakeupcall
|
del wakeupcall
|
||||||
# Get attributes available through the normal convention.
|
# Get attributes available through the normal convention.
|
||||||
attributes += dir(object)
|
attributes = dir(object)
|
||||||
|
attrdict[(key, 'dir', len(attributes))] = attributes
|
||||||
|
# Get attributes from the object's dictionary, if it has one.
|
||||||
try:
|
try:
|
||||||
keys = object.__dict__.keys()
|
attributes = object.__dict__.keys()
|
||||||
except:
|
attributes.sort()
|
||||||
|
except: # Must catch all because object might have __getattr__.
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
attributes += keys
|
attrdict[(key, '__dict__', len(attributes))] = attributes
|
||||||
# For a class instance, get the attributes for the class.
|
# For a class instance, get the attributes for the class.
|
||||||
if hasattr(object, '__class__'):
|
try:
|
||||||
# Break a circular reference. This happens with extension classes.
|
klass = object.__class__
|
||||||
if object.__class__ is object:
|
except: # Must catch all because object might have __getattr__.
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
if klass is object:
|
||||||
|
# Break a circular reference. This happens with extension classes.
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
attributes += getAllAttributeNames(object.__class__)
|
attrdict.update(getAllAttributeNames(klass))
|
||||||
# Also get attributes from any and all parent classes.
|
# Also get attributes from any and all parent classes.
|
||||||
try:
|
try:
|
||||||
bases = object.__bases__
|
bases = object.__bases__
|
||||||
except:
|
except: # Must catch all because object might have __getattr__.
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
if isinstance(bases, type(())):
|
if isinstance(bases, types.TupleType):
|
||||||
for base in bases:
|
for base in bases:
|
||||||
if type(base) is types.TypeType:
|
if type(base) is types.TypeType:
|
||||||
# Break a circular reference. Happens in Python 2.2.
|
# Break a circular reference. Happens in Python 2.2.
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
attributes += getAllAttributeNames(base)
|
attrdict.update(getAllAttributeNames(base))
|
||||||
return attributes
|
return attrdict
|
||||||
|
|
||||||
def getCallTip(command='', locals=None):
|
def getCallTip(command='', locals=None):
|
||||||
"""Return call tip text for a command.
|
"""For a command, return a tuple of object name, argspec, tip text.
|
||||||
|
|
||||||
The call tip information will be based on the locals namespace."""
|
The call tip information will be based on the locals namespace."""
|
||||||
|
calltip = ('', '', '') # object name, argspec, tip text.
|
||||||
calltip = ('', '', '')
|
|
||||||
# Get the proper chunk of code from the command.
|
# Get the proper chunk of code from the command.
|
||||||
root = getRoot(command, terminator='(')
|
root = getRoot(command, terminator='(')
|
||||||
try:
|
try:
|
||||||
object = eval(root, locals)
|
if locals is not None:
|
||||||
|
object = eval(root, locals)
|
||||||
|
else:
|
||||||
|
object = eval(root)
|
||||||
except:
|
except:
|
||||||
return calltip
|
return calltip
|
||||||
name = ''
|
name = ''
|
||||||
dropSelf = 1
|
object, dropSelf = getBaseObject(object)
|
||||||
# Switch to the object that has the information we need.
|
try:
|
||||||
if inspect.isbuiltin(object):
|
|
||||||
# Builtin functions don't have an argspec that we can get.
|
|
||||||
pass
|
|
||||||
elif inspect.ismethod(object) or hasattr(object, 'im_func'):
|
|
||||||
# Get the function from the object otherwise inspect.getargspec()
|
|
||||||
# complains that the object isn't a Python function.
|
|
||||||
object = object.im_func
|
|
||||||
elif inspect.isclass(object):
|
|
||||||
# Get the __init__ method function for the class.
|
|
||||||
constructor = getConstructor(object)
|
|
||||||
if constructor is not None:
|
|
||||||
object = constructor
|
|
||||||
elif callable(object):
|
|
||||||
# Get the __call__ method instead.
|
|
||||||
try:
|
|
||||||
object = object.__call__.im_func
|
|
||||||
except:
|
|
||||||
dropSelf = 0
|
|
||||||
else:
|
|
||||||
dropSelf = 0
|
|
||||||
if hasattr(object, '__name__'):
|
|
||||||
name = object.__name__
|
name = object.__name__
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
tip1 = ''
|
tip1 = ''
|
||||||
argspec = ''
|
argspec = ''
|
||||||
if inspect.isbuiltin(object):
|
if inspect.isbuiltin(object):
|
||||||
@@ -134,8 +145,8 @@ def getCallTip(command='', locals=None):
|
|||||||
# tip1 is a string like: "getCallTip(command='', locals=None)"
|
# tip1 is a string like: "getCallTip(command='', locals=None)"
|
||||||
argspec = apply(inspect.formatargspec, inspect.getargspec(object))
|
argspec = apply(inspect.formatargspec, inspect.getargspec(object))
|
||||||
if dropSelf:
|
if dropSelf:
|
||||||
# The first parameter to a method is a reference to the
|
# The first parameter to a method is a reference to an
|
||||||
# instance, usually coded as "self", and is passed
|
# instance, usually coded as "self", and is usually passed
|
||||||
# automatically by Python and therefore we want to drop it.
|
# automatically by Python and therefore we want to drop it.
|
||||||
temp = argspec.split(',')
|
temp = argspec.split(',')
|
||||||
if len(temp) == 1: # No other arguments.
|
if len(temp) == 1: # No other arguments.
|
||||||
@@ -158,6 +169,89 @@ def getCallTip(command='', locals=None):
|
|||||||
calltip = (name, argspec[1:-1], tip.strip())
|
calltip = (name, argspec[1:-1], tip.strip())
|
||||||
return calltip
|
return calltip
|
||||||
|
|
||||||
|
def getRoot(command, terminator=None):
|
||||||
|
"""Return the rightmost root portion of an arbitrary Python command.
|
||||||
|
|
||||||
|
Return only the root portion that can be eval()'d without side effects.
|
||||||
|
The command would normally terminate with a "(" or ".". The terminator
|
||||||
|
and anything after the terminator will be dropped."""
|
||||||
|
root = ''
|
||||||
|
validChars = "._" + string.uppercase + string.lowercase + string.digits
|
||||||
|
emptyTypes = ("''", '""', '""""""', "''''''", '[]', '()', '{}')
|
||||||
|
validSeparators = string.whitespace + ',+-*/=%<>&|^~:([{'
|
||||||
|
# Drop the final terminator and anything that follows.
|
||||||
|
command = rtrimTerminus(command, terminator)
|
||||||
|
if len(command) == 0:
|
||||||
|
root = ''
|
||||||
|
elif command in emptyTypes and terminator in ('.', '', None):
|
||||||
|
# Let empty type delimiter pairs go through.
|
||||||
|
root = command
|
||||||
|
else:
|
||||||
|
# Go backward through the command until we hit an "invalid" character.
|
||||||
|
i = len(command)
|
||||||
|
while i and command[i-1] in validChars:
|
||||||
|
i -= 1
|
||||||
|
# Default to everything from the "invalid" character to the end.
|
||||||
|
root = command[i:]
|
||||||
|
# Override certain exceptions.
|
||||||
|
if i > 0 and command[i-1] in ("'", '"'):
|
||||||
|
# Detect situations where we are in the middle of a string.
|
||||||
|
# This code catches the simplest case, but needs to catch others.
|
||||||
|
root = ''
|
||||||
|
elif ((2 <= i < len(command) and command[i] == '.') \
|
||||||
|
or (2 <= i <= len(command) and terminator in ('.', '', None))) \
|
||||||
|
and command[i-2:i] in emptyTypes:
|
||||||
|
# Allow empty types to get through.
|
||||||
|
# Don't confuse an empty tupple with an argumentless callable.
|
||||||
|
if i == 2 or (i >= 3 and command[i-3] in validSeparators):
|
||||||
|
root = command[i-2:]
|
||||||
|
return root
|
||||||
|
|
||||||
|
def rtrimTerminus(command, terminator=None):
|
||||||
|
"""Return command minus the final terminator and anything that follows."""
|
||||||
|
if terminator:
|
||||||
|
pieces = command.split(terminator)
|
||||||
|
if len(pieces) > 1:
|
||||||
|
command = terminator.join(pieces[:-1])
|
||||||
|
return command
|
||||||
|
|
||||||
|
def getBaseObject(object):
|
||||||
|
"""Return base object and dropSelf indicator for an object."""
|
||||||
|
if inspect.isbuiltin(object):
|
||||||
|
# Builtin functions don't have an argspec that we can get.
|
||||||
|
dropSelf = 0
|
||||||
|
elif inspect.ismethod(object):
|
||||||
|
# Get the function from the object otherwise inspect.getargspec()
|
||||||
|
# complains that the object isn't a Python function.
|
||||||
|
try:
|
||||||
|
if object.im_self is None:
|
||||||
|
# This is an unbound method so we do not drop self from the
|
||||||
|
# argspec, since an instance must be passed as the first arg.
|
||||||
|
dropSelf = 0
|
||||||
|
else:
|
||||||
|
dropSelf = 1
|
||||||
|
object = object.im_func
|
||||||
|
except AttributeError:
|
||||||
|
dropSelf = 0
|
||||||
|
elif inspect.isclass(object):
|
||||||
|
# Get the __init__ method function for the class.
|
||||||
|
constructor = getConstructor(object)
|
||||||
|
if constructor is not None:
|
||||||
|
object = constructor
|
||||||
|
dropSelf = 1
|
||||||
|
else:
|
||||||
|
dropSelf = 0
|
||||||
|
elif callable(object):
|
||||||
|
# Get the __call__ method instead.
|
||||||
|
try:
|
||||||
|
object = object.__call__.im_func
|
||||||
|
dropSelf = 1
|
||||||
|
except AttributeError:
|
||||||
|
dropSelf = 0
|
||||||
|
else:
|
||||||
|
dropSelf = 0
|
||||||
|
return object, dropSelf
|
||||||
|
|
||||||
def getConstructor(object):
|
def getConstructor(object):
|
||||||
"""Return constructor for class object, or None if there isn't one."""
|
"""Return constructor for class object, or None if there isn't one."""
|
||||||
try:
|
try:
|
||||||
@@ -169,40 +263,5 @@ def getConstructor(object):
|
|||||||
return constructor
|
return constructor
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def getRoot(command, terminator=None):
|
|
||||||
"""Return the rightmost root portion of an arbitrary Python command.
|
|
||||||
|
|
||||||
The command would normally terminate with a "(" or ".". Anything after
|
|
||||||
the terminator will be dropped, allowing you to get back to the root.
|
|
||||||
Return only the root portion that can be eval()'d without side effects.
|
|
||||||
"""
|
|
||||||
root = ''
|
|
||||||
validChars = "._" + string.uppercase + string.lowercase + string.digits
|
|
||||||
if terminator:
|
|
||||||
# Drop the final terminator and anything that follows.
|
|
||||||
pieces = command.split(terminator)
|
|
||||||
if len(pieces) > 1:
|
|
||||||
command = terminator.join(pieces[:-1])
|
|
||||||
if len(command) == 0:
|
|
||||||
root = ''
|
|
||||||
elif command in ("''", '""', '""""""', '[]', '()', '{}'):
|
|
||||||
# Let empty type delimiter pairs go through.
|
|
||||||
root = command
|
|
||||||
else:
|
|
||||||
# Go backward through the command until we hit an "invalid" character.
|
|
||||||
i = len(command)
|
|
||||||
while i and command[i-1] in validChars:
|
|
||||||
i -= 1
|
|
||||||
# Detect situations where we are in the middle of a string.
|
|
||||||
# This code catches the simplest case, but needs to catch others.
|
|
||||||
if command[i-1] in ("'", '"'):
|
|
||||||
# We're in the middle of a string so we aren't dealing with an
|
|
||||||
# object and it would be misleading to return anything here.
|
|
||||||
root = ''
|
|
||||||
else:
|
|
||||||
# Grab everything from the "invalid" character to the end.
|
|
||||||
root = command[i:]
|
|
||||||
return root
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||||
__cvsid__ = "$Id$"
|
__cvsid__ = "$Id$"
|
||||||
__version__ = "$Revision$"[11:-2]
|
__revision__ = "$Revision$"[11:-2]
|
||||||
|
|
||||||
class PseudoKeyword:
|
class PseudoKeyword:
|
||||||
"""A callable class that calls a method passed as a parameter.
|
"""A callable class that calls a method passed as a parameter.
|
||||||
@@ -27,8 +27,10 @@ class PseudoKeyword:
|
|||||||
def __init__(self, method):
|
def __init__(self, method):
|
||||||
"""Create a callable object that executes method when called."""
|
"""Create a callable object that executes method when called."""
|
||||||
|
|
||||||
# XXX Should probably check that this is a callable object.
|
if callable(method):
|
||||||
self.method = method
|
self.method = method
|
||||||
|
else:
|
||||||
|
raise ValueError, 'method must be callable'
|
||||||
|
|
||||||
def __call__(self, *args, **kwds):
|
def __call__(self, *args, **kwds):
|
||||||
self.method(*args, **kwds)
|
self.method(*args, **kwds)
|
||||||
@@ -63,7 +65,10 @@ class PseudoFile:
|
|||||||
class PseudoFileIn(PseudoFile):
|
class PseudoFileIn(PseudoFile):
|
||||||
|
|
||||||
def __init__(self, readline):
|
def __init__(self, readline):
|
||||||
self.readline = readline
|
if callable(readline):
|
||||||
|
self.readline = readline
|
||||||
|
else:
|
||||||
|
raise ValueError, 'readline must be callable'
|
||||||
|
|
||||||
def isatty(self):
|
def isatty(self):
|
||||||
return 1
|
return 1
|
||||||
@@ -72,7 +77,10 @@ class PseudoFileIn(PseudoFile):
|
|||||||
class PseudoFileOut(PseudoFile):
|
class PseudoFileOut(PseudoFile):
|
||||||
|
|
||||||
def __init__(self, write):
|
def __init__(self, write):
|
||||||
self.write = write
|
if callable(write):
|
||||||
|
self.write = write
|
||||||
|
else:
|
||||||
|
raise ValueError, 'write must be callable'
|
||||||
|
|
||||||
def isatty(self):
|
def isatty(self):
|
||||||
return 1
|
return 1
|
||||||
@@ -81,7 +89,10 @@ class PseudoFileOut(PseudoFile):
|
|||||||
class PseudoFileErr(PseudoFile):
|
class PseudoFileErr(PseudoFile):
|
||||||
|
|
||||||
def __init__(self, write):
|
def __init__(self, write):
|
||||||
self.write = write
|
if callable(write):
|
||||||
|
self.write = write
|
||||||
|
else:
|
||||||
|
raise ValueError, 'write must be callable'
|
||||||
|
|
||||||
def isatty(self):
|
def isatty(self):
|
||||||
return 1
|
return 1
|
||||||
|
@@ -6,7 +6,7 @@ Sponsored by Orbtech - Your Source For Python Development Services"""
|
|||||||
|
|
||||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||||
__cvsid__ = "$Id$"
|
__cvsid__ = "$Id$"
|
||||||
__version__ = "$Revision$"[11:-2]
|
__revision__ = "$Revision$"[11:-2]
|
||||||
|
|
||||||
from wxPython.wx import *
|
from wxPython.wx import *
|
||||||
from wxPython.stc import *
|
from wxPython.stc import *
|
||||||
@@ -52,7 +52,7 @@ class ShellFacade:
|
|||||||
still accessible, even though only some are visible to the user."""
|
still accessible, even though only some are visible to the user."""
|
||||||
|
|
||||||
name = 'PyCrust Shell Interface'
|
name = 'PyCrust Shell Interface'
|
||||||
revision = __version__
|
revision = __revision__
|
||||||
|
|
||||||
def __init__(self, other):
|
def __init__(self, other):
|
||||||
"""Create a ShellFacade instance."""
|
"""Create a ShellFacade instance."""
|
||||||
@@ -128,7 +128,7 @@ class Shell(wxStyledTextCtrl):
|
|||||||
"""PyCrust Shell based on wxStyledTextCtrl."""
|
"""PyCrust Shell based on wxStyledTextCtrl."""
|
||||||
|
|
||||||
name = 'PyCrust Shell'
|
name = 'PyCrust Shell'
|
||||||
revision = __version__
|
revision = __revision__
|
||||||
|
|
||||||
def __init__(self, parent, id=-1, pos=wxDefaultPosition, \
|
def __init__(self, parent, id=-1, pos=wxDefaultPosition, \
|
||||||
size=wxDefaultSize, style=wxCLIP_CHILDREN, introText='', \
|
size=wxDefaultSize, style=wxCLIP_CHILDREN, introText='', \
|
||||||
@@ -231,18 +231,9 @@ class Shell(wxStyledTextCtrl):
|
|||||||
def setBuiltinKeywords(self):
|
def setBuiltinKeywords(self):
|
||||||
"""Create pseudo keywords as part of builtins.
|
"""Create pseudo keywords as part of builtins.
|
||||||
|
|
||||||
This is a rather clever hack that sets "close", "exit" and "quit"
|
This simply sets "close", "exit" and "quit" to a helpful string.
|
||||||
to a PseudoKeyword object so that we can make them do what we want.
|
|
||||||
In this case what we want is to call our self.quit() method.
|
|
||||||
The user can type "close", "exit" or "quit" without the final parens.
|
|
||||||
"""
|
"""
|
||||||
## POB: This is having some weird side-effects so I'm taking it out.
|
|
||||||
## import __builtin__
|
|
||||||
## from pseudo import PseudoKeyword
|
|
||||||
## __builtin__.close = __builtin__.exit = __builtin__.quit = \
|
|
||||||
## PseudoKeyword(self.quit)
|
|
||||||
import __builtin__
|
import __builtin__
|
||||||
from pseudo import PseudoKeyword
|
|
||||||
__builtin__.close = __builtin__.exit = __builtin__.quit = \
|
__builtin__.close = __builtin__.exit = __builtin__.quit = \
|
||||||
'Click on the close button to leave the application.'
|
'Click on the close button to leave the application.'
|
||||||
|
|
||||||
@@ -322,6 +313,7 @@ class Shell(wxStyledTextCtrl):
|
|||||||
if self.AutoCompActive(): self.AutoCompCancel()
|
if self.AutoCompActive(): self.AutoCompCancel()
|
||||||
# Get the command between the prompt and the cursor.
|
# Get the command between the prompt and the cursor.
|
||||||
# Add the '(' to the end of the command.
|
# Add the '(' to the end of the command.
|
||||||
|
self.ReplaceSelection('')
|
||||||
command = self.GetTextRange(stoppos, currpos) + '('
|
command = self.GetTextRange(stoppos, currpos) + '('
|
||||||
self.write('(')
|
self.write('(')
|
||||||
if self.autoCallTip: self.autoCallTipShow(command)
|
if self.autoCallTip: self.autoCallTipShow(command)
|
||||||
@@ -939,21 +931,17 @@ class ShellMenu:
|
|||||||
|
|
||||||
m = self.autocompMenu = wxMenu()
|
m = self.autocompMenu = wxMenu()
|
||||||
m.Append(ID_AUTOCOMP_SHOW, 'Show Auto Completion', \
|
m.Append(ID_AUTOCOMP_SHOW, 'Show Auto Completion', \
|
||||||
'Show auto completion during dot syntax', \
|
'Show auto completion during dot syntax', 1)
|
||||||
kind=wxITEM_CHECK)
|
|
||||||
m.Append(ID_AUTOCOMP_INCLUDE_MAGIC, 'Include Magic Attributes', \
|
m.Append(ID_AUTOCOMP_INCLUDE_MAGIC, 'Include Magic Attributes', \
|
||||||
'Include attributes visible to __getattr__ and __setattr__', \
|
'Include attributes visible to __getattr__ and __setattr__', 1)
|
||||||
kind=wxITEM_CHECK)
|
|
||||||
m.Append(ID_AUTOCOMP_INCLUDE_SINGLE, 'Include Single Underscores', \
|
m.Append(ID_AUTOCOMP_INCLUDE_SINGLE, 'Include Single Underscores', \
|
||||||
'Include attibutes prefixed by a single underscore', \
|
'Include attibutes prefixed by a single underscore', 1)
|
||||||
kind=wxITEM_CHECK)
|
|
||||||
m.Append(ID_AUTOCOMP_INCLUDE_DOUBLE, 'Include Double Underscores', \
|
m.Append(ID_AUTOCOMP_INCLUDE_DOUBLE, 'Include Double Underscores', \
|
||||||
'Include attibutes prefixed by a double underscore', \
|
'Include attibutes prefixed by a double underscore', 1)
|
||||||
kind=wxITEM_CHECK)
|
|
||||||
|
|
||||||
m = self.calltipsMenu = wxMenu()
|
m = self.calltipsMenu = wxMenu()
|
||||||
m.Append(ID_CALLTIPS_SHOW, 'Show Call Tips', \
|
m.Append(ID_CALLTIPS_SHOW, 'Show Call Tips', \
|
||||||
'Show call tips with argument specifications', kind=wxITEM_CHECK)
|
'Show call tips with argument specifications', 1)
|
||||||
|
|
||||||
m = self.optionsMenu = wxMenu()
|
m = self.optionsMenu = wxMenu()
|
||||||
m.AppendMenu(ID_AUTOCOMP, '&Auto Completion', self.autocompMenu, \
|
m.AppendMenu(ID_AUTOCOMP, '&Auto Completion', self.autocompMenu, \
|
||||||
@@ -1091,7 +1079,7 @@ class ShellFrame(wxFrame, ShellMenu):
|
|||||||
"""Frame containing the PyCrust shell component."""
|
"""Frame containing the PyCrust shell component."""
|
||||||
|
|
||||||
name = 'PyCrust Shell Frame'
|
name = 'PyCrust Shell Frame'
|
||||||
revision = __version__
|
revision = __revision__
|
||||||
|
|
||||||
def __init__(self, parent=None, id=-1, title='PyShell', \
|
def __init__(self, parent=None, id=-1, title='PyShell', \
|
||||||
pos=wxDefaultPosition, size=wxDefaultSize, \
|
pos=wxDefaultPosition, size=wxDefaultSize, \
|
||||||
@@ -1100,7 +1088,7 @@ class ShellFrame(wxFrame, ShellMenu):
|
|||||||
"""Create a PyCrust ShellFrame instance."""
|
"""Create a PyCrust ShellFrame instance."""
|
||||||
wxFrame.__init__(self, parent, id, title, pos, size, style)
|
wxFrame.__init__(self, parent, id, title, pos, size, style)
|
||||||
intro = 'Welcome To PyCrust %s - The Flakiest Python Shell' % VERSION
|
intro = 'Welcome To PyCrust %s - The Flakiest Python Shell' % VERSION
|
||||||
intro += '\nSponsored by Orbtech - Your Source For Python Development Services'
|
intro += '\nSponsored by Orbtech - Specializing in Python Application Development'
|
||||||
self.CreateStatusBar()
|
self.CreateStatusBar()
|
||||||
self.SetStatusText(intro.replace('\n', ', '))
|
self.SetStatusText(intro.replace('\n', ', '))
|
||||||
if wxPlatform == '__WXMSW__':
|
if wxPlatform == '__WXMSW__':
|
||||||
|
@@ -4,7 +4,7 @@ interpreter, each have a revision property based on the CVS Revision."""
|
|||||||
|
|
||||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||||
__cvsid__ = "$Id$"
|
__cvsid__ = "$Id$"
|
||||||
__version__ = "$Revision$"[11:-2]
|
__revision__ = "$Revision$"[11:-2]
|
||||||
|
|
||||||
VERSION = '0.7.1'
|
VERSION = '0.7.2'
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user