Пример #1
0
    def test_pub_sub_select_channel(self):

        # Connect
        self._context1.bind("localhost:test1")
        self._context2.connect("localhost:test1")

        # Create channels
        pub1 = yoton.PubChannel(self._context1, "foo1")
        pub2 = yoton.PubChannel(self._context1, "foo2")
        #
        sub1 = yoton.SubChannel(self._context2, "foo1")
        sub2 = yoton.SubChannel(self._context2, "foo2")

        # Send a bunch of messages
        ii = [0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1]
        for i in range(len(ii)):
            pub = [pub1, pub2][ii[i]]
            pub.send(str(i))

        time.sleep(0.1)

        # Receive in right order
        count = 0
        while True:
            sub = yoton.select_sub_channel(sub1, sub2)
            if sub:
                i = int(sub.recv())
                self.assertEqual(i, count)
                count += 1
            else:
                break

        # Test count
        self.assertEqual(count, len(ii))
Пример #2
0
 def test_pub_sub_select_channel(self):
     
     # Connect
     self._context1.bind('localhost:test1')
     self._context2.connect('localhost:test1')
     
     # Create channels
     pub1 = yoton.PubChannel(self._context1, 'foo1')
     pub2 = yoton.PubChannel(self._context1, 'foo2')
     #
     sub1 = yoton.SubChannel(self._context2, 'foo1')
     sub2 = yoton.SubChannel(self._context2, 'foo2')
     
     # Send a bunch of messages
     I = [0,1,0,0,1,0,1,1,1,0,0,1,0,0,0,1,1,0,1]
     for i in range(len(I)):
         pub = [pub1, pub2][I[i]]
         pub.send(str(i))
     
     time.sleep(0.1)
     
     # Receive in right order
     count = 0
     while True:
         sub = yoton.select_sub_channel(sub1, sub2)
         if sub:
             i = int(sub.recv())
             self.assertEqual(i, count)
             count += 1
         else:
             break
     
     # Test count
     self.assertEqual(count, len(I))
Пример #3
0
 def _process_commands(self):
     
     # Run startup code/script inside the loop (only the first time)
     # so that keyboard interrupt will work
     if self._codeToRunOnStartup:
         self.context._stat_interpreter.send('Busy')
         self._codeToRunOnStartup, tmp = None, self._codeToRunOnStartup
         self.pushline(tmp)
     if self._scriptToRunOnStartup:
         self.context._stat_interpreter.send('Busy') 
         self._scriptToRunOnStartup, tmp = None, self._scriptToRunOnStartup
         self.runfile(tmp)
     
     # Flush real stdout / stderr
     sys.__stdout__.flush()
     sys.__stderr__.flush()
     
     # Set status and prompt?
     # Prompt is allowed to be an object with __str__ method
     if self.newPrompt:
         self.newPrompt = False
         ps = [sys.ps1, sys.ps2][bool(self.more)]
         self.context._strm_prompt.send(str(ps))
     
     if True:
         # Determine state. The message is really only send
         # when the state is different. Note that the kernelbroker
         # can also set the state ("Very busy", "Busy", "Dead")
         if self._dbFrames:
             self.context._stat_interpreter.send('Debug')
         elif self.more:
             self.context._stat_interpreter.send('More')
         else:
             self.context._stat_interpreter.send('Ready')
     
     
     # Are we still connected?
     if sys.stdin.closed or not self.context.connection_count:
         # Exit from main loop.
         # This will raise SystemExit and will shut us down in the 
         # most appropriate way
         sys.exit()
     
     # Get channel to take a message from
     ch = yoton.select_sub_channel(self.context._ctrl_command, self.context._ctrl_code)
     
     if ch is None:
         pass # No messages waiting
     
     elif ch is self.context._ctrl_command:
         # Read command 
         line1 = self.context._ctrl_command.recv(False) # Command
         if line1:
             # Notify what we're doing
             self.context._strm_echo.send(line1)
             self.context._stat_interpreter.send('Busy')
             self.newPrompt = True
             # Convert command 
             # (only a few magics are supported if IPython is active)
             line2 = self.magician.convert_command(line1.rstrip('\n'))
             # Execute actual code
             if line2 is not None:
                 for line3 in line2.split('\n'):  # not splitlines!
                     self.more = self.pushline(line3)
             else:
                 self.more = False
                 self._resetbuffer()
     
     elif ch is self.context._ctrl_code:
         # Read larger block of code (dict)
         msg = self.context._ctrl_code.recv(False)
         if msg:
             # Notify what we're doing
             # (runlargecode() sends on stdin-echo)
             self.context._stat_interpreter.send('Busy')
             self.newPrompt = True
             # Execute code
             self.runlargecode(msg)
             # Reset more stuff
             self._resetbuffer()
             self.more = False
     
     else:
         # This should not happen, but if it does, just flush!
         ch.recv(False)
