[Zope-Checkins] CVS: Zope3 - .cvsignore:1.2 README.txt:1.2 principals.zcml.in:1.2 products.zcml.in:1.2 sample_principals.zcml:1.2 site.zcml:1.2 stupid_build.py:1.2 stupid_clean:1.2 test.py:1.2 ut.py:1.2 z3.py:1.2 zpl.py:1.2 zserver.zcml:1.2

Jim Fulton jim@zope.com
Mon, 10 Jun 2002 19:28:37 -0400


Update of /cvs-repository/Zope3
In directory cvs.zope.org:/tmp/cvs-serv17445

Added Files:
	.cvsignore README.txt principals.zcml.in products.zcml.in 
	sample_principals.zcml site.zcml stupid_build.py stupid_clean 
	test.py ut.py z3.py zpl.py zserver.zcml 
Log Message:
Merged Zope-3x-branch into newly forked Zope3 CVS Tree.


=== Zope3/.cvsignore 1.1 => 1.2 ===
+products.zcml
+Data.fs
+Data.fs.*


=== Zope3/README.txt 1.1 => 1.2 ===
+
+  The file provides some basic hints for people developing Zope3
+  software.  There is more developer info in the Zope3 Wiki:
+  http://dev.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/
+  Zope3DeveloperInfo
+
+  That's one URL split over two lines.
+
+Building and running tests
+
+  Zope3 requires Python 2.2
+
+  In the top-level Zope3 directory, you should find a script called
+  stupid_build.py.  Run it to build the extension modules needed by
+  Zope.  Example:
+
+  # cd src/Zope3
+  # python2.2 stupid_build.py
+
+  Zope3 includes unit tests based on the Python unittest module.  If
+  you checkin changes, you should verify that all the tests succeed
+  before you checkin.
+
+  To run all the tests, use the script test.py.
+  # python test.py -v
+
+  Use test.py -h for usage.  The test script can run selected tests,
+  stop after the first error, run the tests in a loop, etc.


=== Zope3/principals.zcml.in 1.1 => 1.2 ===
+   xmlns='http://namespaces.zope.org/zope'
+   xmlns:security='http://namespaces.zope.org/security'
+   xmlns:zmi='http://namespaces.zope.org/zmi'
+   xmlns:browser='http://namespaces.zope.org/browser'
+>
+
+<security:defaultPrincipal id="anybody" title="Unauthenticated User" />
+
+</zopeConfigure>


=== Zope3/products.zcml.in 1.1 => 1.2 ===
+   xmlns='http://namespaces.zope.org/zope'
+   xmlns:security='http://namespaces.zope.org/security'
+   xmlns:zmi='http://namespaces.zope.org/zmi'
+   xmlns:browser='http://namespaces.zope.org/browser'
+>
+<!-- add include directives for products here -->
+</zopeConfigure>


=== Zope3/sample_principals.zcml 1.1 => 1.2 ===
+      Don't simply copy this file to principals.zcml unless you
+      absolutely know it will only be used for development.
+   -->
+<zopeConfigure
+   xmlns='http://namespaces.zope.org/zope'
+   xmlns:security='http://namespaces.zope.org/security'
+   xmlns:zmi='http://namespaces.zope.org/zmi'
+   xmlns:browser='http://namespaces.zope.org/browser'
+>
+
+
+<security:defaultPrincipal id="anybody" 
+                           title="Unauthenticated User" />
+
+<security:principal id="stupid" title="Stupid, replace me"
+                    login="stupid" password="123" />
+<security:principal id="idiot" title="I'm an idiot, replace me"
+                    login="idiot" password="456" />
+
+<security:assignRoleToPrincipal role="Manager" principal="stupid" />
+<security:assignRoleToPrincipal role="Member"  principal="idiot" />
+
+</zopeConfigure>


