[Checkins] SVN: zc.monitor/trunk/src/zc/monitor/ add the "MORE" mode so commands can co-opt user interaction

Benji York benji at zope.com
Wed Oct 28 17:17:50 EDT 2009


Log message for revision 105343:
  add the "MORE" mode so commands can co-opt user interaction
  

Changed:
  U   zc.monitor/trunk/src/zc/monitor/CHANGES.txt
  U   zc.monitor/trunk/src/zc/monitor/README.txt
  U   zc.monitor/trunk/src/zc/monitor/__init__.py
  U   zc.monitor/trunk/src/zc/monitor/tests.py

-=-
Modified: zc.monitor/trunk/src/zc/monitor/CHANGES.txt
===================================================================
--- zc.monitor/trunk/src/zc/monitor/CHANGES.txt	2009-10-28 19:45:41 UTC (rev 105342)
+++ zc.monitor/trunk/src/zc/monitor/CHANGES.txt	2009-10-28 21:17:49 UTC (rev 105343)
@@ -2,6 +2,11 @@
 Change History
 ==============
 
+0.2.0 (2009-10-28)
+------------------
+
+- Add the "MORE" mode so commands can co-opt user interaction
+
 0.1.2 (2008-09-15)
 ------------------
 

Modified: zc.monitor/trunk/src/zc/monitor/README.txt
===================================================================
--- zc.monitor/trunk/src/zc/monitor/README.txt	2009-10-28 19:45:41 UTC (rev 105342)
+++ zc.monitor/trunk/src/zc/monitor/README.txt	2009-10-28 21:17:49 UTC (rev 105343)
@@ -20,10 +20,10 @@
 
     >>> def hello(connection, name='world'):
     ...     """Say hello
-    ...     
+    ...
     ...     Provide a name if you're not the world.
     ...     """
-    ...     connection.write("Hi %s, nice to meet ya!\n" % name) 
+    ...     connection.write("Hi %s, nice to meet ya!\n" % name)
 
 and register it:
 
@@ -160,3 +160,51 @@
    Closing the connection:
 
    >>> connection.test_close('test')
+
+
+Command loops
+-------------
+
+Using the "MORE" mode, commands can signal that they want to claim all future
+user input.  We'll implement a silly example to demonstrate how it works.
+
+Here's a command that implements a calculator.
+
+    >>> PROMPT = '.'
+    >>> def calc(connection, *args):
+    ...     if args and args[0] == 'quit':
+    ...         return zc.monitor.QUIT_MARKER
+    ...
+    ...     if args:
+    ...         connection.write(str(eval(''.join(args))))
+    ...         connection.write('\n')
+    ...
+    ...     connection.write(PROMPT)
+    ...     return zc.monitor.MORE_MARKER
+
+If we register this command...
+
+    >>> zope.component.provideUtility(calc,
+    ...     zc.monitor.interfaces.IMonitorPlugin, 'calc')
+
+...we can invoke it and we get a prompt.
+
+    >>> connection = zc.ngi.testing.TextConnection()
+    >>> server = zc.monitor.Server(connection)
+    >>> connection.test_input('calc\n')
+    .
+
+If we then give it more input we get the result plus another prompt.
+
+    >>> connection.test_input('2+2\n')
+    4
+    .
+
+    >>> connection.test_input('4*2\n')
+    8
+    .
+
+Once we're done we can tell the calculator to let us go.
+
+    >>> connection.test_input('quit\n')
+    -> CLOSE

Modified: zc.monitor/trunk/src/zc/monitor/__init__.py
===================================================================
--- zc.monitor/trunk/src/zc/monitor/__init__.py	2009-10-28 19:45:41 UTC (rev 105342)
+++ zc.monitor/trunk/src/zc/monitor/__init__.py	2009-10-28 21:17:49 UTC (rev 105343)
@@ -23,6 +23,7 @@
 
 INTERACTIVE_MARKER = object()
 QUIT_MARKER = object()
+MORE_MARKER = object()
 
 class Server:
 
@@ -36,7 +37,9 @@
 
     def handle_input(self, connection, data):
         args = data.strip().split()
-        if not args:
+        if self.mode is MORE_MARKER:
+            command_name = self.last_command[0]
+        elif not args:
             if self.last_command is not None:
                 command_name, args = self.last_command
             else:
@@ -57,10 +60,8 @@
                 traceback.print_exc(100, connection)
                 print >> connection, "%s: %s\n" % (v.__class__.__name__, v)
             else:
-                if res is INTERACTIVE_MARKER:
+                if res in (INTERACTIVE_MARKER, QUIT_MARKER, MORE_MARKER):
                     self.mode = res
-                elif res is QUIT_MARKER:
-                    self.mode = res
 
         if self.mode is QUIT_MARKER:
             connection.write(zc.ngi.END_OF_DATA)
@@ -83,7 +84,7 @@
             # Don't kill the process just because somebody else has our port.
             # This might be a zopectl debug or some other innocuous problem.
             logging.warning(
-                'unable to start z3monitor server because port %d is in use.',
+                'unable to start zc.monitor server because port %d is in use.',
                 port)
             return False
         else:

Modified: zc.monitor/trunk/src/zc/monitor/tests.py
===================================================================
--- zc.monitor/trunk/src/zc/monitor/tests.py	2009-10-28 19:45:41 UTC (rev 105342)
+++ zc.monitor/trunk/src/zc/monitor/tests.py	2009-10-28 21:17:49 UTC (rev 105343)
@@ -11,14 +11,11 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-import unittest
 
 from zope.testing import doctest
 
 def test_suite():
-    return unittest.TestSuite((
-        doctest.DocFileSuite(
-            'README.txt',
-            ),
-        
-        ))
+    return doctest.DocFileSuite(
+        'README.txt',
+        optionflags=doctest.NORMALIZE_WHITESPACE,
+        )



More information about the checkins mailing list