Пример #4
0
 def _process_commands(self):
     
     # Run startup code/script inside the loop (only the first time)
     # so that keyboard interrupt will work
     if self._codeToRunOnStartup:
         self.context._stat_interpreter.send('Busy')
         self._codeToRunOnStartup, tmp = None, self._codeToRunOnStartup
         self.pushline(tmp)
     if self._scriptToRunOnStartup:
         self.context._stat_interpreter.send('Busy') 
         self._scriptToRunOnStartup, tmp = None, self._scriptToRunOnStartup
         self.runfile(tmp)
     
     # Flush real stdout / stderr
     sys.__stdout__.flush()
     sys.__stderr__.flush()
     
     # Set status and prompt?
     # Prompt is allowed to be an object with __str__ method
     if self.newPrompt:
         self.newPrompt = False
         ps = [sys.ps1, sys.ps2][bool(self.more)]
         self.context._strm_prompt.send(str(ps))
     
     if True:
         # Determine state. The message is really only send
         # when the state is different. Note that the kernelbroker
         # can also set the state ("Very busy", "Busy", "Dead")
         if self._dbFrames:
             self.context._stat_interpreter.send('Debug')
         elif self.more:
             self.context._stat_interpreter.send('More')
         else:
             self.context._stat_interpreter.send('Ready')
     
     
     # Are we still connected?
     if sys.stdin.closed or not self.context.connection_count:
         # Exit from main loop.
         # This will raise SystemExit and will shut us down in the 
         # most appropriate way
         sys.exit()
     
     # Get channel to take a message from
     ch = yoton.select_sub_channel(self.context._ctrl_command, self.context._ctrl_code)
     
     if ch is None:
         pass # No messages waiting
     
     elif ch is self.context._ctrl_command:
         # Read command 
         line1 = self.context._ctrl_command.recv(False) # Command
         if line1:
             # Notify what we're doing
             self.context._strm_echo.send(line1)
             self.context._stat_interpreter.send('Busy')
             self.newPrompt = True
             # Convert command 
             # (only a few magics are supported if IPython is active)
             line2 = self.magician.convert_command(line1.rstrip('\n'))
             # Execute actual code
             if line2 is not None:
                 for line3 in line2.split('\n'):  # not splitlines!
                     self.more = self.pushline(line3)
             else:
                 self.more = False
                 self._resetbuffer()
     
     elif ch is self.context._ctrl_code:
         # Read larger block of code (dict)
         msg = self.context._ctrl_code.recv(False)
         if msg:
             # Notify what we're doing
             # (runlargecode() sends on stdin-echo)
             self.context._stat_interpreter.send('Busy')
             self.newPrompt = True
             # Execute code
             self.runlargecode(msg)
             # Reset more stuff
             self._resetbuffer()
             self.more = False
     
     else:
         # This should not happen, but if it does, just flush!
         ch.recv(False)
