From fea018f8019cdbb6f3150de91d23b83c10a178b3 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Tue, 4 Sep 2001 23:44:17 +0000 Subject: [PATCH] A couple little fixes for wxSTC Updated to 0.6 of PyCrust git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@11560 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- wxPython/CHANGES.txt | 5 +- wxPython/contrib/stc/stc_.cpp | 28 +- wxPython/contrib/stc/stc_.py | 8 +- wxPython/demo/Main.py | 1 + wxPython/demo/PyCrustWithFilling.py | 20 + wxPython/demo/wxStyledTextCtrl_1.py | 2 + wxPython/setup.py | 2 +- wxPython/src/__version__.py | 2 +- wxPython/wxPython/lib/PyCrust/PyCrust.ico | Bin 766 -> 1546 bytes wxPython/wxPython/lib/PyCrust/PyCrust.py | 212 +-------- wxPython/wxPython/lib/PyCrust/PyFilling.py | 35 ++ wxPython/wxPython/lib/PyCrust/PyShell.py | 36 ++ wxPython/wxPython/lib/PyCrust/README.txt | 57 ++- wxPython/wxPython/lib/PyCrust/crust.py | 67 +++ wxPython/wxPython/lib/PyCrust/filling.py | 292 ++++++++++++ wxPython/wxPython/lib/PyCrust/interpreter.py | 24 +- wxPython/wxPython/lib/PyCrust/introspect.py | 25 +- wxPython/wxPython/lib/PyCrust/shell.py | 465 +++++++++++++++---- wxPython/wxPython/lib/PyCrust/version.py | 4 +- 19 files changed, 954 insertions(+), 331 deletions(-) create mode 100644 wxPython/demo/PyCrustWithFilling.py create mode 100644 wxPython/wxPython/lib/PyCrust/PyFilling.py create mode 100644 wxPython/wxPython/lib/PyCrust/PyShell.py create mode 100644 wxPython/wxPython/lib/PyCrust/crust.py create mode 100644 wxPython/wxPython/lib/PyCrust/filling.py diff --git a/wxPython/CHANGES.txt b/wxPython/CHANGES.txt index a6f0a558ff..43ef79bba6 100644 --- a/wxPython/CHANGES.txt +++ b/wxPython/CHANGES.txt @@ -9,7 +9,8 @@ EVT_DETAILED_HELP_RANGE, EVT_CONTEXT_MENU, wxHelpEvent, wxContextMenuEvent, wxContextHelp, wxContextHelpButton, wxTipWindow, and a demo to show them in action. -Deprecated PyShell and PyShellWindow, added a snapshot of PyCrust. +Deprecated PyShell and PyShellWindow, added a snapshot of PyCrust (see +http://sourceforge.net/projects/pycrust/. ) Added the new virtual list capabilities to wxListCtrl. @@ -40,6 +41,8 @@ Added wxGenBitmapTextButton, TablePrint, etc. contribs from Lorne White. Added wxNativeFontInfo and wxFontMapper. + + 2.3.1 ----- Added EVT_GRID_EDITOR_CREATED and wxGridEditorCreatedEvent so the user diff --git a/wxPython/contrib/stc/stc_.cpp b/wxPython/contrib/stc/stc_.cpp index ebd8dec5b5..1ad2814880 100644 --- a/wxPython/contrib/stc/stc_.cpp +++ b/wxPython/contrib/stc/stc_.cpp @@ -988,7 +988,7 @@ static PyObject *_wrap_wxStyledTextCtrl_GetCurLine(PyObject *self, PyObject *arg PyObject * _resultobj; wxString * _result; wxStyledTextCtrl * _arg0; - int * _arg1 = (int *) NULL; + int * _arg1; int temp; PyObject * _argo0 = 0; char *_kwnames[] = { "self", NULL }; @@ -7532,8 +7532,8 @@ static PyObject *_wrap_wxStyledTextCtrl_GetModEventMask(PyObject *self, PyObject return _resultobj; } -#define wxStyledTextCtrl_SetFocus(_swigobj,_swigarg0) (_swigobj->SetFocus(_swigarg0)) -static PyObject *_wrap_wxStyledTextCtrl_SetFocus(PyObject *self, PyObject *args, PyObject *kwargs) { +#define wxStyledTextCtrl_SetSTCFocus(_swigobj,_swigarg0) (_swigobj->SetSTCFocus(_swigarg0)) +static PyObject *_wrap_wxStyledTextCtrl_SetSTCFocus(PyObject *self, PyObject *args, PyObject *kwargs) { PyObject * _resultobj; wxStyledTextCtrl * _arg0; bool _arg1; @@ -7542,19 +7542,19 @@ static PyObject *_wrap_wxStyledTextCtrl_SetFocus(PyObject *self, PyObject *args, char *_kwnames[] = { "self","focus", NULL }; self = self; - if(!PyArg_ParseTupleAndKeywords(args,kwargs,"Oi:wxStyledTextCtrl_SetFocus",_kwnames,&_argo0,&tempbool1)) + if(!PyArg_ParseTupleAndKeywords(args,kwargs,"Oi:wxStyledTextCtrl_SetSTCFocus",_kwnames,&_argo0,&tempbool1)) return NULL; if (_argo0) { if (_argo0 == Py_None) { _arg0 = NULL; } else if (SWIG_GetPtrObj(_argo0,(void **) &_arg0,"_wxStyledTextCtrl_p")) { - PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of wxStyledTextCtrl_SetFocus. Expected _wxStyledTextCtrl_p."); + PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of wxStyledTextCtrl_SetSTCFocus. Expected _wxStyledTextCtrl_p."); return NULL; } } _arg1 = (bool ) tempbool1; { wxPy_BEGIN_ALLOW_THREADS; - wxStyledTextCtrl_SetFocus(_arg0,_arg1); + wxStyledTextCtrl_SetSTCFocus(_arg0,_arg1); wxPy_END_ALLOW_THREADS; } Py_INCREF(Py_None); @@ -7562,8 +7562,8 @@ static PyObject *_wrap_wxStyledTextCtrl_SetFocus(PyObject *self, PyObject *args, return _resultobj; } -#define wxStyledTextCtrl_GetFocus(_swigobj) (_swigobj->GetFocus()) -static PyObject *_wrap_wxStyledTextCtrl_GetFocus(PyObject *self, PyObject *args, PyObject *kwargs) { +#define wxStyledTextCtrl_GetSTCFocus(_swigobj) (_swigobj->GetSTCFocus()) +static PyObject *_wrap_wxStyledTextCtrl_GetSTCFocus(PyObject *self, PyObject *args, PyObject *kwargs) { PyObject * _resultobj; bool _result; wxStyledTextCtrl * _arg0; @@ -7571,18 +7571,18 @@ static PyObject *_wrap_wxStyledTextCtrl_GetFocus(PyObject *self, PyObject *args, char *_kwnames[] = { "self", NULL }; self = self; - if(!PyArg_ParseTupleAndKeywords(args,kwargs,"O:wxStyledTextCtrl_GetFocus",_kwnames,&_argo0)) + if(!PyArg_ParseTupleAndKeywords(args,kwargs,"O:wxStyledTextCtrl_GetSTCFocus",_kwnames,&_argo0)) return NULL; if (_argo0) { if (_argo0 == Py_None) { _arg0 = NULL; } else if (SWIG_GetPtrObj(_argo0,(void **) &_arg0,"_wxStyledTextCtrl_p")) { - PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of wxStyledTextCtrl_GetFocus. Expected _wxStyledTextCtrl_p."); + PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of wxStyledTextCtrl_GetSTCFocus. Expected _wxStyledTextCtrl_p."); return NULL; } } { wxPy_BEGIN_ALLOW_THREADS; - _result = (bool )wxStyledTextCtrl_GetFocus(_arg0); + _result = (bool )wxStyledTextCtrl_GetSTCFocus(_arg0); wxPy_END_ALLOW_THREADS; } _resultobj = Py_BuildValue("i",_result); @@ -9869,8 +9869,8 @@ static PyMethodDef stc_cMethods[] = { { "wxStyledTextCtrl_SetMouseDownCaptures", (PyCFunction) _wrap_wxStyledTextCtrl_SetMouseDownCaptures, METH_VARARGS | METH_KEYWORDS }, { "wxStyledTextCtrl_GetStatus", (PyCFunction) _wrap_wxStyledTextCtrl_GetStatus, METH_VARARGS | METH_KEYWORDS }, { "wxStyledTextCtrl_SetStatus", (PyCFunction) _wrap_wxStyledTextCtrl_SetStatus, METH_VARARGS | METH_KEYWORDS }, - { "wxStyledTextCtrl_GetFocus", (PyCFunction) _wrap_wxStyledTextCtrl_GetFocus, METH_VARARGS | METH_KEYWORDS }, - { "wxStyledTextCtrl_SetFocus", (PyCFunction) _wrap_wxStyledTextCtrl_SetFocus, METH_VARARGS | METH_KEYWORDS }, + { "wxStyledTextCtrl_GetSTCFocus", (PyCFunction) _wrap_wxStyledTextCtrl_GetSTCFocus, METH_VARARGS | METH_KEYWORDS }, + { "wxStyledTextCtrl_SetSTCFocus", (PyCFunction) _wrap_wxStyledTextCtrl_SetSTCFocus, METH_VARARGS | METH_KEYWORDS }, { "wxStyledTextCtrl_GetModEventMask", (PyCFunction) _wrap_wxStyledTextCtrl_GetModEventMask, METH_VARARGS | METH_KEYWORDS }, { "wxStyledTextCtrl_ReleaseDocument", (PyCFunction) _wrap_wxStyledTextCtrl_ReleaseDocument, METH_VARARGS | METH_KEYWORDS }, { "wxStyledTextCtrl_AddRefDocument", (PyCFunction) _wrap_wxStyledTextCtrl_AddRefDocument, METH_VARARGS | METH_KEYWORDS }, @@ -10150,12 +10150,14 @@ static struct { char *n1; char *n2; void *(*pcnv)(void *); } _swig_mapping[] = { { "_wxChar","_char",0}, { "_wxCommandEvent","_wxStyledTextEvent",SwigwxStyledTextEventTowxCommandEvent}, { "_char","_wxChar",0}, + { "_struct_wxNativeFontInfo","_wxNativeFontInfo",0}, { "_EBool","_wxCoord",0}, { "_EBool","_wxPrintQuality",0}, { "_EBool","_signed_int",0}, { "_EBool","_int",0}, { "_EBool","_wxWindowID",0}, { "_unsigned_long","_long",0}, + { "_wxNativeFontInfo","_struct_wxNativeFontInfo",0}, { "_signed_int","_wxCoord",0}, { "_signed_int","_wxPrintQuality",0}, { "_signed_int","_EBool",0}, diff --git a/wxPython/contrib/stc/stc_.py b/wxPython/contrib/stc/stc_.py index 079b8cc4fd..83863a5c3b 100644 --- a/wxPython/contrib/stc/stc_.py +++ b/wxPython/contrib/stc/stc_.py @@ -822,11 +822,11 @@ class wxStyledTextCtrlPtr(wxControlPtr): def GetModEventMask(self, *_args, **_kwargs): val = apply(stc_c.wxStyledTextCtrl_GetModEventMask,(self,) + _args, _kwargs) return val - def SetFocus(self, *_args, **_kwargs): - val = apply(stc_c.wxStyledTextCtrl_SetFocus,(self,) + _args, _kwargs) + def SetSTCFocus(self, *_args, **_kwargs): + val = apply(stc_c.wxStyledTextCtrl_SetSTCFocus,(self,) + _args, _kwargs) return val - def GetFocus(self, *_args, **_kwargs): - val = apply(stc_c.wxStyledTextCtrl_GetFocus,(self,) + _args, _kwargs) + def GetSTCFocus(self, *_args, **_kwargs): + val = apply(stc_c.wxStyledTextCtrl_GetSTCFocus,(self,) + _args, _kwargs) return val def SetStatus(self, *_args, **_kwargs): val = apply(stc_c.wxStyledTextCtrl_SetStatus,(self,) + _args, _kwargs) diff --git a/wxPython/demo/Main.py b/wxPython/demo/Main.py index 74318bcd62..5eebb35137 100644 --- a/wxPython/demo/Main.py +++ b/wxPython/demo/Main.py @@ -24,6 +24,7 @@ import images _treeList = [ ('New since last release', ['ContextHelp', 'PyCrust', + 'PyCrustWithFilling', 'VirtualListCtrl', 'wxListCtrl', 'TablePrint', diff --git a/wxPython/demo/PyCrustWithFilling.py b/wxPython/demo/PyCrustWithFilling.py new file mode 100644 index 0000000000..78a200a9d6 --- /dev/null +++ b/wxPython/demo/PyCrustWithFilling.py @@ -0,0 +1,20 @@ + +from wxPython.wx import * +from wxPython.lib.PyCrust import shell, version, filling + + +#---------------------------------------------------------------------- + +intro = 'Welcome To PyCrust %s - The Flakiest Python Shell' % version.VERSION + +def runTest(frame, nb, log): + win = wxSplitterWindow(nb, -1, size=(640, 480)) + shellWin = shell.Shell(win, -1, introText=intro) + fillingWin = filling.Filling(win, -1, size=(640, 480), + ingredients=shellWin.interp.locals) + win.SplitHorizontally(shellWin, fillingWin) + return win + +#---------------------------------------------------------------------- + +overview = filling.__doc__ diff --git a/wxPython/demo/wxStyledTextCtrl_1.py b/wxPython/demo/wxStyledTextCtrl_1.py index cf589e92f3..76aba88b50 100644 --- a/wxPython/demo/wxStyledTextCtrl_1.py +++ b/wxPython/demo/wxStyledTextCtrl_1.py @@ -175,6 +175,8 @@ def runTest(frame, nb, log): print "GetStyledText(98, 104): ", repr(ed.GetStyledText(98, 104)), len(ed.GetStyledText(98, 104)) print print "GetCurLine(): ", repr(ed.GetCurLine()) + ed.GotoPos(5) + print "GetCurLine(): ", repr(ed.GetCurLine()) print print "GetLine(1): ", repr(ed.GetLine(1)) print diff --git a/wxPython/setup.py b/wxPython/setup.py index ee2b3d47f9..d9a0bb2e23 100755 --- a/wxPython/setup.py +++ b/wxPython/setup.py @@ -13,7 +13,7 @@ from my_distutils import run_swig, contrib_copy_tree # flags and values that affect this script #---------------------------------------------------------------------- -VERSION = "2.3.2b1" +VERSION = "2.3.2b2" DESCRIPTION = "Cross platform GUI toolkit for Python" AUTHOR = "Robin Dunn" AUTHOR_EMAIL = "Robin Dunn " diff --git a/wxPython/src/__version__.py b/wxPython/src/__version__.py index eea883684f..f50900a001 100644 --- a/wxPython/src/__version__.py +++ b/wxPython/src/__version__.py @@ -1 +1 @@ -ver = '2.3.2b1' +ver = '2.3.2b2' diff --git a/wxPython/wxPython/lib/PyCrust/PyCrust.ico b/wxPython/wxPython/lib/PyCrust/PyCrust.ico index bb29c8edd7e66d24e5acde41c632ebb805b87891..2075eec3978f1651c5dad964e71cab2e074089b1 100644 GIT binary patch literal 1546 zcmeH{KTH!*9LGPkP#~nzgrO#y*b%j+mjJd(uoV?5Vp_!nw${lGhF-!@5{EnEP`10p zINohmVsbSuo$PIl?IdpP=mv>{495CtT5xl7GqwIwAAY3})q<-ElltVeLR6E7i2LGP zAUG%3eh(8B^TW6f)oXoX<1A@Kw}H^u%H$DOEd{-i0nuJAy3c*O5d zdc7ZCrSl{Fu9Ju-$cVlt_{GnaOv+VTD)lHDHkRMPY3*ZJPG2XZV$j-c!BUw_*~IJi zFzRgzTNa(Y4zA-u$pNE@Zn+c-MZB6vx7&qO0jxG@tBLvACG*sv)7huK+s1I}=x=-y zYdX2AOROw43KncN$?Fznr%AeCKvrbSi!Iuqd)SVLR+P9RvX)#D>pE_&P9kfP&U&PC zvYuD0qpe9^vDD;Z$tDvq$;WJRQJcb)LvF$%7ZD;H6-F(zlu*_D+{3DMuw2Eq^e;VE zTj;vJUw3NNKynKIUW#xg2=WnLxGq)BNZr@qB8xAi{&&gz}rHxAeBL12A1hx8wdNzED%9JWo7^Y`-NeVsyue8_f>~eJg z9k0GWK=StieA6GPJ@rKG@JUNy?X?7eH$ren%Md9gdKI$W$XOAUmmry!5-Dq8r!>Z? zBAzxzO$%UbpmkU$zHE6l(2OW(RYUe1r&$ z)Fj+QvAFmA=iIxDWqcdyW1sT2rPo)xMz%;3e5eO~rChb~`%^9A_*2Ywb{KLcM0*hm9^!K!#8l_#G{|IAsMso6S1XX#9x FeFHZg6}12W diff --git a/wxPython/wxPython/lib/PyCrust/PyCrust.py b/wxPython/wxPython/lib/PyCrust/PyCrust.py index 84edad7ca0..d2281ce306 100644 --- a/wxPython/wxPython/lib/PyCrust/PyCrust.py +++ b/wxPython/wxPython/lib/PyCrust/PyCrust.py @@ -1,6 +1,5 @@ #!/usr/bin/env python -"""PyCrust is a python shell application. -""" +"""PyCrust is a python shell and namespace browser application.""" __author__ = "Patrick K. O'Brien " __cvsid__ = "$Id$" @@ -8,209 +7,32 @@ __date__ = "July 1, 2001" __version__ = "$Revision$"[11:-2] from wxPython.wx import * +from crust import CrustFrame -from version import VERSION -from shell import Shell - -ID_AUTOCOMP = NewId() -ID_AUTOCOMP_SHOW = NewId() -ID_AUTOCOMP_INCLUDE_MAGIC = NewId() -ID_AUTOCOMP_INCLUDE_SINGLE = NewId() -ID_AUTOCOMP_INCLUDE_DOUBLE = NewId() -ID_CALLTIPS = NewId() -ID_CALLTIPS_SHOW = NewId() - - -class Frame(wxFrame): - """Main window for the PyCrust application.""" - def __init__(self, parent, id, title): - """Create the main frame object for the application.""" - wxFrame.__init__(self, parent, id, title) - intro = 'Welcome To PyCrust %s - The Flakiest Python Shell' % VERSION - self.CreateStatusBar() - self.SetStatusText(intro) - self.icon = wxIcon('PyCrust.ico', wxBITMAP_TYPE_ICO) - self.SetIcon(self.icon) - self.createMenus() - # Create the shell, which will create a default interpreter. - locals = {'__app__': 'PyCrust Application'} - self.shell = Shell(parent=self, id=-1, introText=intro, locals=locals) - # Override the shell so that status messages go to the status bar. - self.shell.setStatusText = self.SetStatusText - - def createMenus(self): - m = self.fileMenu = wxMenu() - m.AppendSeparator() - m.Append(wxID_EXIT, 'E&xit', 'Exit PyCrust') - - m = self.editMenu = wxMenu() - m.Append(wxID_UNDO, '&Undo \tCtrl+Z', 'Undo the last action') - m.Append(wxID_REDO, '&Redo \tCtrl+Y', 'Redo the last undone action') - m.AppendSeparator() - m.Append(wxID_CUT, 'Cu&t \tCtrl+X', 'Cut the selection') - m.Append(wxID_COPY, '&Copy \tCtrl+C', 'Copy the selection') - m.Append(wxID_PASTE, '&Paste \tCtrl+V', 'Paste') - m.AppendSeparator() - m.Append(wxID_CLEAR, 'Cle&ar \tDel', 'Delete the selection') - m.Append(wxID_SELECTALL, 'Select A&ll \tCtrl+A', 'Select all text') - - m = self.autocompMenu = wxMenu() - m.Append(ID_AUTOCOMP_SHOW, 'Show Auto Completion', \ - 'Show auto completion during dot syntax', checkable=1) - m.Append(ID_AUTOCOMP_INCLUDE_MAGIC, 'Include Magic Attributes', \ - 'Include attributes visible to __getattr__ and __setattr__', checkable=1) - m.Append(ID_AUTOCOMP_INCLUDE_SINGLE, 'Include Single Underscores', \ - 'Include attibutes prefixed by a single underscore', checkable=1) - m.Append(ID_AUTOCOMP_INCLUDE_DOUBLE, 'Include Double Underscores', \ - 'Include attibutes prefixed by a double underscore', checkable=1) - - m = self.calltipsMenu = wxMenu() - m.Append(ID_CALLTIPS_SHOW, 'Show Call Tips', \ - 'Show call tips with argument specifications', checkable=1) - - m = self.optionsMenu = wxMenu() - m.AppendMenu(ID_AUTOCOMP, '&Auto Completion', self.autocompMenu, \ - 'Auto Completion Options') - m.AppendMenu(ID_CALLTIPS, '&Call Tips', self.calltipsMenu, \ - 'Call Tip Options') - - m = self.helpMenu = wxMenu() - m.AppendSeparator() - m.Append(wxID_ABOUT, '&About...', 'About PyCrust') - - b = self.menuBar = wxMenuBar() - b.Append(self.fileMenu, '&File') - b.Append(self.editMenu, '&Edit') - b.Append(self.optionsMenu, '&Options') - b.Append(self.helpMenu, '&Help') - self.SetMenuBar(b) - - EVT_MENU(self, wxID_EXIT, self.OnExit) - EVT_MENU(self, wxID_UNDO, self.OnUndo) - EVT_MENU(self, wxID_REDO, self.OnRedo) - EVT_MENU(self, wxID_CUT, self.OnCut) - EVT_MENU(self, wxID_COPY, self.OnCopy) - EVT_MENU(self, wxID_PASTE, self.OnPaste) - EVT_MENU(self, wxID_CLEAR, self.OnClear) - EVT_MENU(self, wxID_SELECTALL, self.OnSelectAll) - EVT_MENU(self, wxID_ABOUT, self.OnAbout) - EVT_MENU(self, ID_AUTOCOMP_SHOW, self.OnAutoCompleteShow) - EVT_MENU(self, ID_AUTOCOMP_INCLUDE_MAGIC, self.OnAutoCompleteIncludeMagic) - EVT_MENU(self, ID_AUTOCOMP_INCLUDE_SINGLE, self.OnAutoCompleteIncludeSingle) - EVT_MENU(self, ID_AUTOCOMP_INCLUDE_DOUBLE, self.OnAutoCompleteIncludeDouble) - EVT_MENU(self, ID_CALLTIPS_SHOW, self.OnCallTipsShow) - - EVT_UPDATE_UI(self, wxID_UNDO, self.OnUpdateMenu) - EVT_UPDATE_UI(self, wxID_REDO, self.OnUpdateMenu) - EVT_UPDATE_UI(self, wxID_CUT, self.OnUpdateMenu) - EVT_UPDATE_UI(self, wxID_COPY, self.OnUpdateMenu) - EVT_UPDATE_UI(self, wxID_PASTE, self.OnUpdateMenu) - EVT_UPDATE_UI(self, wxID_CLEAR, self.OnUpdateMenu) - EVT_UPDATE_UI(self, ID_AUTOCOMP_SHOW, self.OnUpdateMenu) - EVT_UPDATE_UI(self, ID_AUTOCOMP_INCLUDE_MAGIC, self.OnUpdateMenu) - EVT_UPDATE_UI(self, ID_AUTOCOMP_INCLUDE_SINGLE, self.OnUpdateMenu) - EVT_UPDATE_UI(self, ID_AUTOCOMP_INCLUDE_DOUBLE, self.OnUpdateMenu) - EVT_UPDATE_UI(self, ID_CALLTIPS_SHOW, self.OnUpdateMenu) - - def OnExit(self, event): - self.Close(true) - - def OnUndo(self, event): - self.shell.Undo() - - def OnRedo(self, event): - self.shell.Redo() - - def OnCut(self, event): - self.shell.Cut() - - def OnCopy(self, event): - self.shell.Copy() - - def OnPaste(self, event): - self.shell.Paste() - - def OnClear(self, event): - self.shell.Clear() - - def OnSelectAll(self, event): - self.shell.SelectAll() - - def OnAbout(self, event): - """Display an About PyCrust window.""" - title = 'About PyCrust' - text = 'PyCrust %s\n\n' % VERSION + \ - 'Yet another Python shell, only flakier.\n\n' + \ - 'Half-baked by Patrick K. O\'Brien,\n' + \ - 'the other half is still in the oven.\n\n' + \ - 'Shell Revision: %s\n' % self.shell.revision + \ - 'Interpreter Revision: %s\n' % self.shell.interp.revision - dialog = wxMessageDialog(self, text, title, wxOK | wxICON_INFORMATION) - dialog.ShowModal() - dialog.Destroy() - - def OnAutoCompleteShow(self, event): - self.shell.autoComplete = event.IsChecked() - - def OnAutoCompleteIncludeMagic(self, event): - self.shell.autoCompleteIncludeMagic = event.IsChecked() - - def OnAutoCompleteIncludeSingle(self, event): - self.shell.autoCompleteIncludeSingle = event.IsChecked() - - def OnAutoCompleteIncludeDouble(self, event): - self.shell.autoCompleteIncludeDouble = event.IsChecked() - - def OnCallTipsShow(self, event): - self.shell.autoCallTip = event.IsChecked() - - def OnUpdateMenu(self, event): - """Update menu items based on current status.""" - id = event.GetId() - if id == wxID_UNDO: - event.Enable(self.shell.CanUndo()) - elif id == wxID_REDO: - event.Enable(self.shell.CanRedo()) - elif id == wxID_CUT: - event.Enable(self.shell.CanCut()) - elif id == wxID_COPY: - event.Enable(self.shell.CanCopy()) - elif id == wxID_PASTE: - event.Enable(self.shell.CanPaste()) - elif id == wxID_CLEAR: - event.Enable(self.shell.CanCut()) - elif id == ID_AUTOCOMP_SHOW: - event.Check(self.shell.autoComplete) - elif id == ID_AUTOCOMP_INCLUDE_MAGIC: - event.Check(self.shell.autoCompleteIncludeMagic) - elif id == ID_AUTOCOMP_INCLUDE_SINGLE: - event.Check(self.shell.autoCompleteIncludeSingle) - elif id == ID_AUTOCOMP_INCLUDE_DOUBLE: - event.Check(self.shell.autoCompleteIncludeDouble) - elif id == ID_CALLTIPS_SHOW: - event.Check(self.shell.autoCallTip) - class App(wxApp): + """PyCrust standalone application.""" + def OnInit(self): - parent = None - id = -1 - title = 'PyCrust' - self.frame = Frame(parent, id, title) - self.frame.Show(true) - self.SetTopWindow(self.frame) + locals = {'__app__': 'PyCrust Standalone Application'} + self.crustFrame = CrustFrame(locals=locals) + self.crustFrame.Show(true) + # Set focus to the shell editor. + self.crustFrame.crust.shell.SetFocus() + self.SetTopWindow(self.crustFrame) + # Add the application object to the sys module's namespace. + # This allows a shell user to do: + # >>> import sys + # >>> sys.application.whatever + import sys + sys.application = self return true def main(): - import sys application = App(0) - # Add the application object to the sys module's namespace. - # This allows a shell user to do: - # >>> import sys - # >>> sys.application.whatever - sys.application = application application.MainLoop() if __name__ == '__main__': main() + diff --git a/wxPython/wxPython/lib/PyCrust/PyFilling.py b/wxPython/wxPython/lib/PyCrust/PyFilling.py new file mode 100644 index 0000000000..bb2c72b79b --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/PyFilling.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python +"""PyFilling is a python namespace inspection application.""" + +__author__ = "Patrick K. O'Brien " +__cvsid__ = "$Id$" +__date__ = "August 21, 2001" +__version__ = "$Revision$"[11:-2] + +# We use this object to get more introspection when run standalone. +application = None + +import filling + +# These are imported just to have something interesting to inspect. +import crust +import interpreter +import introspect +import pseudo +import shell +import sys +from wxPython import wx + + +def main(): + """Create and run the application.""" + global application + application = filling.App(0) + root = application.fillingFrame.filling.fillingTree.root + application.fillingFrame.filling.fillingTree.Expand(root) + application.MainLoop() + + +if __name__ == '__main__': + main() + diff --git a/wxPython/wxPython/lib/PyCrust/PyShell.py b/wxPython/wxPython/lib/PyCrust/PyShell.py new file mode 100644 index 0000000000..0fea2d5d10 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/PyShell.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +"""PyShell is a python shell application.""" + +__author__ = "Patrick K. O'Brien " +__cvsid__ = "$Id$" +__date__ = "July 1, 2001" +__version__ = "$Revision$"[11:-2] + +from wxPython.wx import * +from shell import ShellFrame + + +class App(wxApp): + """PyShell standalone application.""" + + def OnInit(self): + locals = {'__app__': 'PyShell Standalone Application'} + self.shellFrame = ShellFrame(locals=locals) + self.shellFrame.Show(true) + self.SetTopWindow(self.shellFrame) + # Add the application object to the sys module's namespace. + # This allows a shell user to do: + # >>> import sys + # >>> sys.application.whatever + import sys + sys.application = self + return true + + +def main(): + application = App(0) + application.MainLoop() + +if __name__ == '__main__': + main() + diff --git a/wxPython/wxPython/lib/PyCrust/README.txt b/wxPython/wxPython/lib/PyCrust/README.txt index 73ad07bc2b..df1431c41e 100644 --- a/wxPython/wxPython/lib/PyCrust/README.txt +++ b/wxPython/wxPython/lib/PyCrust/README.txt @@ -4,40 +4,63 @@ Half-baked by Patrick K. O'Brien (pobrien@orbtech.com) What is PyCrust? ---------------- +PyCrust is an interactive Python environment written in Python. +PyCrust components can run standalone or be integrated into other +development environments and/or other Python applications. -PyCrust is is an interactive Python Shell written in Python. -PyCrust can be run standalone or integrated into other development -environments or other Python applications. +PyCrust comes with an interactive Python shell (PyShell), an +interactive namespace/object tree control (PyFilling) and an +integrated, split-window combination of the two (PyCrust). -Where can I get the latest files and join the mailing lists? ------------------------------------------------------------- +What is PyCrust good for? +------------------------- +Have you ever tried to bake a pie without one? Well, you +shouldn't build a Python program without a PyCrust either. + -Latest PyCrust releases: +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 -PyCrust home page: -http://pycrust.sourceforge.net/ -SourceForge summary page: +What else do I need to use PyCrust? +----------------------------------- +PyCrust requires Python 2.1 or later, and wxPython 2.3.1 or later. +PyCrust uses wxPython and the Scintilla wrapper (wxStyledTextCtrl). +Python is available at http://www.python.org/. +wxPython is available at http://www.wxpython.org/. + + +Where is the PyCrust project hosted? +------------------------------------ +At SourceForge, of course. The SourceForge summary page: http://sourceforge.net/projects/pycrust/ -PyCrust Mailing lists: + +Does PyCrust have a mailing list full of wonderful people? +---------------------------------------------------------- +As a matter of fact, we do. Join the PyCrust mailing lists at: http://sourceforge.net/mail/?group_id=31263 -What else do I need to use PyCrust? ------------------------------------ +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 -PyCrust requires Python 2.1 or later, and wxPython 2.3.1 or later. -PyCrust uses wxPython and the Scintilla wrapper class (wxStyledTextCtrl). -Python is available at http://www.python.org/. -wxPython is available at http://www.wxpython.org/. + +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? ------------------------------------------------- - $Date$ $Revision$ $Id$ diff --git a/wxPython/wxPython/lib/PyCrust/crust.py b/wxPython/wxPython/lib/PyCrust/crust.py new file mode 100644 index 0000000000..d45941a05a --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/crust.py @@ -0,0 +1,67 @@ +"""PyCrust Crust combines the shell and filling into one control.""" + +__author__ = "Patrick K. O'Brien " +__cvsid__ = "$Id$" +__date__ = "July 1, 2001" +__version__ = "$Revision$"[11:-2] + +from wxPython.wx import * +from shell import Shell +from filling import Filling +from version import VERSION + + +class Crust(wxSplitterWindow): + """PyCrust Crust based on wxSplitterWindow.""" + + name = 'PyCrust Crust' + revision = __version__ + + def __init__(self, parent, id=-1, pos=wxDefaultPosition, \ + size=wxDefaultSize, style=wxSP_3D, name='Crust Window', \ + ingredients=None, rootLabel=None, intro='', locals=None, \ + InterpClass=None, *args, **kwds): + """Create a PyCrust Crust instance.""" + wxSplitterWindow.__init__(self, parent, id, pos, size, style, name) + self.shell = Shell(parent=self, introText=intro, \ + locals=locals, InterpClass=InterpClass, \ + *args, **kwds) + self.filling = Filling(parent=self, \ + ingredients=self.shell.interp.locals, \ + rootLabel=rootLabel) + """Add 'filling' to the interpreter's locals.""" + self.shell.interp.locals['filling'] = self.filling + self.SplitHorizontally(self.shell, self.filling, 300) + # Set focus to the shell editor. Doesn't always work as intended. + self.shell.SetFocus() + + +class CrustFrame(wxFrame): + """Frame containing all the PyCrust components.""" + + name = 'PyCrust Frame' + revision = __version__ + + def __init__(self, parent=None, id=-1, title='PyCrust', \ + ingredients=None, rootLabel=None, locals=None, \ + InterpClass=None, *args, **kwds): + """Create a PyCrust CrustFrame instance.""" + wxFrame.__init__(self, parent, id, title) + intro = 'Welcome To PyCrust %s - The Flakiest Python Shell' % VERSION + self.CreateStatusBar() + self.SetStatusText(intro) + if wxPlatform == '__WXMSW__': + icon = wxIcon('PyCrust.ico', wxBITMAP_TYPE_ICO) + self.SetIcon(icon) + self.crust = Crust(parent=self, intro=intro, \ + ingredients=ingredients, \ + rootLabel=rootLabel, locals=locals, \ + InterpClass=InterpClass, *args, **kwds) + # Override the filling so that status messages go to the status bar. + self.crust.filling.fillingTree.setStatusText = self.SetStatusText + # Override the shell so that status messages go to the status bar. + self.crust.shell.setStatusText = self.SetStatusText + # Set focus to the shell editor. Doesn't always work as intended. + self.crust.shell.SetFocus() + + diff --git a/wxPython/wxPython/lib/PyCrust/filling.py b/wxPython/wxPython/lib/PyCrust/filling.py new file mode 100644 index 0000000000..ef3292e000 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/filling.py @@ -0,0 +1,292 @@ +"""PyCrust Filling is the gui tree control through which a user can navigate +the local namespace or any object.""" + +__author__ = "Patrick K. O'Brien " +__cvsid__ = "$Id$" +__date__ = "August 21, 2001" +__version__ = "$Revision$"[11:-2] + +from wxPython.wx import * +from wxPython.stc import * +from version import VERSION +import inspect +import introspect +import keyword +import sys +import types + + +class FillingTree(wxTreeCtrl): + """PyCrust FillingTree based on wxTreeCtrl.""" + + name = 'PyCrust Filling Tree' + revision = __version__ + + def __init__(self, parent, id=-1, pos=wxDefaultPosition, \ + size=wxDefaultSize, style=wxTR_HAS_BUTTONS, \ + ingredients=None, rootLabel=None): + """Create a PyCrust FillingTree instance.""" + wxTreeCtrl.__init__(self, parent, id, pos, size) + if not ingredients: + import __main__ + ingredients = __main__ + if not rootLabel: rootLabel = 'Ingredients' + rootdata = wxTreeItemData(ingredients) + self.root = self.AddRoot(rootLabel, -1, -1, rootdata) + self.SetItemHasChildren(self.root, self.hasChildren(self.root)) + EVT_TREE_ITEM_EXPANDING(self, self.GetId(), self.OnItemExpanding) + EVT_TREE_ITEM_COLLAPSED(self, self.GetId(), self.OnItemCollapsed) + EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged) + + def hasChildren(self, object): + """Return true if object has children.""" + if self.getChildren(object): + return true + else: + return false + + def getChildren(self, object): + """Return a dictionary with the attributes or contents of object.""" + dict = {} + objtype = type(object) + if objtype is types.DictType: + dict = object + elif objtype in (types.InstanceType, types.ModuleType): + for key in introspect.getAttributeNames(object): + # Believe it or not, some attributes can disappear, such as + # the exc_traceback attribute of the sys module. So this is + # nested in a try block. + try: + dict[key] = getattr(object, key) + except: + pass + return dict + + def OnItemExpanding(self, event): + selection = event.GetItem() + if self.IsExpanded(selection): + return + object = self.GetPyData(selection) + children = self.getChildren(object) + if not children: + return + list = children.keys() + list.sort() + for item in list: + itemtext = str(item) + # Show string dictionary items with single quotes, except for + # the first level of items, which represent the local namespace. + if type(object) is types.DictType \ + and type(item) is types.StringType \ + and selection != self.root: + itemtext = repr(item) + child = self.AppendItem(selection, itemtext, -1, -1, \ + wxTreeItemData(children[item])) + self.SetItemHasChildren(child, self.hasChildren(children[item])) + + def OnItemCollapsed(self, event): + """Remove all children from the item.""" + item = event.GetItem() + self.DeleteChildren(item) + + def OnSelChanged(self, event): + item = event.GetItem() + if item == self.root: + self.setText('') + return + object = self.GetPyData(item) + text = '' + text += self.getFullName(item) + text += '\n\nType: ' + str(type(object))[7:-2] + value = str(object) + if type(object) is types.StringType: + value = repr(value) + text += '\n\nValue: ' + value + if type(object) is types.InstanceType: + try: + text += '\n\nClass Definition:\n\n' + \ + inspect.getsource(object.__class__) + except: + try: + text += '\n\n"""' + inspect.getdoc(object).strip() + '"""' + except: + pass + else: + try: + text += '\n\nSource Code:\n\n' + \ + inspect.getsource(object) + except: + try: + text += '\n\n"""' + inspect.getdoc(object).strip() + '"""' + except: + pass + self.setText(text) + + def getFullName(self, item, partial=''): + """Return a syntactically proper name for item.""" + parent = self.GetItemParent(item) + parentobject = self.GetPyData(parent) + name = self.GetItemText(item) + # Apply dictionary syntax to dictionary items, except the root + # and first level children. + if item != self.root and parent != self.root \ + and type(parentobject) is types.DictType: + name = '[' + name + ']' + # Apply dot syntax to multipart names. + if partial: + if partial[0] == '[': + name += partial + else: + name += '.' + partial + # Repeat for everything but the root item and first level children. + if item != self.root and parent != self.root: + name = self.getFullName(parent, partial=name) + return name + + def setText(self, text): + """Display information about the current selection.""" + + # This method will most likely be replaced by the enclosing app + # to do something more interesting, like write to a text control. + print text + + def setStatusText(self, text): + """Display status information.""" + + # This method will most likely be replaced by the enclosing app + # to do something more interesting, like write to a status bar. + print text + + +if wxPlatform == '__WXMSW__': + faces = { 'times' : 'Times New Roman', + 'mono' : 'Courier New', + 'helv' : 'Lucida Console', + 'lucida' : 'Lucida Console', + 'other' : 'Comic Sans MS', + 'size' : 8, + 'lnsize' : 7, + 'backcol': '#FFFFFF', + } +else: # GTK + faces = { 'times' : 'Times', + 'mono' : 'Courier', + 'helv' : 'Helvetica', + 'other' : 'new century schoolbook', + 'size' : 12, + 'lnsize' : 10, + 'backcol': '#FFFFFF', + } + + +class FillingText(wxStyledTextCtrl): + """PyCrust FillingText based on wxStyledTextCtrl.""" + + name = 'PyCrust Filling Text' + revision = __version__ + + def __init__(self, parent, id=-1, pos=wxDefaultPosition, \ + size=wxDefaultSize, style=wxCLIP_CHILDREN): + """Create a PyCrust FillingText instance.""" + wxStyledTextCtrl.__init__(self, parent, id, pos, size, style) + # Configure various defaults and user preferences. + self.config() + + def config(self): + """Configure shell based on user preferences.""" + self.SetMarginWidth(1, 0) + + self.SetLexer(wxSTC_LEX_PYTHON) + self.SetKeyWords(0, ' '.join(keyword.kwlist)) + + self.setStyles(faces) + self.SetViewWhiteSpace(0) + self.SetTabWidth(4) + self.SetUseTabs(0) + + def setStyles(self, faces): + """Configure font size, typeface and color for lexer.""" + + # Default style + self.StyleSetSpec(wxSTC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d" % faces) + + self.StyleClearAll() + + # Built in styles + self.StyleSetSpec(wxSTC_STYLE_LINENUMBER, "back:#C0C0C0,face:%(mono)s,size:%(lnsize)d" % faces) + self.StyleSetSpec(wxSTC_STYLE_CONTROLCHAR, "face:%(mono)s" % faces) + self.StyleSetSpec(wxSTC_STYLE_BRACELIGHT, "fore:#0000FF,back:#FFFF88") + self.StyleSetSpec(wxSTC_STYLE_BRACEBAD, "fore:#FF0000,back:#FFFF88") + + # Python styles + self.StyleSetSpec(wxSTC_P_DEFAULT, "face:%(mono)s" % faces) + self.StyleSetSpec(wxSTC_P_COMMENTLINE, "fore:#007F00,face:%(mono)s" % faces) + self.StyleSetSpec(wxSTC_P_NUMBER, "") + self.StyleSetSpec(wxSTC_P_STRING, "fore:#7F007F,face:%(mono)s" % faces) + self.StyleSetSpec(wxSTC_P_CHARACTER, "fore:#7F007F,face:%(mono)s" % faces) + self.StyleSetSpec(wxSTC_P_WORD, "fore:#00007F,bold") + self.StyleSetSpec(wxSTC_P_TRIPLE, "fore:#7F0000") + self.StyleSetSpec(wxSTC_P_TRIPLEDOUBLE, "fore:#000033,back:#FFFFE8") + self.StyleSetSpec(wxSTC_P_CLASSNAME, "fore:#0000FF,bold") + self.StyleSetSpec(wxSTC_P_DEFNAME, "fore:#007F7F,bold") + self.StyleSetSpec(wxSTC_P_OPERATOR, "") + self.StyleSetSpec(wxSTC_P_IDENTIFIER, "") + self.StyleSetSpec(wxSTC_P_COMMENTBLOCK, "fore:#7F7F7F") + self.StyleSetSpec(wxSTC_P_STRINGEOL, "fore:#000000,face:%(mono)s,back:#E0C0E0,eolfilled" % faces) + + +class Filling(wxSplitterWindow): + """PyCrust Filling based on wxSplitterWindow.""" + + name = 'PyCrust Filling' + revision = __version__ + + def __init__(self, parent, id=-1, pos=wxDefaultPosition, \ + size=wxDefaultSize, style=wxSP_3D, name='Filling Window', \ + ingredients=None, rootLabel=None): + """Create a PyCrust Filling instance.""" + wxSplitterWindow.__init__(self, parent, id, pos, size, style, name) + self.fillingTree = FillingTree(parent=self, ingredients=ingredients, \ + rootLabel=rootLabel) + self.fillingText = FillingText(parent=self) + self.SplitVertically(self.fillingTree, self.fillingText, 200) + # Override the filling so that descriptions go to fillingText. + self.fillingTree.setText = self.fillingText.SetText + # Select the root item. + self.fillingTree.SelectItem(self.fillingTree.root) + + +class FillingFrame(wxFrame): + """Frame containing the PyCrust filling, or namespace tree component.""" + + name = 'PyCrust Filling Frame' + revision = __version__ + + def __init__(self, parent=None, id=-1, title='PyFilling', \ + pos=wxDefaultPosition, size=wxDefaultSize, \ + style=wxDEFAULT_FRAME_STYLE, ingredients=None, \ + rootLabel=None): + """Create a PyCrust FillingFrame instance.""" + wxFrame.__init__(self, parent, id, title, pos, size, style) + intro = 'Welcome To PyFilling - The Tastiest Namespace Inspector' + self.CreateStatusBar() + self.SetStatusText(intro) + if wxPlatform == '__WXMSW__': + icon = wxIcon('PyCrust.ico', wxBITMAP_TYPE_ICO) + self.SetIcon(icon) + self.filling = Filling(parent=self, ingredients=ingredients, \ + rootLabel=rootLabel) + # Override the filling so that status messages go to the status bar. + self.filling.fillingTree.setStatusText = self.SetStatusText + + +class App(wxApp): + """PyFilling standalone application.""" + + def OnInit(self): + self.fillingFrame = FillingFrame() + self.fillingFrame.Show(true) + self.SetTopWindow(self.fillingFrame) + return true + + diff --git a/wxPython/wxPython/lib/PyCrust/interpreter.py b/wxPython/wxPython/lib/PyCrust/interpreter.py index 5f12c01f34..48e9056464 100644 --- a/wxPython/wxPython/lib/PyCrust/interpreter.py +++ b/wxPython/wxPython/lib/PyCrust/interpreter.py @@ -1,5 +1,4 @@ -"""PyCrust Interpreter executes Python commands. -""" +"""PyCrust Interpreter executes Python commands.""" __author__ = "Patrick K. O'Brien " __cvsid__ = "$Id$" @@ -8,15 +7,16 @@ __version__ = "$Revision$"[11:-2] import os import sys - from code import InteractiveInterpreter import introspect class Interpreter(InteractiveInterpreter): """PyCrust Interpreter based on code.InteractiveInterpreter.""" + revision = __version__ - def __init__(self, locals=None, rawin=None, + + def __init__(self, locals=None, rawin=None, \ stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr): """Create an interactive interpreter object.""" InteractiveInterpreter.__init__(self, locals=locals) @@ -28,8 +28,8 @@ class Interpreter(InteractiveInterpreter): __builtin__.raw_input = rawin del __builtin__ copyright = 'Type "copyright", "credits" or "license" for more information.' - self.introText = 'Python %s on %s\n%s' % \ - (sys.version, sys.platform, copyright) + self.introText = 'Python %s on %s%s%s' % \ + (sys.version, sys.platform, os.linesep, copyright) try: sys.ps1 except AttributeError: @@ -81,3 +81,15 @@ class Interpreter(InteractiveInterpreter): The call tip information will be based on the locals namespace.""" return introspect.getCallTip(command, self.locals, *args, **kwds) + +class InterpreterAlaCarte(Interpreter): + """PyCrustAlaCarte Demo Interpreter.""" + + def __init__(self, locals, rawin, stdin, stdout, stderr, \ + ps1='main prompt', ps2='continuation prompt'): + """Create an interactive interpreter object.""" + Interpreter.__init__(self, locals=locals, rawin=rawin, \ + stdin=stdin, stdout=stdout, stderr=stderr) + sys.ps1 = ps1 + sys.ps2 = ps2 + diff --git a/wxPython/wxPython/lib/PyCrust/introspect.py b/wxPython/wxPython/lib/PyCrust/introspect.py index 8cf6ae8505..4f3abd1477 100644 --- a/wxPython/wxPython/lib/PyCrust/introspect.py +++ b/wxPython/wxPython/lib/PyCrust/introspect.py @@ -19,27 +19,28 @@ def getAutoCompleteList(command='', locals=None, includeMagic=1, \ root = getRoot(command, terminator='.') try: object = eval(root, locals) - attributes = getAttributeNames(object) - if includeMagic: - try: attributes += object._getAttributeNames() - except: pass - if not includeSingle: - attributes = filter(lambda item: item[0]!='_' or item[1]=='_', attributes) - if not includeDouble: - attributes = filter(lambda item: item[:2]!='__', attributes) + attributes = getAttributeNames(object, includeMagic, \ + includeSingle, includeDouble) return attributes except: return [] -def getAttributeNames(object): +def getAttributeNames(object, includeMagic=1, includeSingle=1, includeDouble=1): """Return list of unique attributes, including inherited, for an object.""" attributes = [] dict = {} - # Remove duplicates from the attribute list. + if includeMagic: + try: attributes += object._getAttributeNames() + except: pass + # Get all attribute names, removing duplicates from the attribute list. for item in getAllAttributeNames(object): dict[item] = None attributes += dict.keys() attributes.sort() + if not includeSingle: + attributes = filter(lambda item: item[0]!='_' or item[1]=='_', attributes) + if not includeDouble: + attributes = filter(lambda item: item[:2]!='__', attributes) return attributes def getAllAttributeNames(object): @@ -137,7 +138,9 @@ def getRoot(command, terminator=None): pieces = command.split(terminator) if len(pieces) > 1: command = terminator.join(pieces[:-1]) - if command in ("''", '""', '""""""', '[]', '()', '{}'): + if len(command) == 0: + root = '' + elif command in ("''", '""', '""""""', '[]', '()', '{}'): # Let empty type delimiter pairs go through. root = command else: diff --git a/wxPython/wxPython/lib/PyCrust/shell.py b/wxPython/wxPython/lib/PyCrust/shell.py index 0c71206bd2..e14e6c6d4e 100644 --- a/wxPython/wxPython/lib/PyCrust/shell.py +++ b/wxPython/wxPython/lib/PyCrust/shell.py @@ -1,7 +1,7 @@ -"""PyCrust Shell is the gui text control in which a user interacts and types -in commands to be sent to the interpreter. This particular shell is based on -wxPython's wxStyledTextCtrl. -""" +"""The PyCrust Shell is an interactive text control in which a user types in +commands to be sent to the interpreter. This particular shell is based on +wxPython's wxStyledTextCtrl. The latest files are always available at the +SourceForge project page at http://sourceforge.net/projects/pycrust/.""" __author__ = "Patrick K. O'Brien " __cvsid__ = "$Id$" @@ -10,13 +10,12 @@ __version__ = "$Revision$"[11:-2] from wxPython.wx import * from wxPython.stc import * - import keyword import os import sys - from version import VERSION + if wxPlatform == '__WXMSW__': faces = { 'times' : 'Times New Roman', 'mono' : 'Courier New', @@ -32,79 +31,85 @@ else: # GTK 'mono' : 'Courier', 'helv' : 'Helvetica', 'other' : 'new century schoolbook', - 'size' : 9, - 'lnsize' : 8, + 'size' : 12, + 'lnsize' : 10, 'backcol': '#FFFFFF', } class Shell(wxStyledTextCtrl): """PyCrust Shell based on wxStyledTextCtrl.""" + name = 'PyCrust Shell' revision = __version__ - def __init__(self, parent, id, introText='', locals=None, interp=None): - """Create a PyCrust Shell object.""" - wxStyledTextCtrl.__init__(self, parent, id, style=wxCLIP_CHILDREN) - self.introText = introText + + def __init__(self, parent, id=-1, pos=wxDefaultPosition, \ + size=wxDefaultSize, style=wxCLIP_CHILDREN, introText='', \ + locals=None, InterpClass=None, *args, **kwds): + """Create a PyCrust Shell instance.""" + wxStyledTextCtrl.__init__(self, parent, id, pos, size, style) + # Import a default interpreter class if one isn't provided. + if InterpClass == None: + from interpreter import Interpreter + else: + Interpreter = InterpClass + # Create default locals so we have something interesting. + shellLocals = {'__name__': 'PyShell', + '__doc__': 'PyShell, The PyCrust Python Shell.', + '__version__': VERSION, + } + # Add the dictionary that was passed in. + if locals: + shellLocals.update(locals) + from pseudo import PseudoFileIn, PseudoFileOut, PseudoFileErr + self.interp = Interpreter(locals=shellLocals, \ + rawin=self.readRaw, \ + stdin=PseudoFileIn(self.readIn), \ + stdout=PseudoFileOut(self.writeOut), \ + stderr=PseudoFileErr(self.writeErr), \ + *args, **kwds) # Keep track of the most recent prompt starting and ending positions. self.promptPos = [0, 0] # Keep track of multi-line commands. self.more = 0 + # Create the command history. Commands are added into the front of + # the list (ie. at index 0) as they are entered. self.historyPos is + # the current position in the history; it gets incremented as you + # retrieve the previous command, decremented as you retrieve the next, + # and reset when you hit Enter. self.historyPos == -1 means you're on + # the current command, not in the history. self.tempCommand is + # storage space for whatever was on the last line when you first hit + # "Retrieve-Previous", so that the final "Retrieve-Next" will restore + # whatever was originally there. self.lastCommandRecalled remembers + # the index of the last command to be recalled from the history, so + # you can repeat a group of commands by going up-up-up-enter to find + # the first one in the group then down-enter-down-enter to recall each + # subsequent command. Also useful for multiline commands, in lieu of + # a proper implementation of those. + self.history = [] + self.historyPos = -1 + self.tempCommand = '' + self.lastCommandRecalled = -1 # Assign handlers for keyboard events. EVT_KEY_DOWN(self, self.OnKeyDown) EVT_CHAR(self, self.OnChar) - # Create a default interpreter if one isn't provided. - if interp == None: - from interpreter import Interpreter - from pseudo import PseudoFileIn, PseudoFileOut, PseudoFileErr - self.stdin = PseudoFileIn(self.readIn) - self.stdout = PseudoFileOut(self.writeOut) - self.stderr = PseudoFileErr(self.writeErr) - # Override the default locals so we have something interesting. - self.locals = {'__name__': 'PyCrust', - '__doc__': 'PyCrust, The Python Shell.', - '__version__': VERSION, - } - # Add the dictionary that was passed in. - if locals: - self.locals.update(locals) - self.interp = Interpreter(locals=self.locals, - rawin=self.readRaw, - stdin=self.stdin, - stdout=self.stdout, - stderr=self.stderr) - else: - self.interp = interp - # Configure various defaults and user preferences. self.config() - - try: - self.showIntro(self.introText) - except: - pass - - try: - self.setBuiltinKeywords() - except: - pass - - try: - self.setLocalShell() - except: - pass - + # Display the introductory banner information. + try: self.showIntro(introText) + except: pass + # Assign some pseudo keywords to the interpreter's namespace. + try: self.setBuiltinKeywords() + except: pass + # Add 'shell' to the interpreter's local namespace. + try: self.setLocalShell() + except: pass # Do this last so the user has complete control over their # environment. They can override anything they want. - try: - self.execStartupScript(self.interp.startupScript) - except: - pass + try: self.execStartupScript(self.interp.startupScript) + except: pass def destroy(self): - del self.stdin - del self.stdout - del self.stderr del self.interp def config(self): @@ -133,7 +138,7 @@ class Shell(wxStyledTextCtrl): def showIntro(self, text=''): """Display introductory text in the shell.""" if text: - if text[-1] != '\n': text += '\n' + if not text.endswith(os.linesep): text += os.linesep self.write(text) try: self.write(self.interp.introText) @@ -148,10 +153,15 @@ class Shell(wxStyledTextCtrl): 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__ from pseudo import PseudoKeyword __builtin__.close = __builtin__.exit = __builtin__.quit = \ - PseudoKeyword(self.quit) + 'Click on the close button to leave the application.' def quit(self): """Quit the application.""" @@ -211,14 +221,86 @@ class Shell(wxStyledTextCtrl): """Key down event handler. The main goal here is to not allow modifications to previous - lines of text. - """ + lines of text.""" key = event.KeyCode() currpos = self.GetCurrentPos() stoppos = self.promptPos[1] # If the auto-complete window is up let it do its thing. if self.AutoCompActive(): event.Skip() + # Control+UpArrow steps up through the history. + elif key == WXK_UP and event.ControlDown() \ + and self.historyPos < len(self.history) - 1: + # Move to the end of the buffer. + endpos = self.GetTextLength() + self.SetCurrentPos(endpos) + # The first Control+Up stores the current command; + # Control+Down brings it back. + if self.historyPos == -1: + self.tempCommand = self.getCommand() + # Now replace the current line with the next one from the history. + self.historyPos = self.historyPos + 1 + self.SetSelection(stoppos, endpos) + self.ReplaceSelection(self.history[self.historyPos]) + # Control+DownArrow steps down through the history. + elif key == WXK_DOWN and event.ControlDown(): + # Move to the end of the buffer. + endpos = self.GetTextLength() + self.SetCurrentPos(endpos) + # Are we at the bottom end of the history? + if self.historyPos == -1: + # Do we have a lastCommandRecalled stored? + if self.lastCommandRecalled >= 0: + # Replace the current line with the command after the + # last-recalled command (you'd think there should be a +1 + # here but there isn't because the history was shuffled up + # by 1 after the previous command was recalled). + self.SetSelection(stoppos, endpos) + self.ReplaceSelection(self.history[self.lastCommandRecalled]) + # We've now warped into middle of the history. + self.historyPos = self.lastCommandRecalled + self.lastCommandRecalled = -1 + else: + # Fetch either the previous line from the history, or the saved + # command if we're back at the start. + self.historyPos = self.historyPos - 1 + if self.historyPos == -1: + newText = self.tempCommand + else: + newText = self.history[self.historyPos] + # Replace the current line with the new text. + self.SetSelection(stoppos, endpos) + self.ReplaceSelection(newText) + # F8 on the last line does a search up the history for the text in + # front of the cursor. + elif key == WXK_F8 and self.GetCurrentLine() == self.GetLineCount()-1: + tempCommand = self.getCommand() + # The first F8 saves the current command, just like Control+Up. + if self.historyPos == -1: + self.tempCommand = tempCommand + # The text up to the cursor is what we search for. + searchText = tempCommand + numCharsAfterCursor = self.GetTextLength() - self.GetCurrentPos() + if numCharsAfterCursor > 0: + searchText = searchText[:-numCharsAfterCursor] + # Search upwards from the current history position and loop back + # to the beginning if we don't find anything. + for i in range(self.historyPos+1, len(self.history)) + \ + range(self.historyPos): + command = self.history[i] + if command[:len(searchText)] == searchText: + # Replace the current line with the one we've found. + endpos = self.GetTextLength() + self.SetSelection(stoppos, endpos) + self.ReplaceSelection(command) + # Put the cursor back at the end of the search text. + pos = self.GetTextLength() - len(command) + len(searchText) + self.SetCurrentPos(pos) + self.SetAnchor(pos) + # We've now warped into middle of the history. + self.historyPos = i + self.lastCommandRecalled = -1 + break # Return is used to submit a command to the interpreter. elif key == WXK_RETURN: if self.CallTipActive: self.CallTipCancel() @@ -252,8 +334,7 @@ class Shell(wxStyledTextCtrl): """Keypress event handler. The main goal here is to not allow modifications to previous - lines of text. - """ + lines of text.""" key = event.KeyCode() currpos = self.GetCurrentPos() stoppos = self.promptPos[1] @@ -296,14 +377,24 @@ class Shell(wxStyledTextCtrl): # Grab information about the current line. thepos = self.GetCurrentPos() theline = self.GetCurrentLine() - thetext = self.GetCurLine()[0] - command = self.getCommand(thetext) + command = self.getCommand() # Go to the very bottom of the text. endpos = self.GetTextLength() self.SetCurrentPos(endpos) endline = self.GetCurrentLine() # If they hit RETURN on the last line, execute the command. if theline == endline: + # Store the last-recalled command; see the main comment for + # self.lastCommandRecalled. + if command != '': + self.lastCommandRecalled = self.historyPos + # Reset the history position. + self.historyPos = -1 + # Insert this command into the history, unless it's a blank line + # or the same as the last command. + if command != '' \ + and (len(self.history) == 0 or command != self.history[0]): + self.history.insert(0, command) self.push(command) # Otherwise, replace the last line with the new line. else: @@ -319,15 +410,19 @@ class Shell(wxStyledTextCtrl): self.SetCurrentPos(thepos) self.SetAnchor(thepos) - def getCommand(self, text): + def getCommand(self, text=None): """Extract a command from text which may include a shell prompt. - The command may not necessarily be valid Python syntax. - """ - + The command may not necessarily be valid Python syntax.""" + if not text: + text = self.GetCurLine()[0] +## This is a hack due to a bug in the wxPython 2.3.2 beta. The following +## two lines of code should go away once the bug has been fixed and the +## line above should be restored. +## self.write(' ') +## text = self.GetCurLine()[0][:-1] # XXX Need to extract real prompts here. Need to keep track of the - # prompt every time a command is issued. Do this in the interpreter - # with a line number, prompt, command dictionary. For the history, perhaps. + # prompt every time a command is issued. ps1 = str(sys.ps1) ps1size = len(ps1) ps2 = str(sys.ps2) @@ -344,7 +439,7 @@ class Shell(wxStyledTextCtrl): def push(self, command): """Send command to the interpreter for execution.""" - self.write('\n') + self.write(os.linesep) self.more = self.interp.push(command) self.prompt() # Keep the undo feature from undoing previous responses. The only @@ -353,22 +448,30 @@ class Shell(wxStyledTextCtrl): self.EmptyUndoBuffer() def write(self, text): - """Display text in the shell.""" + """Display text in the shell. + + Replace line endings with OS-specific endings.""" + lines = text.split('\r\n') + for l in range(len(lines)): + chunks = lines[l].split('\r') + for c in range(len(chunks)): + chunks[c] = os.linesep.join(chunks[c].split('\n')) + lines[l] = os.linesep.join(chunks) + text = os.linesep.join(lines) self.AddText(text) self.EnsureCaretVisible() #self.ScrollToColumn(0) - + def prompt(self): """Display appropriate prompt for the context, either ps1 or ps2. - If this is a continuation line, autoindent as necessary. - """ + If this is a continuation line, autoindent as necessary.""" if self.more: prompt = str(sys.ps2) else: prompt = str(sys.ps1) pos = self.GetCurLine()[1] - if pos > 0: self.write('\n') + if pos > 0: self.write(os.linesep) self.promptPos[0] = self.GetCurrentPos() self.write(prompt) self.promptPos[1] = self.GetCurrentPos() @@ -377,7 +480,7 @@ class Shell(wxStyledTextCtrl): self.write('\t') # Temporary hack indentation. self.EnsureCaretVisible() self.ScrollToColumn(0) - + def readIn(self): """Replacement for stdin.""" prompt = 'Please enter your response:' @@ -386,7 +489,7 @@ class Shell(wxStyledTextCtrl): try: if dialog.ShowModal() == wxID_OK: text = dialog.GetValue() - self.write(text + '\n') + self.write(text + os.linesep) return text finally: dialog.Destroy() @@ -476,3 +579,205 @@ class Shell(wxStyledTextCtrl): """Return true if text is selected and can be copied.""" return self.GetSelectionStart() != self.GetSelectionEnd() + +wxID_SELECTALL = NewId() # This *should* be defined by wxPython. +ID_AUTOCOMP = NewId() +ID_AUTOCOMP_SHOW = NewId() +ID_AUTOCOMP_INCLUDE_MAGIC = NewId() +ID_AUTOCOMP_INCLUDE_SINGLE = NewId() +ID_AUTOCOMP_INCLUDE_DOUBLE = NewId() +ID_CALLTIPS = NewId() +ID_CALLTIPS_SHOW = NewId() + + +class ShellFrame(wxFrame): + """Frame containing the PyCrust shell component.""" + + name = 'PyCrust Shell Frame' + revision = __version__ + + def __init__(self, parent=None, id=-1, title='PyShell', \ + pos=wxDefaultPosition, size=wxDefaultSize, \ + style=wxDEFAULT_FRAME_STYLE, locals=None, \ + InterpClass=None, *args, **kwds): + """Create a PyCrust ShellFrame instance.""" + wxFrame.__init__(self, parent, id, title, pos, size, style) + intro = 'Welcome To PyCrust %s - The Flakiest Python Shell' % VERSION + self.CreateStatusBar() + self.SetStatusText(intro) + if wxPlatform == '__WXMSW__': + icon = wxIcon('PyCrust.ico', wxBITMAP_TYPE_ICO) + self.SetIcon(icon) + self.createMenus() + self.shell = Shell(parent=self, id=-1, introText=intro, \ + locals=locals, InterpClass=InterpClass, \ + *args, **kwds) + # Override the shell so that status messages go to the status bar. + self.shell.setStatusText = self.SetStatusText + + def createMenus(self): + m = self.fileMenu = wxMenu() + m.AppendSeparator() + m.Append(wxID_EXIT, 'E&xit', 'Exit PyCrust') + + m = self.editMenu = wxMenu() + m.Append(wxID_UNDO, '&Undo \tCtrl+Z', 'Undo the last action') + m.Append(wxID_REDO, '&Redo \tCtrl+Y', 'Redo the last undone action') + m.AppendSeparator() + m.Append(wxID_CUT, 'Cu&t \tCtrl+X', 'Cut the selection') + m.Append(wxID_COPY, '&Copy \tCtrl+C', 'Copy the selection') + m.Append(wxID_PASTE, '&Paste \tCtrl+V', 'Paste') + m.AppendSeparator() + m.Append(wxID_CLEAR, 'Cle&ar \tDel', 'Delete the selection') + m.Append(wxID_SELECTALL, 'Select A&ll \tCtrl+A', 'Select all text') + + m = self.autocompMenu = wxMenu() + m.Append(ID_AUTOCOMP_SHOW, 'Show Auto Completion', \ + 'Show auto completion during dot syntax', \ + checkable=1) + m.Append(ID_AUTOCOMP_INCLUDE_MAGIC, 'Include Magic Attributes', \ + 'Include attributes visible to __getattr__ and __setattr__', \ + checkable=1) + m.Append(ID_AUTOCOMP_INCLUDE_SINGLE, 'Include Single Underscores', \ + 'Include attibutes prefixed by a single underscore', \ + checkable=1) + m.Append(ID_AUTOCOMP_INCLUDE_DOUBLE, 'Include Double Underscores', \ + 'Include attibutes prefixed by a double underscore', \ + checkable=1) + + m = self.calltipsMenu = wxMenu() + m.Append(ID_CALLTIPS_SHOW, 'Show Call Tips', \ + 'Show call tips with argument specifications', checkable=1) + + m = self.optionsMenu = wxMenu() + m.AppendMenu(ID_AUTOCOMP, '&Auto Completion', self.autocompMenu, \ + 'Auto Completion Options') + m.AppendMenu(ID_CALLTIPS, '&Call Tips', self.calltipsMenu, \ + 'Call Tip Options') + + m = self.helpMenu = wxMenu() + m.AppendSeparator() + m.Append(wxID_ABOUT, '&About...', 'About PyCrust') + + b = self.menuBar = wxMenuBar() + b.Append(self.fileMenu, '&File') + b.Append(self.editMenu, '&Edit') + b.Append(self.optionsMenu, '&Options') + b.Append(self.helpMenu, '&Help') + self.SetMenuBar(b) + + EVT_MENU(self, wxID_EXIT, self.OnExit) + EVT_MENU(self, wxID_UNDO, self.OnUndo) + EVT_MENU(self, wxID_REDO, self.OnRedo) + EVT_MENU(self, wxID_CUT, self.OnCut) + EVT_MENU(self, wxID_COPY, self.OnCopy) + EVT_MENU(self, wxID_PASTE, self.OnPaste) + EVT_MENU(self, wxID_CLEAR, self.OnClear) + EVT_MENU(self, wxID_SELECTALL, self.OnSelectAll) + EVT_MENU(self, wxID_ABOUT, self.OnAbout) + EVT_MENU(self, ID_AUTOCOMP_SHOW, \ + self.OnAutoCompleteShow) + EVT_MENU(self, ID_AUTOCOMP_INCLUDE_MAGIC, \ + self.OnAutoCompleteIncludeMagic) + EVT_MENU(self, ID_AUTOCOMP_INCLUDE_SINGLE, \ + self.OnAutoCompleteIncludeSingle) + EVT_MENU(self, ID_AUTOCOMP_INCLUDE_DOUBLE, \ + self.OnAutoCompleteIncludeDouble) + EVT_MENU(self, ID_CALLTIPS_SHOW, \ + self.OnCallTipsShow) + + EVT_UPDATE_UI(self, wxID_UNDO, self.OnUpdateMenu) + EVT_UPDATE_UI(self, wxID_REDO, self.OnUpdateMenu) + EVT_UPDATE_UI(self, wxID_CUT, self.OnUpdateMenu) + EVT_UPDATE_UI(self, wxID_COPY, self.OnUpdateMenu) + EVT_UPDATE_UI(self, wxID_PASTE, self.OnUpdateMenu) + EVT_UPDATE_UI(self, wxID_CLEAR, self.OnUpdateMenu) + EVT_UPDATE_UI(self, ID_AUTOCOMP_SHOW, self.OnUpdateMenu) + EVT_UPDATE_UI(self, ID_AUTOCOMP_INCLUDE_MAGIC, self.OnUpdateMenu) + EVT_UPDATE_UI(self, ID_AUTOCOMP_INCLUDE_SINGLE, self.OnUpdateMenu) + EVT_UPDATE_UI(self, ID_AUTOCOMP_INCLUDE_DOUBLE, self.OnUpdateMenu) + EVT_UPDATE_UI(self, ID_CALLTIPS_SHOW, self.OnUpdateMenu) + + def OnExit(self, event): + self.Close(true) + + def OnUndo(self, event): + self.shell.Undo() + + def OnRedo(self, event): + self.shell.Redo() + + def OnCut(self, event): + self.shell.Cut() + + def OnCopy(self, event): + self.shell.Copy() + + def OnPaste(self, event): + self.shell.Paste() + + def OnClear(self, event): + self.shell.Clear() + + def OnSelectAll(self, event): + self.shell.SelectAll() + + def OnAbout(self, event): + """Display an About PyCrust window.""" + import sys + title = 'About PyCrust' + text = 'PyCrust %s\n\n' % VERSION + \ + 'Yet another Python shell, only flakier.\n\n' + \ + 'Half-baked by Patrick K. O\'Brien,\n' + \ + 'the other half is still in the oven.\n\n' + \ + 'Shell Revision: %s\n' % self.shell.revision + \ + 'Interpreter Revision: %s\n\n' % self.shell.interp.revision + \ + 'Python Version: %s\n' % sys.version.split()[0] + \ + 'wxPython Version: %s\n' % wx.__version__ + \ + 'Platform: %s\n' % sys.platform + dialog = wxMessageDialog(self, text, title, wxOK | wxICON_INFORMATION) + dialog.ShowModal() + dialog.Destroy() + + def OnAutoCompleteShow(self, event): + self.shell.autoComplete = event.IsChecked() + + def OnAutoCompleteIncludeMagic(self, event): + self.shell.autoCompleteIncludeMagic = event.IsChecked() + + def OnAutoCompleteIncludeSingle(self, event): + self.shell.autoCompleteIncludeSingle = event.IsChecked() + + def OnAutoCompleteIncludeDouble(self, event): + self.shell.autoCompleteIncludeDouble = event.IsChecked() + + def OnCallTipsShow(self, event): + self.shell.autoCallTip = event.IsChecked() + + def OnUpdateMenu(self, event): + """Update menu items based on current status.""" + id = event.GetId() + if id == wxID_UNDO: + event.Enable(self.shell.CanUndo()) + elif id == wxID_REDO: + event.Enable(self.shell.CanRedo()) + elif id == wxID_CUT: + event.Enable(self.shell.CanCut()) + elif id == wxID_COPY: + event.Enable(self.shell.CanCopy()) + elif id == wxID_PASTE: + event.Enable(self.shell.CanPaste()) + elif id == wxID_CLEAR: + event.Enable(self.shell.CanCut()) + elif id == ID_AUTOCOMP_SHOW: + event.Check(self.shell.autoComplete) + elif id == ID_AUTOCOMP_INCLUDE_MAGIC: + event.Check(self.shell.autoCompleteIncludeMagic) + elif id == ID_AUTOCOMP_INCLUDE_SINGLE: + event.Check(self.shell.autoCompleteIncludeSingle) + elif id == ID_AUTOCOMP_INCLUDE_DOUBLE: + event.Check(self.shell.autoCompleteIncludeDouble) + elif id == ID_CALLTIPS_SHOW: + event.Check(self.shell.autoCallTip) + + diff --git a/wxPython/wxPython/lib/PyCrust/version.py b/wxPython/wxPython/lib/PyCrust/version.py index 0c48e4021d..5fc855db6d 100644 --- a/wxPython/wxPython/lib/PyCrust/version.py +++ b/wxPython/wxPython/lib/PyCrust/version.py @@ -1,5 +1,5 @@ """Provides an object representing the current "version" or "release" of -PyCrust as a whole. Individual classes, such as the shell, editor and +PyCrust as a whole. Individual classes, such as the shell, filling and interpreter, each have a revision property based on the CVS Revision.""" __author__ = "Patrick K. O'Brien " @@ -7,4 +7,4 @@ __cvsid__ = "$Id$" __date__ = "July 1, 2001" __version__ = "$Revision$"[11:-2] -VERSION = '0.5.2' +VERSION = '0.6' -- 2.45.2