=== Zope3/site.zcml 1.1 => 1.2 ===
+   xmlns='http://namespaces.zope.org/zope'
+   xmlns:security='http://namespaces.zope.org/security'
+>
+
+<include package="Zope" file="zope.zcml" />
+
+<security:role id="Manager" title="Site Manager" />
+<security:role id="Member" title="Site Member" />
+
+<include file="principals.zcml" />
+
+<security:grantPermissionToRole permission="Zope.View" 
+                                role="Manager" />
+<security:grantPermissionToRole permission="Zope.ManageContent"
+                                role="Manager" />
+<security:grantPermissionToRole permission="Zope.Security" 
+                                role="Manager" />
+
+<security:grantPermissionToRole permission="Zope.ManageServices" 
+                                role="Manager" />
+
+<security:grantPermissionToRole permission="Zope.ManageApplication" 
+                                role="Manager" />
+
+<include file="products.zcml" />
+
+</zopeConfigure>


=== Zope3/stupid_build.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+# 
+##############################################################################
+"""
+Really stupid in-place builder for C extensions that are linked in to Zope 3.
+
+usage:
+
+$ cd /path/to/Zope3root
+$ python2.2 stupid_build.py
+
+Usage with a specific compiler such as mingw32:
+
+$ python2.2 stupid_build.py -c mingw32
+
+This module hopefully won't last long enough to need a license. ;-)
+"""
+
+import sys, os
+
+def remove_stale_bytecode(arg, dirname, names):
+    names = map(os.path.normcase, names)
+    for name in names:
+        if name.endswith(".pyc") or name.endswith(".pyo"):
+            srcname = name[:-1]
+            if srcname not in names:
+                fullname = os.path.join(dirname, name)
+                print "Removing stale bytecode file", fullname
+                os.unlink(fullname)
+
+def visit(setup_dirs, dirname, names):
+    remove_stale_bytecode(None, dirname, names)
+    if 'setup.py' in names:
+        setup_dirs.append(dirname)
+
+def main():
+    if (not os.path.exists('products.zcml') and
+        os.path.exists('products.zcml.in')):
+        print 'Copying products.zcml.in to products.zcml'
+        open('products.zcml', 'w').write(open('products.zcml.in').read())
+
+    if not os.path.exists('principals.zcml'):
+        print """WARNING: You need to create principals.zcml
+
+        The file principals.zcml contains your "bootstrap" user
+        database. You aren't going to get very far without it.  Start
+        by copying principals.zcml.in and then look at
+        sample_principals.zcml for some example principal and role
+        settings.
+        """
+
+
+        
+    setup_dirs = []
+    os.path.walk(os.getcwd(), visit, setup_dirs)
+    args = tuple(sys.argv[1:])
+    if not args:
+        args = ('clean',)
+    for dir in setup_dirs:
+        print "Building extensions in %s" % dir
+        os.chdir(dir)
+        os.spawnl(os.P_WAIT, sys.executable,
+                  sys.executable, "setup.py", 'build_ext', '-i', *args)
+        print
+
+if __name__ == "__main__":
+    main()


=== Zope3/stupid_clean 1.1 => 1.2 ===
+
+files=`find -name \*.o -o -name \*.so`
+if [ ! -z "$files" ] ; then
+    rm $files
+fi
+
+