Пример #5
0
    def _mainloop(self):
        """ The actual main loop of the interpreter.
        """

        # Get channels as local variables
        ctrl_command = self.context._ctrl_command
        ctrl_code = self.context._ctrl_code
        strm_echo = self.context._strm_echo
        strm_prompt = self.context._strm_prompt
        stat_interpreter = self.context._stat_interpreter

        # To keep track of whether to send a new prompt, and whether more
        # code is expected.
        more = 0
        newPrompt = True

        while True:
            try:

                # Run startup script inside the loop (only the first time)
                # so that keyboard interrupt will work
                if self._scriptToRunOnStartup:
                    stat_interpreter.send('Busy')
                    self._scriptToRunOnStartup, tmp = None, self._scriptToRunOnStartup
                    self.runfile(tmp)

                # Set status and prompt?
                # Prompt is allowed to be an object with __str__ method
                if newPrompt:
                    newPrompt = False
                    # Write prompt (note that the second "if" is not an "elif"!
                    preamble = ''
                    if self._dbFrames:
                        preamble = '(' + self._dbFrameName + ')'
                    if more:
                        strm_prompt.send(preamble + str(sys.ps2))
                    else:
                        strm_prompt.send(preamble + str(sys.ps1))

                if True:
                    # Determine state. The message is really only send
                    # when the state is different. Note that the kernelbroker
                    # can also set the state ("Very busy", "Busy", "Dead")
                    if self._dbFrames:
                        stat_interpreter.send('Debug')
                    elif more:
                        stat_interpreter.send('More')
                    else:
                        stat_interpreter.send('Ready')

                # Are we still connected?
                if sys.stdin.closed or not self.context.connection_count:
                    # Exit from main loop
                    break

                # Get channel to take a message from
                ch = yoton.select_sub_channel(ctrl_command, ctrl_code)

                if ch is None:
                    pass  # No messages waiting

                elif ch is ctrl_command:
                    # Read command
                    line1 = ctrl_command.recv(False)  # Command
                    if line1:
                        # Notify what we're doing
                        strm_echo.send(line1)
                        stat_interpreter.send('Busy')
                        newPrompt = True
                        # Convert command
                        line2 = self.magician.convert_command(
                            line1.rstrip('\n'))
                        # Execute actual code
                        if line2 is not None:
                            for line3 in line2.split('\n'):  # not splitlines!
                                more = self.pushline(line3)
                        else:
                            more = False
                            self._resetbuffer()

                elif ch is ctrl_code:
                    # Read larger block of code (dict)
                    msg = ctrl_code.recv(False)
                    if msg:
                        # Notify what we're doing
                        # (runlargecode() sends on stdin-echo)
                        stat_interpreter.send('Busy')
                        newPrompt = True
                        # Execute code
                        self.runlargecode(msg)
                        # Reset more stuff
                        self._resetbuffer()
                        more = False

                else:
                    # This should not happen, but if it does, just flush!
                    ch.recv(False)

                # Keep GUI toolkit up to date
                if self.guiApp:
                    self.guiApp.processEvents()

                # Wait for a bit at each round
                time.sleep(self.sleeptime)  # 50 ms

            except KeyboardInterrupt:
                self.write("\nKeyboardInterrupt\n")
                self._resetbuffer()
                more = 0
            except TypeError:
                # For some reason, when wx is hijacked, keyboard interrupts
                # result in a TypeError.
                # I tried to find the source, but did not find it. If anyone
                # has an idea, please e-mail me!
                if self.guiName == 'WX':
                    self.write(
                        "\nKeyboard Interrupt\n")  # space to see difference
                    self._resetbuffer()
                    more = 0
            except SystemExit:
                # Exit from interpreter (essentially SystemExit falls through)
                raise
