added experimental microthread support for use with stackless python -- bw compatible (jvr)
diff --git a/Mac/Tools/IDE/PyEdit.py b/Mac/Tools/IDE/PyEdit.py
index 7983705..8a70cdb 100644
--- a/Mac/Tools/IDE/PyEdit.py
+++ b/Mac/Tools/IDE/PyEdit.py
@@ -16,10 +16,20 @@
import marshal
import regex
+try:
+ # experimental microthread support
+ import uthread2
+except ImportError:
+ uthread2 = None
+
_scriptuntitledcounter = 1
_wordchars = string.letters + string.digits + "_"
+runButtonLabels = ["Run all", "Stop!"]
+runSelButtonLabels = ["Run selection", "Pause!", "Resume"]
+
+
class Editor(W.Window):
def __init__(self, path = "", title = ""):
@@ -54,7 +64,8 @@
else:
sourceOS = 'UNIX'
searchString = '\n'
- change = EasyDialogs.AskYesNoCancel('³%s² contains %s-style line feeds. Change them to MacOS carriage returns?' % (self.title, sourceOS), 1)
+ change = EasyDialogs.AskYesNoCancel('³%s² contains %s-style line feeds. '
+ 'Change them to MacOS carriage returns?' % (self.title, sourceOS), 1)
# bug: Cancel is treated as No
if change > 0:
text = string.replace(text, searchString, '\r')
@@ -98,6 +109,8 @@
self.run_as_main = self.settings["run_as_main"]
else:
self.run_as_main = 0
+ self._threadstate = (0, 0)
+ self._thread = None
def readwindowsettings(self):
try:
@@ -178,8 +191,8 @@
self.bevelbox = W.BevelBox((0, 0, 0, topbarheight))
self.hline = W.HorizontalLine((0, topbarheight, 0, 0))
self.infotext = W.TextBox((175, 6, -4, 14), backgroundcolor = (0xe000, 0xe000, 0xe000))
- self.runbutton = W.Button((5, 4, 80, 16), "Run all", self.run)
- self.runselbutton = W.Button((90, 4, 80, 16), "Run selection", self.runselection)
+ self.runbutton = W.Button((5, 4, 80, 16), runButtonLabels[0], self.run)
+ self.runselbutton = W.Button((90, 4, 80, 16), runSelButtonLabels[0], self.runselection)
# bind some keys
editor.bind("cmdr", self.runbutton.push)
@@ -460,7 +473,14 @@
self.runselbutton.push()
def run(self):
- self._run()
+ if self._threadstate == (0, 0):
+ self._run()
+ else:
+ uthread2.globalLock()
+ self._thread.raiseException(KeyboardInterrupt)
+ if self._thread.isPaused():
+ self._thread.start()
+ uthread2.globalUnlock()
def _run(self):
pytext = self.editgroup.editor.get()
@@ -468,7 +488,14 @@
self.execstring(pytext, globals, globals, file, modname)
def runselection(self):
- self._runselection()
+ if self._threadstate == (0, 0):
+ self._runselection()
+ elif self._threadstate == (1, 1):
+ self._thread.pause()
+ self.setthreadstate((1, 2))
+ elif self._threadstate == (1, 2):
+ self._thread.start()
+ self.setthreadstate((1, 1))
def _runselection(self):
globals, file, modname = self.getenvironment()
@@ -517,6 +544,19 @@
pytext = selfirstline * '\r' + pytext
self.execstring(pytext, globals, locals, file, modname)
+ def setthreadstate(self, state):
+ oldstate = self._threadstate
+ if oldstate[0] <> state[0]:
+ self.runbutton.settitle(runButtonLabels[state[0]])
+ if oldstate[1] <> state[1]:
+ self.runselbutton.settitle(runSelButtonLabels[state[1]])
+ self._threadstate = state
+
+ def _exec_threadwrapper(self, *args, **kwargs):
+ apply(execstring, args, kwargs)
+ self.setthreadstate((0, 0))
+ self._thread = None
+
def execstring(self, pytext, globals, locals, file, modname):
tracebackwindow.hide()
# update windows
@@ -531,8 +571,15 @@
else:
cwdindex = None
try:
- execstring(pytext, globals, locals, file, self.debugging,
- modname, self.profiling)
+ if uthread2 and uthread2.currentThread() is not None:
+ self._thread = uthread2.Thread(file,
+ self._exec_threadwrapper, pytext, globals, locals, file, self.debugging,
+ modname, self.profiling)
+ self.setthreadstate((1, 1))
+ self._thread.start()
+ else:
+ execstring(pytext, globals, locals, file, self.debugging,
+ modname, self.profiling)
finally:
if self.path:
os.chdir(savedir)
@@ -561,6 +608,7 @@
self.globals = {}
else:
globals = self.globals
+ modname = subname
else:
file = '<%s>' % self.title
globals = self.globals
@@ -1034,8 +1082,13 @@
return
try:
if debugging:
- PyDebugger.startfromhere()
- else:
+ if uthread2:
+ uthread2.globalLock()
+ PyDebugger.startfromhere()
+ uthread2.globalUnlock()
+ else:
+ PyDebugger.startfromhere()
+ elif not uthread2:
MacOS.EnableAppswitch(0)
try:
if profiling:
@@ -1052,18 +1105,23 @@
else:
exec code in globals, locals
finally:
- MacOS.EnableAppswitch(-1)
+ if not uthread2:
+ MacOS.EnableAppswitch(-1)
except W.AlertError, detail:
raise W.AlertError, detail
except (KeyboardInterrupt, BdbQuit):
pass
except:
+ if uthread2:
+ uthread2.globalLock()
if debugging:
sys.settrace(None)
PyDebugger.postmortem(sys.exc_type, sys.exc_value, sys.exc_traceback)
return
else:
tracebackwindow.traceback(1, filename)
+ if not uthread2:
+ uthread2.globalUnlock()
if debugging:
sys.settrace(None)
PyDebugger.stop()
diff --git a/Mac/Tools/IDE/PythonIDEMain.py b/Mac/Tools/IDE/PythonIDEMain.py
index a340eef..6e1ee21 100644
--- a/Mac/Tools/IDE/PythonIDEMain.py
+++ b/Mac/Tools/IDE/PythonIDEMain.py
@@ -1,9 +1,8 @@
-# copyright 1997-1998 Just van Rossum, Letterror. just@letterror.com
+# copyright 1997-2000 Just van Rossum, Letterror. just@letterror.com
import Splash
import FrameWork
-import Win
import Wapplication
import W
import os
@@ -33,7 +32,14 @@
import sys
for path in sys.argv[1:]:
self.opendoc(path)
- self.mainloop()
+ try:
+ import uthread2
+ except ImportError:
+ self.mainloop()
+ else:
+ main = uthread2.Thread("mainloop", self.mainloop)
+ main.start()
+ uthread2.run()
def makeusermenus(self):
m = Wapplication.Menu(self.menubar, "File")