=== Zope3/test.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+# 
+##############################################################################
+"""
+test.py [-bdvvL] [modfilter [testfilter]]
+
+Test harness.
+
+-b  build
+    Run "python setup.py -q build" before running tests, where "python"
+    is the version of python used to run test.py.  Highly recommended.
+
+-d  debug
+    Instead of the normal test harness, run a debug version which
+    doesn't catch any exceptions.  This is occasionally handy when the
+    unittest code catching the exception doesn't work right.
+    Unfortunately, the debug harness doesn't print the name of the
+    test, so Use With Care.
+
+-v  verbose
+    With one -v, unittest prints a dot (".") for each test run.  With
+    -vv, unittest prints the name of each test (for some definition of
+    "name" ...).  Witn no -v, unittest is silent until the end of the
+    run, except when errors occur.
+
+-L  Loop
+    Keep running the selected tests in a loop.  You may experience
+    memory leakage.
+
+-g  threshold
+    Set the garbage collector generation0 threshold.  This can be used to
+    stress memory and gc correctness.  Some crashes are only reproducible when
+    the threshold is set to 1 (agressive garbage collection).  Do "-g 0" to
+    disable garbage collection altogether.
+
+modfilter
+testfilter
+    Case-sensitive regexps to limit which tests are run, used in search
+    (not match) mode.
+    In an extension of Python regexp notation, a leading "!" is stripped
+    and causes the sense of the remaining regexp to be negated (so "!bc"
+    matches any string that does not match "bc", and vice versa).
+    By default these act like ".", i.e. nothing is excluded.
+
+    modfilter is applied to a test file's path, starting at "build" and
+    including (OS-dependent) path separators.
+
+    testfilter is applied to the (method) name of the unittest methods
+    contained in the test files whose paths modfilter matched.
+
+Extreme (yet useful) examples:
+
+    test.py -vvb . "^checkWriteClient$"
+
+    Builds the project silently, then runs unittest in verbose mode on all
+    tests whose names are precisely "checkWriteClient".  Useful when
+    debugging a specific test.
+
+    test.py -vvb . "!^checkWriteClient$"
+
+    As before, but runs all tests whose names aren't precisely
+    "checkWriteClient".  Useful to avoid a specific failing test you don't
+    want to deal with just yet.
+"""
+
+import os
+import re
+import sys
+import traceback
+import unittest
+from os.path import join
+
+from distutils.util import get_platform
+
+# We know we're going to need this so import it now.  Python 2.2 does not come
+# with the pyexpat library by default, although Python 2.3 will.
+try:
+    import pyexpat
+except ImportError:
+    print >> sys.stderr, "WARNING: the pyexpat module is required"
+    raise
+
+class ImmediateTestResult(unittest._TextTestResult):
+
+    __super_init = unittest._TextTestResult.__init__
+
+    def __init__(self, *args, **kwarg):
+        debug = kwarg.get('debug')
+        if debug is not None:
+            del kwarg['debug']
+        self.__super_init(*args, **kwarg)
+        self._debug = debug
+        
+    def _print_traceback(self, msg, err, test, errlist):
+        if self.showAll or self.dots:
+            self.stream.writeln("\n")
+
+        tb = ''.join(traceback.format_exception(*err))
+        self.stream.writeln(msg)
+        self.stream.writeln(tb)
+        errlist.append((test, tb))
+
+    def addError(self, test, err):
+        if self._debug:
+            raise err[0], err[1], err[2]
+        self._print_traceback("Error in test %s" % test, err,
+                              test, self.errors)
+
+    def addFailure(self, test, err):
+        if self._debug:
+            raise err[0], err[1], err[2]
+        self._print_traceback("Failure in test %s" % test, err,
+                              test, self.failures)
+
+    def printErrorList(self, flavor, errors):
+        for test, err in errors:
+            self.stream.writeln(self.separator1)
+            self.stream.writeln("%s: %s" % (flavor, self.getDescription(test)))
+            self.stream.writeln(self.separator2)
+            self.stream.writeln(err)
+
+class ImmediateTestRunner(unittest.TextTestRunner):
+
+    __super_init = unittest.TextTestRunner.__init__
+
+    def __init__(self, **kwarg):
+        debug = kwarg.get('debug')
+        if debug is not None:
+            del kwarg['debug']
+        self.__super_init(**kwarg)
+        self._debug = debug
+
+    def _makeResult(self):
+        return ImmediateTestResult(self.stream, self.descriptions,
+                                   self.verbosity, debug=self._debug)
+
+# setup list of directories to put on the path
+
+def setup_path():
+    DIRS = [join('lib','python'),
+            ]
+    cwd = os.getcwd()
+    for d in DIRS:
+        sys.path.insert(0, join(cwd, d))
+
+def match(rx, s):
+    if not rx:
+        return 1
+    if rx[0] == '!':
+        return re.search(rx[1:], s) is None
+    else:
+        return re.search(rx, s) is not None
+
+class TestFileFinder:
+    def __init__(self):
+        self.files = []
+
+    def visit(self, rx, dir, files):
+        if dir[-5:] != "tests":
+            return
+        # ignore tests in ZopeLegacy directory
+        if dir.startswith(join('lib','python','ZopeLegacy')):
+            return
+        # ignore tests that aren't in packages
+        if not "__init__.py" in files:
+            print "not a package", dir
+            return
+        for file in files:
+            if file[:4] == "test" and file[-3:] == ".py":
+                path = join(dir, file)
+                if match(rx, path):
+                    self.files.append(path)
+
+def find_tests(rx):
+    finder = TestFileFinder()
+    os.path.walk(join('lib','python'), finder.visit, rx)
+    return finder.files
+
+def package_import(modname):
+    mod = __import__(modname)
+    for part in modname.split(".")[1:]:
+        mod = getattr(mod, part)
+    return mod
+
+def module_from_path(path):
+    """Return the Python package name indiciated by the filesystem path."""
+
+    assert path.endswith('.py')
+    path = path[:-3]
+    dirs = []
+    while path:
+        path, end = os.path.split(path)
+        dirs.insert(0, end)
+    return ".".join(dirs[2:])
+
+def get_suite(file):
+    modname = module_from_path(file)
+    try:
+        mod = package_import(modname)
+    except ImportError, err:
+        # print traceback
+        print "Error importing %s\n%s" % (modname, err)
+        if debug:
+            raise
+        return None
+    try:
+        suite_func = mod.test_suite
+    except AttributeError:
+        print "No test_suite() in %s" % file
+        return None
+    return suite_func()
+
+def filter_testcases(s, rx):
+    new = unittest.TestSuite()
+    for test in s._tests:
+        if isinstance(test, unittest.TestCase):
+            name = test.id() # Full test name: package.module.class.method
+            name = name[1 + name.rfind('.'):] # extract method name
+            if match(rx, name):
+                new.addTest(test)
+        else:
+            filtered = filter_testcases(test, rx)
+            if filtered:
+                new.addTest(filtered)
+    return new
+
+def runner(files, test_filter, debug):
+    runner = ImmediateTestRunner(verbosity=VERBOSE, debug=debug)
+    suite = unittest.TestSuite()
+    for file in files:
+        s = get_suite(file)
+        if s is not None:
+            if test_filter is not None:
+                s = filter_testcases(s, test_filter)
+            suite.addTest(s)
+    r = runner.run(suite)
+
+def remove_stale_bytecode(arg, dirname, names):
+    names = map(os.path.normcase, names)
+    for name in names:
+        if name.endswith(".pyc") or name.endswith(".pyo"):
+            srcname = name[:-1]
+            if srcname not in names:
+                fullname = os.path.join(dirname, name)
+                print "Removing stale bytecode file", fullname
+                os.unlink(fullname)
+
+def main(module_filter, test_filter):
+    os.path.walk(os.curdir, remove_stale_bytecode, None)
+    setup_path()
+    files = find_tests(module_filter)
+    files.sort()
+
+    if LOOP:
+        while 1:
+            runner(files, test_filter, debug)
+    else:
+        runner(files, test_filter, debug)
+
+
+def process_args():
+    import getopt
+    global module_filter
+    global test_filter
+    global VERBOSE
+    global LOOP
+    global debug
+    global build
+    global gcthresh
+
+    module_filter = None
+    test_filter = None
+    VERBOSE = 0
+    LOOP = 0
+    debug = 0 # Don't collect test results; simply let tests crash
+    build = 0
+    gcthresh = None
+
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], 'vdLbhCg:',
+                                   ['help'])
+    except getopt.error, msg:
+        print msg
+        print "Try `python %s -h' for more information." % sys.argv[0]
+        sys.exit(2)
+
+    for k, v in opts:
+        if k == '-v':
+            VERBOSE += 1
+        elif k == '-d':
+            debug = 1
+        elif k == '-L':
+            LOOP = 1
+        elif k == '-b':
+            build = 1
+        elif k in ('-h', '--help'):
+            print __doc__
+            sys.exit(0)
+        elif k == '-C':
+            import pychecker.checker
+        elif k == '-g':
+            gcthresh = int(v)
+
+    if gcthresh is not None:
+        import gc
+        gc.set_threshold(gcthresh)
+        print 'gc threshold:', gc.get_threshold()
+
+    if build:
+        cmd = sys.executable + " stupid_build.py"
+        if VERBOSE:
+            print cmd
+        sts = os.system(cmd)
+        if sts:
+            print "Build failed", hex(sts)
+            sys.exit(1)
+
+    if args:
+        if len(args) > 1:
+            test_filter = args[1]
+        module_filter = args[0]
+    try:
+        bad = main(module_filter, test_filter)
+        if bad:
+            sys.exit(1)
+    except ImportError, err:
+        print err
+        print sys.path
+        raise
+
+
+if __name__ == "__main__":
+    process_args()