Пример #6
0
    def poll(self, channel=None):
        """ poll()
        To keep the shell up-to-date.
        Call this periodically. 
        """

        if self._write_buffer:
            # There is still data in the buffer
            sub, M = self._write_buffer
        else:
            # Check what subchannel has the latest message pending
            sub = yoton.select_sub_channel(self._strm_out, self._strm_err,
                                           self._strm_echo, self._strm_raw,
                                           self._strm_broker,
                                           self._strm_prompt)
            # Read messages from it
            if sub:
                M = sub.recv_selected()
                #M = [sub.recv()] # Slow version (for testing)
                # Optimization: handle backspaces on stack of messages
                if sub is self._strm_out:
                    M = self._handleBackspacesOnList(M)
            # New prompt?
            if sub is self._strm_prompt:
                self.stateChanged.emit(self)

        # Write all pending messages that are later than any other message
        if sub:
            # Select messages to process
            N = 256
            M, buffer = M[:N], M[N:]
            # Buffer the rest
            if buffer:
                self._write_buffer = sub, buffer
            else:
                self._write_buffer = None
            # Get how to deal with prompt
            prompt = 0
            if sub is self._strm_echo:
                prompt = 1
            elif sub is self._strm_prompt:
                prompt = 2
            # Get color
            color = None
            if sub is self._strm_broker:
                color = '#000'
            elif sub is self._strm_raw:
                color = '#888888'  # Halfway
            elif sub is self._strm_err:
                color = '#F00'
            # Write
            self.write(''.join(M), prompt, color)

        # Do any actions?
        action = self._strm_action.recv(False)
        if action:
            if action.startswith('open '):
                fname = action.split(' ', 1)[1]
                iep.editors.loadFile(fname)
            else:
                print('Unkown action: %s' % action)

        # Update status
        state = self._stat_interpreter.recv()
        if state != self._state:
            self._state = state
            self.stateChanged.emit(self)

        # Update debug status
        state = self._stat_debug.recv()
        if state != self._debugState:
            self._debugState = state
            self.debugStateChanged.emit(self)
Пример #7
0
 def poll(self, channel=None):
     """ poll()
     To keep the shell up-to-date.
     Call this periodically. 
     """
     
     if self._write_buffer:
         # There is still data in the buffer
         sub, M = self._write_buffer
     else:
         # Check what subchannel has the latest message pending
         sub = yoton.select_sub_channel(self._strm_out, self._strm_err, 
                             self._strm_echo, self._strm_raw,
                             self._strm_broker, self._strm_prompt )
         # Read messages from it
         if sub:
             M = sub.recv_selected()
             #M = [sub.recv()] # Slow version (for testing)
             # Optimization: handle backspaces on stack of messages
             if sub is self._strm_out:
                 M = self._handleBackspacesOnList(M)
         # New prompt?
         if sub is self._strm_prompt:
             self.stateChanged.emit(self)
     
     # Write all pending messages that are later than any other message
     if sub:
         # Select messages to process
         N = 256
         M, buffer = M[:N], M[N:]
         # Buffer the rest
         if buffer:
             self._write_buffer = sub, buffer
         else:
             self._write_buffer = None
         # Get how to deal with prompt
         prompt = 0
         if sub is self._strm_echo:
             prompt = 1 
         elif sub is  self._strm_prompt:
             prompt = 2
         # Get color
         color = None
         if sub is self._strm_broker:
             color = '#000'
         elif sub is self._strm_raw:
             color = '#888888' # Halfway
         elif sub is self._strm_err:
             color = '#F00'
         # Write
         self.write(''.join(M), prompt, color)
     
     
     # Do any actions?
     action = self._strm_action.recv(False)
     if action:
         if action.startswith('open '):
             fname = action.split(' ',1)[1]
             iep.editors.loadFile(fname)
         else:
             print('Unkown action: %s' % action)
     
     # Update status
     state = self._stat_interpreter.recv()
     if state != self._state:
         self._state = state
         self.stateChanged.emit(self)
     
     # Update debug status
     state = self._stat_debug.recv()        
     if state != self._debugState:
         self._debugState = state
         self.debugStateChanged.emit(self)
