[pypy-svn] r39030 - in pypy/branch/guido-buildtool-web/pypy/tool/build: . templates test

guido at codespeak.net guido at codespeak.net
Fri Feb 16 17:23:35 CET 2007


Author: guido
Date: Fri Feb 16 17:23:34 2007
New Revision: 39030

Added:
   pypy/branch/guido-buildtool-web/pypy/tool/build/templates/builderinfo.html
   pypy/branch/guido-buildtool-web/pypy/tool/build/templates/buildersinfo.html
   pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_webapp.py
Modified:
   pypy/branch/guido-buildtool-web/pypy/tool/build/build.py
   pypy/branch/guido-buildtool-web/pypy/tool/build/config.py
   pypy/branch/guido-buildtool-web/pypy/tool/build/conftest.py
   pypy/branch/guido-buildtool-web/pypy/tool/build/metaserver.py
   pypy/branch/guido-buildtool-web/pypy/tool/build/templates/index.html
   pypy/branch/guido-buildtool-web/pypy/tool/build/templates/serverstatus.html
   pypy/branch/guido-buildtool-web/pypy/tool/build/test/fake.py
   pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_build.py
   pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_metaserver.py
   pypy/branch/guido-buildtool-web/pypy/tool/build/webapp.py
   pypy/branch/guido-buildtool-web/pypy/tool/build/webserver.py
Log:
Added some more pages and some more information on the BuildRequest objects to
display. Some pages don't yet display anything, though, and not all the
information that we're interested in is available yet. Also small cleanups of
the tests, and added some 'missing tests'.


Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/build.py
==============================================================================
--- pypy/branch/guido-buildtool-web/pypy/tool/build/build.py	(original)
+++ pypy/branch/guido-buildtool-web/pypy/tool/build/build.py	Fri Feb 16 17:23:34 2007
@@ -110,6 +110,9 @@
         self.svnurl = svnurl
         self.svnrev = svnrev
         self.revrange = revrange
+        self.request_time = py.std.time.time()
+        self.build_start_time = None
+        self.build_end_time = None
 
     def __str__(self):
         return '<BuildRequest %s:%s>' % (self.svnurl, self.normalized_rev)
@@ -119,7 +122,8 @@
         """
         return 'build.BuildRequest(%r, %r, %r, %r, %r, %r)' % (
                 self.email, self.sysinfo, self.compileinfo, self.svnurl,
-                self.svnrev, self.revrange)
+                self.svnrev, self.revrange, self.request_time,
+                self.build_start_time, self.build_end_time)
 
     def serialize(self):
         data = {'normalized_rev': self.normalized_rev} # it's a property
@@ -132,6 +136,9 @@
 svnrev: %(svnrev)s
 revrange: %(revrange)s
 normalized_rev: %(normalized_rev)s
+request_time: %(request_time)s
+build_start_time: %(build_start_time)s
+build_end_time: %(build_end_time)s
 """ % data
 
     def _fromstring(cls, s):
@@ -146,6 +153,9 @@
                   eval(data['compileinfo']), data['svnurl'], data['svnrev'],
                   int(data['revrange']))
         ret._nr = int(data['normalized_rev'])
+        ret.request_time = eval(data['request_time'])
+        ret.build_start_time = eval(data['build_start_time'])
+        ret.build_end_time = eval(data['build_end_time'])
         return ret
     fromstring = classmethod(_fromstring)
 

Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/config.py
==============================================================================
--- pypy/branch/guido-buildtool-web/pypy/tool/build/config.py	(original)
+++ pypy/branch/guido-buildtool-web/pypy/tool/build/config.py	Fri Feb 16 17:23:34 2007
@@ -3,7 +3,7 @@
 packageparent = py.magic.autopath().dirpath().dirpath().dirpath().dirpath()
 
 # general settings, used by both server and client
-server = 'codespeak.net'
+server = 'localhost'
 port = 12321
 testport = 32123
 path = [str(packageparent)]

Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/conftest.py
==============================================================================
--- pypy/branch/guido-buildtool-web/pypy/tool/build/conftest.py	(original)
+++ pypy/branch/guido-buildtool-web/pypy/tool/build/conftest.py	Fri Feb 16 17:23:34 2007
@@ -9,6 +9,11 @@
                action="store_true", dest="functional", default=False,
                help="run pypybuilder functional tests"
         ),
