[Zope3-checkins] CVS: Zope3/lib/python/Zope/App - _app.py:1.4.22.1

Jim Fulton jim@zope.com
Thu, 19 Dec 2002 12:23:23 -0500


Update of /cvs-repository/Zope3/lib/python/Zope/App
In directory cvs.zope.org:/tmp/cvs-serv716

Modified Files:
      Tag: AdapterAndView-branch
	_app.py 
Log Message:
Moved debugging another step forward:

- Use separate methods for different tasks:

  publish -- to run a request as the publisher would, including
             outputing the response

  run -- Run the request without error handling and without printing
         the response. This is what to use for post-morten debugging.

  debug -- Run the request as the publisher does, but in pdb. Note
           that we don't get into pdb until after the request has been
           set up.  

- Request variables are no longer provides as keyword arguments.
  Rather, explicit arguments are provided for environment and form
  dictionaries::

   import Zope.App
   app = Zope.App.Application('Data.fs', 'site.zcml')
   app.publish("/", environment={'HTTP_METHOD': 'POST'},
                    form={'color': 'blue'})

To do:

  - Reading options from a .zopedebug file

  - Handling alternate presentation types

  - Timing and profiling


  

=== Zope3/lib/python/Zope/App/_app.py 1.4 => 1.4.22.1 ===
--- Zope3/lib/python/Zope/App/_app.py:1.4	Thu Oct 24 11:37:02 2002
+++ Zope3/lib/python/Zope/App/_app.py	Thu Dec 19 12:23:22 2002
@@ -88,19 +88,31 @@
 
     __browser_pub = None
     __TestRequest = None
-    def debug(self, path='/', stdin='', stdout=None, basic=None, pm=0,
-              environment = None, **kw):
-        
+
+    def _request(self,
+                 path='/', stdin='', stdout=None, basic=None,
+                 environment = None, form=None):
+
+
+        env = {}
+        frm = {}
+
         if stdout is None:
             stdout = StringIO()
 
         if type(stdin) is str:
             stdin = StringIO(stdin)
 
-        env = {'PATH_INFO': path}
+        p=path.split('?')
+        if len(p)==1:
+            env['PATH_INFO'] = p[0]
+        elif len(p)==2:
+            env['PATH_INFO'], env['QUERY_STRING'] = p
+        else:
+            raise ValueError("Too many ?s in path", path)
+
         if environment is not None:
             env.update(environment)
-        env.update(kw)
 
         if basic:
             env['HTTP_AUTHORIZATION']="Basic %s" % base64.encodestring(basic)
@@ -109,14 +121,93 @@
             from Zope.Publisher.Browser.BrowserRequest import TestRequest
             from Zope.App.ZopePublication.Browser.Publication \
                  import BrowserPublication
+            from Zope.App.ZopePublication.ZopePublication \
+                 import DebugPublication
+
+            class BrowserPublication(DebugPublication, BrowserPublication):
+                pass
+            
             self.__TestRequest = TestRequest
             self.__browser_pub = BrowserPublication(self.db)
 
         request = self.__TestRequest(stdin, stdout, env)
         request.setPublication(self.__browser_pub)
+        if form:
+            request.update(form)
 
-        _publish(request, handle_errors = not pm)
+        return request
 
+    def publish(self, path='/', stdin='', stdout=None, *args, **kw):
+        
+        if stdout is None:
+            stdout = StringIO()
+
+        request = self._request(path, stdin, stdout, *args, **kw)
+        _publish(request)
         stdout.seek(0)
         print stdout.read()
+
+    def run(self, *args, **kw):
+        request = self._request(*args, **kw)
+        _publish(request, handle_errors = 0)
+
+    def debug(self, *args, **kw):
         
+        import pdb
+
+        class Pdb(pdb.Pdb):
+            def do_pub(self,arg):
+                if hasattr(self,'done_pub'):
+                    print 'pub already done.'
+                else:
+                    self.do_s('')
+                    self.do_s('')
+                    self.do_c('')
+                    self.done_pub=1
+            def do_ob(self,arg):
+                if hasattr(self,'done_ob'):
+                    print 'ob already done.'
+                else:
+                    self.do_pub('')
+                    self.do_c('')
+                    self.done_ob=1
+
+        db=Pdb()
+
+        def fbreak(db, meth):
+            try:
+                meth = meth.im_func
+            except AttributeError:
+                pass
+            code = meth.func_code
+            lineno = getlineno(code)
+            filename = code.co_filename
+            db.set_break(filename,lineno)
+
+        request = self._request(*args, **kw)
+        fbreak(db, _publish)
+        fbreak(db, request.publication.call_wrapper.__call__)
+
+##         dbdata = {'breakpoints':(), 'env':env, 'extra': extra}
+##         b=''
+##         try: b=open('.bobodb','r').read()
+##         except: pass
+##         if b:
+##             exec b in dbdata
+
+##         for b in dbdata['breakpoints']:
+##             if isinstance(b, TupleType):
+##                 apply(db.set_break, b)
+##             else:
+##                 fbreak(db,b)
+
+        db.prompt='pdb> '
+
+        print '* Type c<cr> to jump to published object call.'
+        db.runcall(_publish, request)
+
+try:
+    from codehack import getlineno
+except:
+    def getlineno(code):
+        return code.co_firstlineno