def raw_input(self, prompt='Input:'): if not isinstance(prompt, str): prompt = str(prompt) self.input_event = ManualResetEvent(False) self.setup_input_box(prompt) self.input_event.WaitOne() self.remove_input_box() return self._raw_input_text
def __init__(self, printer, context, root): self._input_data = [] self.original_context = context self.printer = printer self.prompt = root.prompt self.root = root self.done_first_run = False self._sync = ManualResetEvent(False) self.ff3 = False self.FontSize = 15 self.Margin = Thickness(0) self.FontFamily = FontFamily( "Consolas, Monaco, Lucida Console, Global Monospace") self.AcceptsReturn = True self.BorderThickness = Thickness(0) self.VerticalScrollBarVisibility = ScrollBarVisibility.Auto self.MinWidth = 300 def reset(): "Clear the console, its history and the execution context." self._reset_needed = True return 'resetting' def input(prompt='Input:'): 'input([prompt]) -> value\n\nEquivalent to eval(raw_input(prompt)).' return eval(self.context['raw_input'](prompt), self.context, self.context) self.original_context['reset'] = reset self.original_context['gohome'] = gohome self.original_context['exit'] = 'There is no escape...' self.original_context['raw_input'] = self.raw_input self.original_context['input'] = input # for debugging only! self.original_context['root'] = root self.context = {} self.history = None self._reset_needed = False self._thread = None self._thread_reset = None self._raw_input_text = '' self._temp_context = None self.engine = Python.CreateEngine() self.scope = self.engine.CreateScope() self._original_caret = None if hasattr(self, 'CaretBrush'): self._original_caret = self.CaretBrush self._disabled = SolidColorBrush(Colors.White) self.KeyDown += self.handle_key self.TextChanged += self.text_changed
def execute(self, contents): self.printer.print_lines(contents) self.Text = '' self.history.append(contents) self._sync.Reset() started = ManualResetEvent(False) if self._temp_context is not None: self.context.update(self._temp_context) def _execute(): context = self.context started.Set() try: code = compile(contents + '\n', '<stdin>', 'single', PyCF_DONT_IMPLY_DEDENT) exec code in context except: if reset_event.WaitOne(1): # don't print exception messages if thread has been terminated return exc_type, value, tb = sys.exc_info() if value is None: # String exceptions # workaround for IronPython bug exc_type = Exception value = Exception('StringException') tblist = traceback.extract_tb(tb) message = traceback.format_list(tblist) del message[:1] if message: # we don't print the 'Traceback...' part for SyntaxError message.insert(0, "Traceback (most recent call last):\n") message.extend(traceback.format_exception_only( exc_type, value)) self.printer.print_new(''.join(message)) # access through closure not on self as we may be an orphaned # thread - with a new reset_event on self result = reset_event.WaitOne(0) if not reset_event.WaitOne(0): self.completed() self._sync.Set() self._thread_reset = reset_event = ManualResetEvent(False) self._thread = Thread(ThreadStart(_execute)) self._thread.IsBackground = True self._thread.Name = "executing" self._thread.Start() self.prompt.Visibility = Visibility.Collapsed if hasattr(self, 'CaretBrush'): self.CaretBrush = self._disabled started.WaitOne()
def do_synchronously(self, function, wait_sync=False): event = ManualResetEvent(False) def do_operation(): function() event.Set() self.Dispatcher.BeginInvoke(do_operation) event.WaitOne() if wait_sync: # wait for execution to complete self._sync.WaitOne()
from System import Uri, AsyncCallback from System.IO import StreamReader from System.Net import WebRequest from System.Windows.Browser import HtmlPage import time import unittest from System.Windows.Threading import Dispatcher from System.Threading import ManualResetEvent, Thread, ThreadStart are = ManualResetEvent(False) TEST_NET_CONTENT = '[[[CONTENT OF TEST_NET.TXT]]]' def puts(*a): print(a) def web_request(obj, uri_string, func): req = WebRequest.Create(Uri(uri_string)) req.BeginGetResponse(AsyncCallback(web_complete(obj, func)), req) def web_complete(obj, func): def __web_complete(a): req = a.AsyncState res = req.EndGetResponse(a) content = StreamReader(res.GetResponseStream()).ReadToEnd() func(content) are.Set()
class ConsoleTextBox(TextBox): def __new__(cls, printer, context, root): return TextBox.__new__(cls) def __init__(self, printer, context, root): self._input_data = [] self.original_context = context self.printer = printer self.prompt = root.prompt self.root = root self.done_first_run = False self._sync = ManualResetEvent(False) self.ff3 = False self.FontSize = 15 self.Margin = Thickness(0) self.FontFamily = FontFamily( "Consolas, Monaco, Lucida Console, Global Monospace") self.AcceptsReturn = True self.BorderThickness = Thickness(0) self.VerticalScrollBarVisibility = ScrollBarVisibility.Auto self.MinWidth = 300 def reset(): "Clear the console, its history and the execution context." self._reset_needed = True return 'resetting' def input(prompt='Input:'): 'input([prompt]) -> value\n\nEquivalent to eval(raw_input(prompt)).' return eval(self.context['raw_input'](prompt), self.context, self.context) self.original_context['reset'] = reset self.original_context['gohome'] = gohome self.original_context['exit'] = 'There is no escape...' self.original_context['raw_input'] = self.raw_input self.original_context['input'] = input # for debugging only! self.original_context['root'] = root self.context = {} self.history = None self._reset_needed = False self._thread = None self._thread_reset = None self._raw_input_text = '' self._temp_context = None self.engine = Python.CreateEngine() self.scope = self.engine.CreateScope() self._original_caret = None if hasattr(self, 'CaretBrush'): self._original_caret = self.CaretBrush self._disabled = SolidColorBrush(Colors.White) self.KeyDown += self.handle_key self.TextChanged += self.text_changed def reset(self): sys.ps1 = ps1 sys.ps2 = ps2 self.printer.clear() self._reset_needed = False self.context.clear() self.context = self.original_context.copy() self.history = ConsoleHistory() self.printer.print_new(banner) if not self.done_first_run: self.done_first_run = True self.browser_sniff() def browser_sniff(self): useragent = HtmlPage.BrowserInformation.UserAgent match = re.search(FF3_RE, useragent) if match is not None: browser = match.groups()[0] self.printer.print_new(FF3_MESSAGE % browser) self.ff3 = True def OnKeyDown(self, event): # needed so that we get KeyDown # for del and backspace events etc pass def text_changed(self, sender, event): # replace any tabs that are pasted in if '\t' in self.Text: self.Text = self.Text.replace('\t', ' ') self.SelectionStart = len(self.Text) def write(self, data): self.printer.write(data) def is_complete(self, text, pos): if len(text.splitlines()) > 1 and pos < len(text.rstrip()): return False if text.endswith('\\'): return False source = self.engine.CreateScriptSourceFromString( text, 'stdin', SourceCodeKind.InteractiveCode) try: result = source.GetCodeProperties() except TypeError: # happens when text is 'lambda' for some reason return True if result == ScriptCodeParseResult.IncompleteToken: return False elif result == ScriptCodeParseResult.IncompleteStatement: if not text.rstrip(' ').endswith('\n'): return False return True def on_first_line(self, text): first_line_end = text.find('\n') if first_line_end == -1: return True return self.SelectionStart <= first_line_end def on_last_line(self, text): last_line_end = text.rfind('\n') if last_line_end == -1: return True return self.SelectionStart > last_line_end def handle_key(self, sender, event): # Mac Safari uses '\r' for newlines in Silverlight TextBox?? contents = self.Text.replace('\r\n', '\n').replace('\r', '\n') key = event.Key start = self.SelectionStart end = start + self.SelectionLength modifiers = Keyboard.Modifiers control = (modifiers & ModifierKeys.Control) or (modifiers & ModifierKeys.Apple) if key == Key.C and control: event.Handled = True self.keyboard_interrupt() return if self._thread is not None: # ignore key events (we have already checked for Ctrl-C) event.Handled = True return if key != Key.Enter: if key == Key.Up: if self.on_first_line(contents): event.Handled = True previous = self.history.back(contents) if previous is not None: self.Text = previous self.SelectionStart = len(previous) return elif key == Key.Down: if self.on_last_line(contents): event.Handled = True next = self.history.forward(contents) if next is not None: self.Text = next self.SelectionStart = len(next) return elif key == Key.Tab: event.Handled = True self.Text = self.Text[:start] + ' ' + self.Text[end:] self.SelectionStart = start + 4 return if key == key.Add and self.ff3: if not (modifiers & ModifierKeys.Shift): event.Handled = True self.Text = self.Text[:start] + '=' + self.Text[end:] self.SelectionStart = start + 1 return TextBox.OnKeyDown(self, event) return event.Handled = True if empty_or_comment_only(contents): # needed or we get a SyntaxError self.Text = '' self.printer.print_lines(contents) self.printer.scroll() return # manual handling unfortunately # means things like trailing comments break # these functions; so not ideal stripped = contents.rstrip() if stripped == 'gohome': gohome() elif stripped == 'reset': contents = 'reset()' elif stripped == 'import this': # import hook so that importing *worked* # would be a better solution... self.printer.print_lines(stripped) self.Text = '' self.history.append(contents) import this self.context['this'] = this self.printer.set_prompt() self.printer.scroll() return if not self.is_complete(contents, start): self.do_indent(start) else: self.execute(contents) def execute(self, contents): self.printer.print_lines(contents) self.Text = '' self.history.append(contents) self._sync.Reset() started = ManualResetEvent(False) if self._temp_context is not None: self.context.update(self._temp_context) def _execute(): context = self.context started.Set() try: code = compile(contents + '\n', '<stdin>', 'single', PyCF_DONT_IMPLY_DEDENT) exec code in context except: if reset_event.WaitOne(1): # don't print exception messages if thread has been terminated return exc_type, value, tb = sys.exc_info() if value is None: # String exceptions # workaround for IronPython bug exc_type = Exception value = Exception('StringException') tblist = traceback.extract_tb(tb) message = traceback.format_list(tblist) del message[:1] if message: # we don't print the 'Traceback...' part for SyntaxError message.insert(0, "Traceback (most recent call last):\n") message.extend(traceback.format_exception_only( exc_type, value)) self.printer.print_new(''.join(message)) # access through closure not on self as we may be an orphaned # thread - with a new reset_event on self result = reset_event.WaitOne(0) if not reset_event.WaitOne(0): self.completed() self._sync.Set() self._thread_reset = reset_event = ManualResetEvent(False) self._thread = Thread(ThreadStart(_execute)) self._thread.IsBackground = True self._thread.Name = "executing" self._thread.Start() self.prompt.Visibility = Visibility.Collapsed if hasattr(self, 'CaretBrush'): self.CaretBrush = self._disabled started.WaitOne() @invoke def completed(self, reset_temp=True): if reset_temp: self._temp_context = None self._thread = None self.prompt.Visibility = Visibility.Visible self._thread_reset = None if hasattr(self, 'CaretBrush'): self.CaretBrush = self._original_caret if self._reset_needed: self.reset() else: self.printer.set_prompt() self.printer.scroll() def do_indent(self, start): to_the_left = self.Text[:start + 1] lines = to_the_left.splitlines() initial_indent = ' ' for line in lines: # we do this incase the user is using one or two space # indent instead of four if line.startswith(' '): initial_indent = get_indent(line) break # there *must* be something here because an empty textbox # would already have been caught by empty_or_comment_only last_line = lines[-1] new_indent = current_indent = get_indent(last_line) if last_line.rstrip().endswith(':'): new_indent = current_indent + initial_indent elif is_terminator(last_line): new_indent = ' ' * (len(current_indent) - len(initial_indent)) new_start = self.SelectionStart new_pos = new_start + len(new_indent) self.Text = self.Text[:new_start] + '\n' + new_indent + self.Text[ new_start:] self.SelectionStart = new_pos + 1 def keyboard_interrupt(self): # Aborting threads doesn't work on Silverlight :-( #self._thread.Abort() reset_temp = True if self._thread_reset is not None: reset_temp = False # signal to background thread not to complete self._thread_reset.Set() context = self.context self._temp_context = context.copy() # This will hopefully cause the existing thread to error out context.clear() context['raw_input'] = context['input'] = blow_up self._thread_reset = None self._thread = None if self.Text.strip(): self.history.append(self.Text) self.printer.print_new('KeyboardInterrupt') self.Text = '' self.completed(reset_temp) @invoke def setup_input_box(self, prompt): self.Visibility = Visibility.Collapsed self.root.rawInputPrompt.Text = prompt + ' ' self.root.rawInputField.Text = '' self.root.rawInputField.Width = self.Width - 60 self.root.rawInput.Visibility = Visibility.Visible self.root.rawInputField.KeyDown += self.check_for_enter self.root.rawInputField.Focus() @invoke def remove_input_box(self): self.Visibility = Visibility.Visible self.root.rawInput.Visibility = Visibility.Collapsed self.root.rawInputField.KeyDown -= self.check_for_enter self.printer.print_new(self.root.rawInputPrompt.Text + self._raw_input_text) self.Focus() def check_for_enter(self, sender, event): if event.Key == Key.Enter: event.Handled = True self._raw_input_text = self.root.rawInputField.Text self.input_event.Set() def raw_input(self, prompt='Input:'): if not isinstance(prompt, str): prompt = str(prompt) self.input_event = ManualResetEvent(False) self.setup_input_box(prompt) self.input_event.WaitOne() self.remove_input_box() return self._raw_input_text def _handle_lines(self, lines): try: self._input_data = [] for line in lines: self.handle_line(line) if self._input_data: self.handle_line('') self.Dispatcher.BeginInvoke(lambda: self.Focus()) except Exception, e: _debug('Handle lines', e)
def test_all(self): from System.Threading import ManualResetEvent, Thread, ThreadStart class MyOC: one = 'one' two = 'two' three = 'three' four = 'four' five = 'five' six = 'six' class MyUserType(object): one = 'one' two = 'two' three = 'three' four = 'four' five = 'five' six = 'six' class BaseUserTypeOne(object): pass class BaseUserTypeTwo(object): pass class DerivedUserType(BaseUserTypeOne): pass go = ManualResetEvent(False) # setup a table used for transforming loop iterations into identifiers. # 1 becomes A, 11 becomes AA, 12 becomes AB, 123 becomes ABC, etc... identityTable = [chr(x) for x in range(256)] transTable = '' for x in identityTable: if ord(x) >= ord('0') and ord(x) <= ord('9'): transTable = transTable + chr(ord('A') + ord(x) - ord('0')) else: transTable = transTable + x # base test infrastructure, reader thread, writer thread, and test # runner def reader(): try: try: go.WaitOne() for i in xrange(loopCnt): readerWorker(i) except Exception, e: self.fail( 'Test failed, unexpected exception from reader: %r' % e) finally: global readerAlive readerAlive = False class writer: def __init__(self, writer, index): self.writer = writer self.index = index def __call__(self, *args): try: try: go.WaitOne() for i in xrange(loopCnt): self.writer(i, self.index) except Exception, e: self.fail( 'Test failed (writer through exception): %r' % e) finally: global writerAlive writerAlive = False def runTest(): global writerAlive global readerAlive writerAlive = True readerAlive = True a = Thread(ThreadStart(reader)) a.IsBackground = True a.Start() if isinstance(writerWorker, tuple): b = [] index = 0 for wr in writerWorker: th = Thread(ThreadStart(writer(wr, index))) th.IsBackground = True th.Start() b.append(th) index = index + 1 else: b = [Thread(ThreadStart(writer(writerWorker, 0)))] b[0].IsBackground = True b[0].Start() go.Set() a.Join() for th in b: th.Join() # individual test cases, setup reader/writer workers # and then call run test # OldClass test cases def Reader_Dir(i): x = dir(oc) def Reader_CheckOneKey(i): self.assertEqual(getattr(oc, 'outsideFuncEnv'), outsideFuncEnvValue) def Reader_HasAttr(i): attrName = str(i).translate(transTable) hasattr(oc, attrName) def Reader_VerifyAllPresent(i): # verify that we can find all the previous values in the dictionary global writerAlive if not writerAlive: return # writer takes signifcantly less time, stop checking once we're no longer experiencing contention global prevValues for x in prevValues.keys(): #print 'checking ', x self.assertEqual(hasattr(oc, x), True) #print getattr(oc,x), prevValues[x] self.assertEqual(getattr(oc, x), prevValues[x]) for x in dir(oc): if not prevValues.has_key(x): prevValues[x] = getattr(oc, x) # generic writer, just keeps adding more and more attributes def Writer_Generic(i, writerIndex): attrName = str(i).translate(transTable) x = object() setattr(oc, attrName, x) self.assertEqual(getattr(oc, attrName), x) # generic writer, adds an attribute and then removes it. def Writer_Generic_Delete(i, writerIndex): attrName = str(i).translate(transTable) x = object() setattr(oc, attrName, x) self.assertEqual(getattr(oc, attrName), x) delattr(oc, attrName) # adds attributes to the class, deletes them in batches of 50 def Writer_Generic_BatchDelete(i, writerIndex): attrName = str(i).translate(transTable) x = object() setattr(oc, attrName, x) self.assertEqual(getattr(oc, attrName), x) if i != 0 and i % 50 == 0: for x in xrange(i - 50, i): attrName = str(x).translate(transTable) delattr(oc, attrName) def Reader_ExtraKeys(i): global oc if (i % 6) == 0: # create a new instance every 6 iterations (6 is the number # of custom keys per old-instance dict) oc = MyOC() if hasattr(oc, 'abc'): self.assertEqual(oc.abc, 'abc') if hasattr(oc, 'abcd'): self.assertEqual(oc.abcd, 'abcd') if hasattr(oc, 'abcde'): self.assertEqual(oc.abcde, 'abcde') if hasattr(oc, 'abcdef'): self.assertEqual(oc.abcdef, 'abcdef') if hasattr(oc, 'abcdefg'): self.assertEqual(oc.abcdefg, 'abcdefg') if hasattr(oc, 'abcdefgh'): self.assertEqual(oc.abcdefgh, 'abcdefgh') def Writer_ExtraKeys(i, writerIndex): if i % 6 == 0: oc.abc = 'abc' elif i % 6 == 1: oc.abcd = 'abcd' elif i % 6 == 2: oc.abcde = 'abcde' elif i % 6 == 3: oc.abcdef = 'abcdef' elif i % 6 == 4: oc.abcdefg = 'abcdefg' elif i % 6 == 5: oc.abcdefgh = 'abcdefgh' def Init_OldClass(loopCnt): global oc, outsideFuncEnvValue, prevValues prevValues = {} outsideFuncEnvValue = object() oc = MyOC() # fill in some attributes so we don't hit extra values... for id in range(loopCnt, loopCnt + 20): setattr(oc, str(id).translate(transTable), object()) # now set a value that's outside of the extra values setattr(oc, 'outsideFuncEnv', outsideFuncEnvValue) def Nop(i): pass # List Test Cases def List_Writer(i, writerIndex): myList.append(i) def List_Writer_Extend(i, writerIndex): myList.extend([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) def List_Reader(i): global lastRead if myList: lastRead = myList[-1] def List_Clear(i, writerIndex): if i % 50 == 0: if myList: del myList[:] def List_Slice_Set(i, writerIndex): if i % 50 == 0: myList[:] = [] def List_Index_Writer(i, writerIndex): global lastRead if myList: myList[-1] = lastRead def Init_List_Sort(loopCnt): global listOfLists1, listOfLists2 listOfLists1 = [] listOfLists2 = [] for x in range(200): listOfLists1.append([]) listOfLists2.append([]) for x in listOfLists1: for y in listOfLists2: x.append(y) y.append(x) def List_Sorter(i, writerIndex): global listOfLists1, listOfLists2 if writerIndex == 1: listOfLists1.sort() else: listOfLists2.sort() def Init_List(loopCnt): global myList, lastRead myList = [] lastRead = 0 def PostCondition_List(expectedLength): # create a closer around the inner function w/ the expected length def PostCondition_List_Inner(): self.assertEqual(len(myList), expectedLength) return PostCondition_List_Inner # user type test cases # verify mro / base classes update atomically def UserType_Write_Bases(i, writerIndex): if BaseUserTypeOne in myUserType.__bases__: myUserType.__bases__ = (BaseUserTypeTwo, ) else: myUserType.__bases__ = (BaseUserTypeOne, ) def UserType_Read_BasesAndMro(i): bases = myUserType.__bases__ self.assertTrue(bases == (BaseUserTypeOne, ) or bases == (BaseUserTypeTwo, )) mro = myUserType.__mro__ self.assertTrue( mro == (DerivedUserType, BaseUserTypeOne, object) or mro == (DerivedUserType, BaseUserTypeTwo, object)) def Init_UserType_Bases(loopCnt): global myUserType myUserType = DerivedUserType def Init_UserType(loopCnt): global oc, outsideFuncEnvValue, prevValues prevValues = {} outsideFuncEnvValue = object() oc = MyUserType() # set a value that's outside of the extra values setattr(oc, 'outsideFuncEnv', outsideFuncEnvValue) def Init_NewTypeMaker(loopCnt): global baseTypes baseTypes = (object, ) def CreateType(i, writerIndex): global baseTypes # we keep deriving a new type from a new combination of base types - always # object and an ever-growing list of old-style classes. Thread 0 is responsible # for pushing a new base type in. This causes all the creation threads to hit # contention and wait for a type to be published. type('foo', baseTypes, {}) if writerIndex == 0: class foo: pass baseTypes = baseTypes + (foo, ) testCases = [ # initialization, reader, writer, test loopCnt, post-condition. # Multiple writes can be provided w/ a tuple # new type maker tests (Init_NewTypeMaker, Nop, (CreateType, CreateType, CreateType, CreateType, CreateType, CreateType), 100 ), # user type tests (Init_UserType, Reader_ExtraKeys, (Writer_ExtraKeys, Writer_ExtraKeys), 100000), (Init_UserType, Reader_CheckOneKey, Writer_Generic_BatchDelete, 10000), (Init_UserType, Reader_CheckOneKey, Writer_Generic, 10000), (Init_UserType, Reader_CheckOneKey, Writer_Generic_Delete, 10000), (Init_UserType, Reader_Dir, Writer_Generic_BatchDelete, 10000), (Init_UserType, Reader_VerifyAllPresent, Writer_Generic, 10000), (Init_UserType, Reader_Dir, Writer_Generic_Delete, 10000), (Init_UserType, Reader_HasAttr, Writer_Generic, 10000), (Init_UserType_Bases, UserType_Read_BasesAndMro, UserType_Write_Bases, 10000), # list tests (Init_List_Sort, Nop, (List_Sorter, List_Sorter), 1000), (Init_List, List_Reader, (List_Index_Writer, List_Slice_Set), 100000), (Init_List, List_Reader, (List_Index_Writer, List_Clear), 100000), (Init_List, List_Reader, (List_Writer), 10000, PostCondition_List(10000)), (Init_List, List_Reader, (List_Index_Writer, List_Writer_Extend), 10000, PostCondition_List(10000 * 10)), (Init_List, List_Reader, (List_Writer, List_Index_Writer), 10000, PostCondition_List(10000)), (Init_List, Nop, (List_Writer_Extend, List_Writer_Extend), 10000, PostCondition_List(10000 * 2 * 10)), (Init_List, Nop, (List_Writer, List_Writer, List_Writer), 10000, PostCondition_List(10000 * 3)), # old-style class tests (Init_OldClass, Reader_ExtraKeys, (Writer_ExtraKeys, Writer_ExtraKeys), 100000), (Init_OldClass, Reader_CheckOneKey, Writer_Generic_BatchDelete, 10000), (Init_OldClass, Reader_CheckOneKey, Writer_Generic, 10000), (Init_OldClass, Reader_CheckOneKey, Writer_Generic_Delete, 10000), (Init_OldClass, Reader_Dir, Writer_Generic_BatchDelete, 10000), (Init_OldClass, Reader_VerifyAllPresent, Writer_Generic, 10000), (Init_OldClass, Reader_Dir, Writer_Generic_Delete, 10000), (Init_OldClass, Reader_HasAttr, Writer_Generic, 10000), ] def doOneTest(test): """runs a single test, argument is a testCase tuple""" print 'running test', test global loopCnt, writerWorker, readerWorker # call init function loopCnt = test[3] test[0](loopCnt) # set our workers readerWorker = test[1] writerWorker = test[2] # set our loopcnt # run the test runTest() if len(test) >= 5: test[4]() for test in testCases: doOneTest(test)