+        Option('', '--webcheck',
+               action="store_true", dest="webcheck", default=False,
+               help=("run (X)HTML validity tests (using "
+                     "http://www.w3c.org/validator)")
+        ),
 )
 
 class Directory(Dir):

Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/metaserver.py
==============================================================================
--- pypy/branch/guido-buildtool-web/pypy/tool/build/metaserver.py	(original)
+++ pypy/branch/guido-buildtool-web/pypy/tool/build/metaserver.py	Fri Feb 16 17:23:34 2007
@@ -25,6 +25,9 @@
             return False
     return True
 
+def make_id(build):
+    """ generate a unique, but predictable id for a build """
+
 class MetaServer(object):
     """ the build meta-server
 
@@ -171,12 +174,28 @@
 
     def status(self):
         # XXX temporary
-        in_progress = len([b for b in self._builders if b.busy_on])
-        return {'in_progress': in_progress,
+        running = len([b for b in self._builders if b.busy_on])
+        return {'builders': len(self._builders),
+                'running': running,
                 'queued': len(self._queued),
-                'waiting': len(self._waiting),
+                'waiting': len(self._waiting) + running,
                 'done': len(self._done)}
 
+    def buildersinfo(self):
+        ret = []
+        for b in self._builders:
+            print 'busy_on:', b.busy_on
+            print 'resolved:', b.busy_on and b.busy_on.compileinfo or None
+            ret.append({
+                'hostname': b.hostname,
+                'sysinfo': b.sysinfo,
+                'busy_on': b.busy_on and b.busy_on.compileinfo or None,
+            })
+        return ret
+
+    def buildids(self):
+        pass
+
     def _cleanup_builders(self):
         self._queuelock.acquire()
         try:

Added: pypy/branch/guido-buildtool-web/pypy/tool/build/templates/builderinfo.html
==============================================================================
--- (empty file)
+++ pypy/branch/guido-buildtool-web/pypy/tool/build/templates/builderinfo.html	Fri Feb 16 17:23:34 2007
@@ -0,0 +1,8 @@
+      <div class="builder">
+        <h3>%(hostname)s</h3>
+        <div class="builderinfo">
+          <div>sysinfo: %(sysinfo)s</div>
+          <div>busy on: %(busy_on)s</div>
+        </div>
+      </div>
+

Added: pypy/branch/guido-buildtool-web/pypy/tool/build/templates/buildersinfo.html
==============================================================================
--- (empty file)
+++ pypy/branch/guido-buildtool-web/pypy/tool/build/templates/buildersinfo.html	Fri Feb 16 17:23:34 2007
@@ -0,0 +1,13 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+  <head>
+    <title>Build meta server builders page</title>
+  </head>
+  <body>
+    <h2>Connected build servers</h2>
+    <div class="builders">
+%(builders)s
+    </div>
+  </body>
+</html>
+

Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/templates/index.html
==============================================================================
--- pypy/branch/guido-buildtool-web/pypy/tool/build/templates/index.html	(original)
+++ pypy/branch/guido-buildtool-web/pypy/tool/build/templates/index.html	Fri Feb 16 17:23:34 2007
@@ -1,9 +1,13 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 <html>
   <head>
     <title>Build meta server web interface (temp index page)</title>
   </head>
   <body>
-    <a href="/serverstatus">server status</a>
+    <ul>
+      <li><a href="/serverstatus">server status</a></li>
+      <li><a href="/builders">connected build servers</a></li>
+    </ul>
   </body>
 </html>
 

Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/templates/serverstatus.html
==============================================================================
--- pypy/branch/guido-buildtool-web/pypy/tool/build/templates/serverstatus.html	(original)
+++ pypy/branch/guido-buildtool-web/pypy/tool/build/templates/serverstatus.html	Fri Feb 16 17:23:34 2007
@@ -1,3 +1,4 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 <html>
   <head>
     <title>Build meta server status page</title>
@@ -5,10 +6,10 @@
   <body>
     <h2>Server status</h2>
     <ul>
-      <li>Currently in progress: %(in_progress)s</li>
+      <li>Connected build servers: %(builders)s</li>
+      <li>Currently running builds: %(running)s</li>
       <li>Builds done: %(done)s</li>
-      <li>Waiting (clients for which a suitable build is in progress already):
-          %(waiting)s</li>
+      <li>Clients waiting for a build: %(waiting)s</li>
       <li>Builds for which no suitable server is available: %(queued)s</li>
     </ul>
   </body>

Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/test/fake.py
==============================================================================
--- pypy/branch/guido-buildtool-web/pypy/tool/build/test/fake.py	(original)
+++ pypy/branch/guido-buildtool-web/pypy/tool/build/test/fake.py	Fri Feb 16 17:23:34 2007
@@ -17,9 +17,10 @@
         pass
 
 class FakeBuildserver(object):
-    def __init__(self, info):
+    def __init__(self, info, compile_info=None):
         self.channel = FakeChannel()
         self.sysinfo = info
+        self.compileinfo = compile_info or {}
         self.busy_on = None
         self.refused = []
         self.hostname = "fake"

Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_build.py
==============================================================================
--- pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_build.py	(original)
+++ pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_build.py	Fri Feb 16 17:23:34 2007
@@ -93,7 +93,10 @@
 svnrev: HEAD
 revrange: 0
 normalized_rev: 1
-"""
+request_time: %s
+build_start_time: None
+build_end_time: None
+""" % (br.request_time,)
     assert build.BuildRequest.fromstring(ser).serialize() == ser
 
     py.test.raises(SyntaxError, 'build.BuildRequest.fromstring("foo")')

Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_metaserver.py
==============================================================================
--- pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_metaserver.py	(original)
+++ pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_metaserver.py	Fri Feb 16 17:23:34 2007
@@ -13,10 +13,11 @@
                        mailhost=None)
     mod.svr = metaserver.MetaServer(config, FakeChannel())
     
-    mod.c1 = FakeBuildserver({'foo': 1, 'bar': [1,2]})
+    mod.c1 = FakeBuildserver({'foo': 1, 'bar': [1,2]}, {'spam': ['spam',
+                                                                 'eggs']})
     mod.svr.register(mod.c1)
 
-    mod.c2 = FakeBuildserver({'foo': 2, 'bar': [2,3]})
+    mod.c2 = FakeBuildserver({'foo': 2, 'bar': [2,3]}, {'spam': 'eggs'})
     mod.svr.register(mod.c2)
 
 def test_server_issubdict():
@@ -39,6 +40,7 @@
     assert svr._builders[0] == c1
     assert svr._builders[1] == c2
 
+
     py.test.raises(IndexError, "c1.channel.receive()")
 
     assert svr._channel.receive().find('registered') > -1
@@ -158,7 +160,6 @@
     assert bp2.check()
 
 def test_status():
-    return
     temppath = py.test.ensuretemp('test_status')
     config = Container(projectname='test', buildpath=temppath)
     svr = metaserver.MetaServer(config, FakeChannel())
@@ -170,10 +171,24 @@
     bs = FakeBuildserver({})
     bs.busy_on = 'foo'
     svr._builders.append(bs)
+    print svr.status()
     assert svr.status() == {
         'done': 2,
         'queued': 3,
-        'waiting': 0,
-        'in_progress': 1,
+        'waiting': 1,
+        'running': 1,
+        'builders': 1,
     }
 
+def test_buildersinfo():
+    bi = svr.buildersinfo()
+    assert len(bi) == 2
+    assert bi[0]['sysinfo'] == {'foo': 1, 'bar': [1,2]}
+    assert bi[0]['busy_on'] == None
+    assert bi[1]['sysinfo'] == {'foo': 2, 'bar': [2,3]}
+    svr._builders[0].busy_on = c1
+    bi = svr.buildersinfo()
+    assert bi[0]['busy_on']
+    # for now, later more info should be made available
+    assert bi[0]['busy_on'] == c1.compileinfo
+

Added: pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_webapp.py
==============================================================================
--- (empty file)
+++ pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_webapp.py	Fri Feb 16 17:23:34 2007
@@ -0,0 +1,148 @@
+import py
+from py.__.test.web.webcheck import check_html
+from pypy.tool.build.webapp import *
+from pypy.tool.build.conftest import option
+from pypy.tool.build.test import fake
+from pypy.tool.build import config as build_config
+
+TESTPORT = build_config.testport
+
+here = py.magic.autopath().dirpath()
+pypyparent = here.dirpath().dirpath().dirpath().dirpath()
+
+def html_validate(html):
+    if not option.webcheck:
+        py.test.skip('Skipping XHTML validation (rest of the test passed)')
+    check_html(html)
+
+class TestTemplate(object):
+    def test_render(self):
+        # XXX stupid test ;) but perhaps we're going to add features later or
+        # something...
+        s = py.std.StringIO.StringIO('<foo>%(foo)s</foo>')
+        s.seek(0)
+        t = Template(s)
+        assert t.render({'foo': 'bar'}) == '<foo>bar</foo>'
+
+class FakeMetaServer(object):
+    def __init__(self):
+        self._status = {}
+        self._builders = []
+
+    def status(self):
+        return self._status
+
+    def buildersinfo(self):
+        return self._builders
+
+_metaserver_init = """
+    import sys
+    sys.path += %r
+
+    from pypy.tool.build.test.test_webapp import FakeMetaServer
+    from pypy.tool import build
+    build.metaserver_instance = s = FakeMetaServer()
+    try:
+        while 1:
+            command = channel.receive()
+            if command == 'quit':
+                break
+            command, data = command
+            if command == 'set_status':
+                s._status = data
+            elif command == 'set_buildersinfo':
+                s._builders = data
+    finally:
+        channel.close()
+"""
+
+def init_fake_metaserver(port, path):
+    gw = py.execnet.PopenGateway()
+    conference = execnetconference.conference(gw, port, True)
+    channel = conference.remote_exec(_metaserver_init % (path,))
+    return channel
+
+def setup_module(mod):
+    mod.path = path = pypyparent.strpath
+    mod.server_channel = init_fake_metaserver(TESTPORT, path)
+    mod.config = fake.Container(port=TESTPORT, path=path)
+    mod.gateway = py.execnet.PopenGateway()
+
+def teardown_module(mod):
+    mod.server_channel.send('quit')
+    mod.gateway.exit()
+
+class TestIndexPage(object):
+    def test_handle(self):
+        p = IndexPage()
+        headers, html = p.handle(None, '/', '')
+        assert headers == {'Content-Type': 'text/html; charset=UTF-8'}
+        assert html.strip().startswith('<!DOCTYPE html')
+        assert html.strip().endswith('</html>')
+        html_validate(html)
+
+class TestServerStatusPage(object):
+    def test_get_status(self):
+        p = ServerStatusPage(config, gateway)
+        assert p.get_status() == {}
+        server_channel.send(('set_status', {'foo': 'bar'}))
+        assert p.get_status() == {'foo': 'bar'}
+
+    def test_handle(self):
+        server_channel.send(('set_status', {'builders': 3, 'running': 2,
+                                            'done': 7, 'waiting': 5,
+                                            'queued': 2}))
+        p = ServerStatusPage(config, gateway)
+        headers, html = p.handle(None, '/serverstatus', '')
+        assert headers == {'Content-Type': 'text/html; charset=UTF-8'}
+        assert html.strip().startswith('<!DOCTYPE html')
+        assert html.strip().endswith('</html>')
+        html_validate(html)
+
+class TestBuilderInfoPage(object):
+    def test_get_builderinfo(self):
+        p = BuildersInfoPage(config, gateway)
+        assert p.get_buildersinfo() == []
+        server_channel.send(('set_buildersinfo', [{'foo': 'bar'}]))
+        assert p.get_buildersinfo() == [{'foo': 'bar'}]
+
+    def test_handle(self):
+        server_channel.send(('set_buildersinfo', [{'hostname': 'host1',
+                                                   'sysinfo': {'foo': 'bar'},
+                                                   'busy_on': None},
+                                                  {'hostname': 'host2',
+                                                   'sysinfo': {'foo': 'baz'},
+                                                   'busy_on': {'spam': 'eggs'},
+                                                   }]))
+        p = BuildersInfoPage(config, gateway)
+        headers, html = p.handle(None, '/buildersinfo', '')
+        assert headers == {'Content-Type': 'text/html; charset=UTF-8'}
+        assert html.strip().startswith('<!DOCTYPE html')
+        assert html.strip().endswith('</html>')
+        html_validate(html)
+
+class TestBuildPage(object):
+    def test_handle(self):
+        pass
+
+class TestBuildCollectionIndexPage(object):
+    def test_get_builds(self):
+        pass
+
+    def test_handle(self):
+        p = BuildCollectionIndexPage(config, gateway)
+        headers, html = p.handle(None, '/builds/', '')
+        assert headers == {'Content-Type': 'text/html; charset=UTF-8'}
+        assert html.strip().startswith('<!DOCTYPE html')
+        assert html.strip().endswith('</html>')
+        html_validate(html)
+
+class TestBuildCollection(object):
+    def test_traverse(self):
+        p = BuildCollection(config, gateway)
+        assert p.traverse(['index'], '/builds/index') is p.index
+        assert p.traverse([''], '/builds/') is p.index
+        assert isinstance(p.traverse(['foo'], '/builds/foo'), BuildPage)
+        py.test.raises(HTTPError,
+                       "p.traverse(['foo', 'bar'], '/builds/foo/bar')")
+

Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/webapp.py
==============================================================================
--- pypy/branch/guido-buildtool-web/pypy/tool/build/webapp.py	(original)
+++ pypy/branch/guido-buildtool-web/pypy/tool/build/webapp.py	Fri Feb 16 17:23:34 2007
@@ -10,6 +10,11 @@
 mypath = py.magic.autopath().dirpath()
 
 class Template(object):
+    """ very stupid template class
+
+        does nothing more than string interpolation, no loop constructs or
+        other fancyness: you will have to do that yourself
+    """
     def __init__(self, path):
         self.template = path.read()
         
@@ -20,55 +25,131 @@
     """ the index page """
     def handle(self, handler, path, query):
         template = Template(mypath.join('templates/index.html'))
-        return {'Content-Type': 'text/html'}, template.render({})
+        return ({'Content-Type': 'text/html; charset=UTF-8'},
+                template.render({}))
 
-class ServerStatus(Resource):
-    """ a page displaying overall meta server statistics """
+class ServerPage(Resource):
+    """ base class for pages that communicate with the server
+    """
+
+    def __init__(self, config, gateway=None):
+        self.config = config
+        self.gateway = gateway or self.init_gateway()
 
     remote_code = """
         import sys
         sys.path += %r
 