=== Zope3/ut.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""XXX short summary goes here.
+
+XXX longer description goes here.
+
+$Id$
+"""
+
+from unittest import TestCase, TestSuite, main, makeSuite
+
+#############################################################################
+# If your tests change any global registries, then uncomment the
+# following import and include CleanUp as a base class of your
+# test. It provides a setUp and tearDown that clear global data that
+# has registered with the test cleanup framework.  Don't use this
+# tests outside the Zope package.
+
+# from Zope.Testing.CleanUp import CleanUp # Base class w registry cleanup
+
+#############################################################################
+
+class Test(TestCase):
+    pass
+
+def test_suite():
+    return TestSuite((
+        makeSuite(Test),
+        ))
+
+if __name__=='__main__':
+    main(defaultTest='test_suite')


=== Zope3/z3.py 1.1 => 1.2 ===
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+# 
+##############################################################################
+"""
+
+$Id$
+"""
+
+import os, sys, asyncore
+
+basepath = filter(None, sys.path)
+
+def run(argv=sys.argv):
+
+    # setting python paths
+    program = argv[0]
+    here = os.path.join(os.getcwd(), os.path.split(program)[0])
+    libpython = os.path.join(here,'lib','python') 
+    sys.path=[libpython, here] + basepath
+
+    # temp hack
+    dir = os.getcwd()
+
+    from Zope.Configuration.xmlconfig import XMLConfig
+
+    # Load server-independent site config
+    XMLConfig(os.path.join(dir, 'site.zcml'))()
+    
+    # Load server config
+    XMLConfig(os.path.join(dir, 'zserver.zcml'))()
+
+    try:
+        asyncore.loop()
+    except KeyboardInterrupt:
+        # Exit without spewing an exception.
+        pass
+    sys.exit(0)
+
+
+if __name__ == '__main__':
+    run()
+    


=== Zope3/zpl.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+# 
+##############################################################################
+"""XXX short summary goes here.
+
+XXX longer description goes here.
+
+$Id$
+"""


=== Zope3/zserver.zcml 1.1 => 1.2 ===
+   xmlns="http://namespaces.zope.org/zope"
+   xmlns:startup="http://namespaces.zope.org/startup">
+
+  <!-- Define a specific site. The name of the site is used for server
+       messages only. The number of threads specifies the number of
+       threads the server should maximally use. -->
+
+  <startup:defineSite name="Zope 3 Default"
+                      threads="4">
+
+    <!-- You can choose between several storages.
+
+         At the moment only two storages are supported:
+             FileStorage - Saves data in a specified file
+             MappingStorage - Saves data in a dictionary. No saving. -->
+
+    <startup:useFileStorage file = "Data.fs" />
+    <!--startup:useMappingStorage /-->
+
+
+    <!-- Setup the log file.
+
+         There are two special file names:
+             STDERR - sends output to standard error
+             STDOUT - sends output to standard output -->
+
+    <startup:useLog file="STDERR" />
+
+
+    <!-- Now define the servers you would like to start. All you need
+    to specify is the server type. Both, the port and verbose option,
+    are optional.
+
+    The following types are currently available: 
+        Browser - A standard HTML/XUL server
+        XML-RPC - An XML-RPC server, for calling objects remotely
+        FTP - A server to access the ZODB via the FTP protocol
+    Soon:
+        SOAP - An SOAP server for Zope based on ZSI
+
+    The 'port' option specifies the port the server should run on of course.
+
+    The 'verbose' option specifies whether any logs should be written. If
+    set to false, nothing is reported. -->
+
+    <startup:addServer type = "Browser" port = "8080" />
+    <startup:addServer type = "XML-RPC" port = "8081" verbose="true" />
+    <startup:addServer type = "FTP" port = "8021" />
+
+
+  </startup:defineSite>
+
+
+</zopeConfigure>