Пример #8
0
 def _mainloop(self):
     """ The actual main loop of the interpreter.
     """
     
     # Get channels as local variables
     ctrl_command = self.context._ctrl_command
     ctrl_code = self.context._ctrl_code
     strm_echo = self.context._strm_echo
     strm_prompt = self.context._strm_prompt
     stat_interpreter = self.context._stat_interpreter
     
     # To keep track of whether to send a new prompt, and whether more
     # code is expected.
     more = 0
     newPrompt = True
     
     while True:
         try:
             
             # Run startup script inside the loop (only the first time)
             # so that keyboard interrupt will work
             if self._scriptToRunOnStartup:
                 stat_interpreter.send('Busy') 
                 self._scriptToRunOnStartup, tmp = None, self._scriptToRunOnStartup
                 self.runfile(tmp)
             
             # Set status and prompt?
             # Prompt is allowed to be an object with __str__ method
             if newPrompt:
                 newPrompt = False
                 # Write prompt (note that the second "if" is not an "elif"!
                 preamble = ''
                 if self._dbFrames:
                     preamble = '('+self._dbFrameName+')'
                 if more:
                     strm_prompt.send(preamble+str(sys.ps2))
                 else:
                     strm_prompt.send(preamble+str(sys.ps1))
             
             if True:
                 # Determine state. The message is really only send
                 # when the state is different. Note that the kernelbroker
                 # can also set the state ("Very busy", "Busy", "Dead")
                 if self._dbFrames:
                     stat_interpreter.send('Debug')
                 elif more:
                     stat_interpreter.send('More')
                 else:
                     stat_interpreter.send('Ready')
             
             
             # Are we still connected?
             if sys.stdin.closed or not self.context.connection_count:
                 # Exit from main loop
                 break
             
             # Get channel to take a message from
             ch = yoton.select_sub_channel(ctrl_command, ctrl_code)
             
             if ch is None:
                 pass # No messages waiting
             
             elif ch is ctrl_command:
                 # Read command 
                 line1 = ctrl_command.recv(False) # Command
                 if line1:
                     # Notify what we're doing
                     strm_echo.send(line1)
                     stat_interpreter.send('Busy')
                     newPrompt = True
                     # Convert command
                     line2 = self.magician.convert_command(line1.rstrip('\n'))
                     # Execute actual code
                     if line2 is not None:
                         for line3 in line2.split('\n'): # not splitlines!
                             more = self.pushline(line3)
                     else:
                         more = False
                         self._resetbuffer()
             
             elif ch is ctrl_code:
                 # Read larger block of code (dict)
                 msg = ctrl_code.recv(False)
                 if msg:
                     # Notify what we're doing
                     # (runlargecode() sends on stdin-echo)
                     stat_interpreter.send('Busy')
                     newPrompt = True
                     # Execute code
                     self.runlargecode(msg)
                     # Reset more stuff
                     self._resetbuffer()
                     more = False
             
             else:
                 # This should not happen, but if it does, just flush!
                 ch.recv(False)
             
             # Keep GUI toolkit up to date
             if self.guiApp:
                 self.guiApp.processEvents()
             
             # Wait for a bit at each round
             time.sleep(self.sleeptime) # 50 ms
         
         
         except KeyboardInterrupt:
             self.write("\nKeyboardInterrupt\n")
             self._resetbuffer()
             more = 0
         except TypeError:
             # For some reason, when wx is hijacked, keyboard interrupts
             # result in a TypeError.
             # I tried to find the source, but did not find it. If anyone
             # has an idea, please e-mail me!
             if self.guiName == 'WX':
                 self.write("\nKeyboard Interrupt\n") # space to see difference
                 self._resetbuffer()
                 more = 0
         except SystemExit:
             # Exit from interpreter (essentially SystemExit falls through)
             raise