-        try:
-            from pypy.tool.build import metaserver_instance
-            ret = metaserver_instance.status()
-            channel.send(ret)
-            channel.close()
-        except:
-            import sys, traceback
-            exc, e, tb = sys.exc_info()
-            channel.send(str(exc) + ' - ' + str(e))
-            for line in traceback.format_tb(tb):
-                channel.send(line[:-1])
-            del tb
+        from pypy.tool.build import metaserver_instance
+        ret = metaserver_instance.%s(%s)
+        channel.send(ret)
+        channel.close()
     """
 
+    def call_method(self, methodname, args=''):
+        """ calls a method on the server
+        
+            methodname is the name of the method to call, args is a string
+            which is _interpolated_ into the method call (so if you want to
+            pass the integers 1 and 2 as arguments, 'args' will become '1, 2')
+        """
+        conference = execnetconference.conference(self.gateway,
+                                                  self.config.port, False)
+        channel = conference.remote_exec(self.remote_code % (self.config.path,
+                                                             methodname,
+                                                             args))
+        ret = channel.receive()
+        channel.close()
+        return ret
+
+    def init_gateway(self):
+        if self.config.server in ['localhost', '127.0.0.1']:
+            gw = py.execnet.PopenGateway()
+        else:
+            gw = py.execnet.SshGateway(self.config.server)
+        return gw
+
+class ServerStatusPage(ServerPage):
+    """ a page displaying overall meta server statistics """
+
     def handle(self, handler, path, query):
         template = Template(mypath.join('templates/serverstatus.html'))
         return ({'Content-Type': 'text/html; charset=UTF-8'},
                 template.render(self.get_status()))
 
     def get_status(self):
-        if config.server in ['localhost', '127.0.0.1']:
-            gw = py.execnet.PopenGateway()
-        else:
-            gw = py.execnet.SshGateway(config.server)
+        return self.call_method('status')
 
-        conference = execnetconference.conference(gw, config.port, False)
-        channel = conference.remote_exec(self.remote_code % (config.path,))
-        ret = channel.receive()
-        channel.close()
-        return ret
+class BuildersInfoPage(ServerPage):
+    def handle(self, handler, path, query):
+        template = Template(mypath.join('templates/buildersinfo.html'))
+        context = {
+            'builders': '\n'.join([self.get_builder_html(b)
+                                   for b in self.get_buildersinfo()])
+        }
+        return ({'Content-Type': 'text/html; charset=UTF-8'},
+                template.render(context))
+
+    def get_buildersinfo(self):
+        return self.call_method('buildersinfo')
+
+    def get_builder_html(self, buildinfo):
+        template = Template(mypath.join('templates/builderinfo.html'))
+        return template.render(buildinfo)
+
+class BuildPage(ServerPage):
+    """ display information for one build """
+
+    def __init__(self, buildid, config, gateway=None):
+        super(BuildPage, self).__init__(config, gateway)
+        self._buildid = buildid
+
+    def handle(self, handler, path, query):
+        pass
+
+class BuildCollectionIndexPage(ServerPage):
+    """ display the list of available builds """
+
+    def handle(self, handler, path, query):
+        template = Template(mypath.join('templates/builds.html'))
+        context = {'builds': '\n'.join([self.get_build_html(b) for b in
+                                        self.get_builds()])}
+        return ({'Content-Type': 'text/html; charset=UTF-8'},
+                template.render(context))
+
+    def get_builds(self):
+        return []
+
+class BuildCollection(Collection):
+    """ container for BuildCollectionIndexPage and BuildPage """
+
+    def __init__(self, config, gateway=None):
+        self.index = BuildCollectionIndexPage(config, gateway)
+        self.config = config
+        self.gateway = gateway
+    
+    def traverse(self, path, orgpath):
+        """ generate a BuildPage on the fly """
+        # next element of the path is the id of the build '/<collection>/<id>'
+        name = path.pop()
+        if name in ['', 'index']:
+            return self.index
+        if len(path):
+            # no Collection type children here...
+            raise HTTPError(404)
+        # we have a name for a build, let's build a page for it (if it can't
+        # be found, this page will raise an exception)
+        return BuildPage(name, self.config, self.gateway)
 
 class Application(Collection):
     """ the application root """
     index = IndexPage()
-    serverstatus = ServerStatus()
-    foo = Collection()
-    foo.index = IndexPage()
+    serverstatus = ServerStatusPage(config)
+    buildersinfo = BuildersInfoPage(config)
+    builds = BuildCollection(config)
 
 class AppHandler(Handler):
-    application = Application() # shared by all instances!
+    application = Application()
 
 if __name__ == '__main__':
     from pypy.tool.build.webserver import run_server

Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/webserver.py
==============================================================================
--- pypy/branch/guido-buildtool-web/pypy/tool/build/webserver.py	(original)
+++ pypy/branch/guido-buildtool-web/pypy/tool/build/webserver.py	Fri Feb 16 17:23:34 2007
@@ -96,6 +96,9 @@
             return resource
 
 class Handler(BaseHTTPRequestHandler):
+    """ BaseHTTPRequestHandler that does object publishing
+    """
+
     application = None # attach web root (Collection object) here!!
     bufsize = 1024
     
@@ -143,6 +146,8 @@
         return self.application.traverse(chunks, path)
 
     def process_http_error(self, e):
+        """ create the response body and headers for errors
+        """
         headers = {'Content-Type': 'text/plain'} # XXX need more headers here?
         if e.status in [301, 302]:
             headers['Location'] = e.data
@@ -152,6 +157,8 @@
         return headers, body
     
     def response(self, status, headers, body):
+        """ generate the HTTP response and send it to the client
+        """
         self.send_response(status)
         if (isinstance(body, str) and
                 not 'content-length' in [k.lower() for k in headers]):
@@ -171,6 +178,8 @@
             raise ValueError('body is not a plain string or file-like object')
 
 def run_server(address, handler):
+    """ run a BaseHTTPServer instance
+    """
     server = HTTPServer(address, handler)
     server.serve_forever()
 



More information about the Pypy-commit mailing list