[Zope3-checkins] SVN: Zope3/branches/ZopeX3-3.0/src/zope/ Backport of the following revisions:

Stephan Richter srichter at cosmos.phy.tufts.edu
Thu Aug 12 11:45:45 EDT 2004


Log message for revision 27052:
  Backport of the following revisions:
  ------------------------------------------------------------------------
  r26400 | srichter | 2004-07-10 10:30:52 -0400 (Sat, 10 Jul 2004) | 5 
  lines
  
  Don't make the query/getResource function depend on the context. This is
  done via the global site now. However, we still need to pass in the site
  to which the resource belongs, so that we can set the parent of it,
  which is important for the absolute URL to work.
  
  ------------------------------------------------------------------------
  
  ------------------------------------------------------------------------
  r26401 | srichter | 2004-07-10 10:31:29 -0400 (Sat, 10 Jul 2004) | 2 
  lines
  
  Cleanup whitespace.
  
  ------------------------------------------------------------------------
  
  ------------------------------------------------------------------------
  r26402 | srichter | 2004-07-10 10:32:18 -0400 (Sat, 10 Jul 2004) | 2 
  lines
  
  Converted XXX to TODO and statement. Added explanatory comment.
  
  ------------------------------------------------------------------------
  
  ------------------------------------------------------------------------
  r26403 | srichter | 2004-07-10 10:36:36 -0400 (Sat, 10 Jul 2004) | 2 
  lines
  
  Gave module menaingful doc.
  
  ------------------------------------------------------------------------
  
  ------------------------------------------------------------------------
  r26404 | srichter | 2004-07-10 10:44:16 -0400 (Sat, 10 Jul 2004) | 3 
  lines
  
  Fixed XXX by doing the right thing and allow option interfaces argument
  to the Factory constructor.
  
  ------------------------------------------------------------------------
  
  ------------------------------------------------------------------------
  r26405 | srichter | 2004-07-10 10:45:36 -0400 (Sat, 10 Jul 2004) | 7 
  lines
  
  Changed XXX to TODO.
  
  Removed a lot of the backward-compatibility code, which got rid of
  several XXX.
  
  zope.component is now clean.
  
  ------------------------------------------------------------------------
  
  ------------------------------------------------------------------------
  r26406 | srichter | 2004-07-10 10:58:53 -0400 (Sat, 10 Jul 2004) | 5 
  lines
  
  Removed all XXX.
  
  Removed backward-compat of zopeConfigure.
  
  
  ------------------------------------------------------------------------
  
  
  


Changed:
  U   Zope3/branches/ZopeX3-3.0/src/zope/app/form/browser/complexsample/vocabulary.py
  U   Zope3/branches/ZopeX3-3.0/src/zope/app/publisher/browser/icon.py
  U   Zope3/branches/ZopeX3-3.0/src/zope/app/traversing/namespace.py
  U   Zope3/branches/ZopeX3-3.0/src/zope/cachedescriptors/tests/test_property.py
  U   Zope3/branches/ZopeX3-3.0/src/zope/component/__init__.py
  U   Zope3/branches/ZopeX3-3.0/src/zope/component/factory.py
  U   Zope3/branches/ZopeX3-3.0/src/zope/component/interfaces.py
  U   Zope3/branches/ZopeX3-3.0/src/zope/component/tests/test_api.py
  U   Zope3/branches/ZopeX3-3.0/src/zope/component/tests/test_factory.py
  U   Zope3/branches/ZopeX3-3.0/src/zope/configuration/tests/test_backward.py
  U   Zope3/branches/ZopeX3-3.0/src/zope/configuration/tests/test_config.py
  U   Zope3/branches/ZopeX3-3.0/src/zope/configuration/tests/test_docutils.py
  U   Zope3/branches/ZopeX3-3.0/src/zope/configuration/tests/test_xmlconfig.py
  U   Zope3/branches/ZopeX3-3.0/src/zope/configuration/xmlconfig.py
  U   Zope3/branches/ZopeX3-3.0/src/zope/dependencytool/finddeps.py


-=-
Modified: Zope3/branches/ZopeX3-3.0/src/zope/app/form/browser/complexsample/vocabulary.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/app/form/browser/complexsample/vocabulary.py	2004-08-12 14:56:23 UTC (rev 27051)
+++ Zope3/branches/ZopeX3-3.0/src/zope/app/form/browser/complexsample/vocabulary.py	2004-08-12 15:45:44 UTC (rev 27052)
@@ -11,7 +11,6 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-
 """Sample vocabularies for use with the complexsample widgets.
 
 $Id$

Modified: Zope3/branches/ZopeX3-3.0/src/zope/app/publisher/browser/icon.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/app/publisher/browser/icon.py	2004-08-12 14:56:23 UTC (rev 27051)
+++ Zope3/branches/ZopeX3-3.0/src/zope/app/publisher/browser/icon.py	2004-08-12 15:45:44 UTC (rev 27052)
@@ -13,17 +13,15 @@
 ##############################################################################
 """Icon support
 
-
 $Id$
 """
-
 import os
 import re
 
 from zope.app import zapi
 from zope.app.component.metaconfigure import handler
 from zope.app.publisher.browser import metaconfigure
-from zope.app.traversing.namespace import getResourceInContext
+from zope.app.traversing.namespace import getResource
 from zope.publisher.interfaces.browser import IBrowserRequest
 from zope.configuration.exceptions import ConfigurationError
 from zope.app.component.interface import provideInterface
@@ -41,14 +39,16 @@
         self.alt = alt
 
     def __call__(self):
-        resource = getResourceInContext(self.context, self.rname, self.request)
+        # The context is important here, since it becomes the parent of the
+        # icon, which is needed to generate the absolute URL.
+        resource = getResource(self.context, self.rname, self.request)
         src = resource()
 
         return ('<img src="%s" alt="%s" width="16" height="16" border="0" />'
                 % (src, self.alt))
 
     def url(self):
-        resource = getResourceInContext(self.context, self.rname, self.request)
+        resource = getResource(self.context, self.rname, self.request)
         src = resource()
         return src
 

Modified: Zope3/branches/ZopeX3-3.0/src/zope/app/traversing/namespace.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/app/traversing/namespace.py	2004-08-12 14:56:23 UTC (rev 27051)
+++ Zope3/branches/ZopeX3-3.0/src/zope/app/traversing/namespace.py	2004-08-12 15:45:44 UTC (rev 27052)
@@ -20,6 +20,7 @@
 from zope import component
 from zope.component.servicenames import Presentation
 from zope.exceptions import NotFoundError
+
 from zope.app.traversing.interfaces import ITraversable, IPathAdapter
 from zope.proxy import removeAllProxies
 
@@ -151,15 +152,14 @@
 
     return ns, name
 
-def getResourceInContext(ob, name, request):
-    resource = queryResourceInContext(ob, name, request)
+def getResource(site, name, request):
+    resource = queryResource(site, name, request)
     if resource is None:
-        raise NotFoundError(ob, name)
+        raise NotFoundError(site, name)
     return resource
 
-def queryResourceInContext(ob, name, request, default=None):
-    resource_service = component.getService(Presentation, ob)
-    resource = resource_service.queryResource(name, request)
+def queryResource(site, name, request, default=None):
+    resource = component.queryResource(name, request)
     if resource is None:
         return default
 
@@ -167,12 +167,11 @@
     # resource to do this.  we will still return the proxied resource.
     r = removeAllProxies(resource)
 
-    r.__parent__ = ob
+    r.__parent__ = site
     r.__name__ = name
 
     return resource
 
-
 # ---- namespace processors below ----
 
 class SimpleHandler(object):
@@ -341,12 +340,10 @@
 class resource(view):
 
     def traverse(self, name, ignored):
-        resource = queryResourceInContext(self.context, name, self.request)
-        if resource is None:
-            raise NotFoundError(self.context, name)
+        # The context is important here, since it becomes the parent of the
+        # resource, which is needed to generate the absolute URL.
+        return getResource(self.context, name, self.request)
 
-        return resource
-
 class skin(view):
 
     def traverse(self, name, ignored):

Modified: Zope3/branches/ZopeX3-3.0/src/zope/cachedescriptors/tests/test_property.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/cachedescriptors/tests/test_property.py	2004-08-12 14:56:23 UTC (rev 27051)
+++ Zope3/branches/ZopeX3-3.0/src/zope/cachedescriptors/tests/test_property.py	2004-08-12 15:45:44 UTC (rev 27052)
@@ -11,10 +11,8 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-"""XXX short summary goes here.
+"""Test caching of properties.
 
-XXX longer description goes here.
-
 $Id$
 """
 __metaclass__ = type

Modified: Zope3/branches/ZopeX3-3.0/src/zope/component/__init__.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/component/__init__.py	2004-08-12 14:56:23 UTC (rev 27051)
+++ Zope3/branches/ZopeX3-3.0/src/zope/component/__init__.py	2004-08-12 15:45:44 UTC (rev 27052)
@@ -51,38 +51,17 @@
 def getGlobalService(name):
     return serviceManager.getService(name)
 
-def getServiceManager(context):
-    # Backwards compatibility stub
-    warnings.warn("getServiceManager(context) is  deprecated,"
-                  " use getServices(context=None) instead.",
-                  DeprecationWarning, 2)
-    return getServices(context)
-
-
 def getServices(context=None):
     if context is None:
         return serviceManager
     else:
         # Use the global service manager to adapt context to IServiceService
         # to avoid the recursion implied by using a local getAdapter call.
+        try:
+            return IServiceService(context)
+        except TypeError, error:
+            raise ComponentLookupError(*error.args)
 
-        # We should be using the line of code below.
-        ## return IServiceService(context)
-        #
-        # Instead, we need to support code that has passed in an object
-        # as context, at least until the whole component API is fixed up.
-        # XXX try ripping this code out.
-        sm = IServiceService(context, None)
-        if sm is None:
-            # Deprecated support for a context that isn't adaptable to
-            # IServiceService.  Return the default service manager.
-            # warnings.warn("getServices' context arg must be None or"
-            #               "  adaptable to IServiceService.",
-            #               DeprecationWarning, warningLevel())
-            return serviceManager
-        else:
-            return sm
-
 getServices = hookable(getServices)
 
 def getService(name, context=None):
@@ -94,23 +73,9 @@
 # Utility service
 
 def getUtility(interface, name='', context=None):
-    if not isinstance(name, basestring):
-        context, interface, name = interface, name, context
-        if name is None:
-            name = ''
-        warnings.warn("getUtility(context, interface, name) is deprecated."
-                      "  Use getUtility(interface, name, context=context).",
-                      DeprecationWarning, warningLevel())
     return getService(Utilities, context=context).getUtility(interface, name)
 
 def queryUtility(interface, name='', default=None, context=None):
-    ## XXX this check is for migration.  Remove soon.
-    if (not IInterface.providedBy(interface) or
-        not isinstance(name, basestring) or
-        isinstance(default, basestring)):
-        raise TypeError("queryUtility got nonsense arguments."
-                        " Check that you are updated with the"
-                        " component API change.")
     return getService(Utilities, context).queryUtility(
         interface, name, default)
 
@@ -234,29 +199,10 @@
                     yield name, factory
                     break
 
-def getFactory(context, name):
-    warnings.warn(
-        "Use getUtility(IFactory, name, context) instead of getFactory(...)",
-        DeprecationWarning, 2)
-    return getUtility(IFactory, name, context=context)
 
-def queryFactory(context, name, default=None):
-    warnings.warn(
-        "Use getUtility(IFactory, name, context) instead of getFactory(...)",
-        DeprecationWarning, 2)
-    return queryUtility(IFactory, name=name, context=context)
-
-
 # Presentation service
 
 def getView(object, name, request, providing=Interface, context=None):
-    if not IInterface.providedBy(providing):
-        providing, context = context, providing
-        warnings.warn("Use getView(object, name, request,"
-                      " prodiving=Interface, context=Interface)"
-                      " instead of getView(object, name, request,"
-                      " context=None, prodiving=Interface)",
-                      DeprecationWarning, 2)
     view = queryView(object, name, request, context=context,
                      providing=providing)
     if view is not None:
@@ -306,9 +252,6 @@
     return s.queryDefaultViewName(object, request, default)
 
 def getResource(name, request, providing=Interface, context=None):
-    if isinstance(request, basestring):
-        # "Backwards compatibility"
-        raise TypeError("getResource got incorrect arguments.")
     view = queryResource(name, request, providing=providing, context=context)
     if view is not None:
         return view
@@ -317,8 +260,5 @@
 
 def queryResource(name, request, default=None, providing=Interface,
                   context=None):
-    if isinstance(request, basestring):
-        # "Backwards compatibility"
-        raise TypeError("queryResource got incorrect arguments.")
     s = getService(Presentation, context)
     return s.queryResource(name, request, default, providing=providing)

Modified: Zope3/branches/ZopeX3-3.0/src/zope/component/factory.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/component/factory.py	2004-08-12 14:56:23 UTC (rev 27051)
+++ Zope3/branches/ZopeX3-3.0/src/zope/component/factory.py	2004-08-12 15:45:44 UTC (rev 27052)
@@ -16,6 +16,7 @@
 $Id$
 """
 from zope.interface import implements, implementedBy
+from zope.interface.declarations import Implements
 from zope.component.interfaces import IFactory
 
 class Factory(object):
@@ -26,18 +27,23 @@
     """
     implements(IFactory)
 
-    def __init__(self, callable, title='', description=''):
+    def __init__(self, callable, title='', description='', interfaces=None):
         self._callable = callable
         self.title = title
         self.description = description
+        self._interfaces = interfaces
 
     def __call__(self, *args, **kw):
         return self._callable(*args, **kw)
 
     def getInterfaces(self):
+        if self._interfaces is not None:
+            spec = Implements(*self._interfaces)
+            spec.__name__ = getattr(self._callable, '__name__', '[callable]')
+            return spec
         try:
             return implementedBy(self._callable)
         except TypeError:
-            # XXX This is a hack
-            # We really only support classes
-            return implementedBy(object())
+            spec = Implements()
+            spec.__name__ = getattr(self._callable, '__name__', '[callable]')
+            return spec

Modified: Zope3/branches/ZopeX3-3.0/src/zope/component/interfaces.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/component/interfaces.py	2004-08-12 14:56:23 UTC (rev 27051)
+++ Zope3/branches/ZopeX3-3.0/src/zope/component/interfaces.py	2004-08-12 15:45:44 UTC (rev 27052)
@@ -41,9 +41,6 @@
         this adapter is returned.
         """
 
-    def getServiceManager(context):
-        """Backwards compatibility for getServices()"""
-
     def getService(name, context=None):
         """Get a named service.
 
@@ -229,7 +226,8 @@
 
     # Factory service
 
-    # XXX:  Hard to make context a keyword, leaving as it is
+    # TODO: Hard to make context a keyword, leaving as it is. Maybe we should
+    #       at least move it to the second position.
     def createObject(context, name, *args, **kwargs):
         """Create an object using a factory
 
@@ -253,24 +251,6 @@
         create objects which implement the given interface.
         """
 
-    # XXX: This method is deprecated, since factories are utiltities
-    def getFactory(context, name):
-        """Get a factory
-
-        Get the factory of the given name that is nearest to the
-        context.  If a matching factory cannot be found raises
-        ComponentLookupError
-        """
-
-    # XXX: This method is deprecated, since factories are utiltities
-    def queryFactory(context, name, default=None):
-        """Get a factory
-
-        Get the factory of the given name that is nearest to the
-        context.  If a matching factory cannot be found then the
-        default is returned.
-        """
-
     # Presentation service
 
     def getView(object, name, request, providing=Interface, context=None):

Modified: Zope3/branches/ZopeX3-3.0/src/zope/component/tests/test_api.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/component/tests/test_api.py	2004-08-12 14:56:23 UTC (rev 27051)
+++ Zope3/branches/ZopeX3-3.0/src/zope/component/tests/test_api.py	2004-08-12 15:45:44 UTC (rev 27052)
@@ -124,10 +124,9 @@
         context = ConformsToIServiceService(servicemanager)
         self.assert_(getServices(context) is servicemanager)
 
-        # XXX enable this test before checking in
         # Using a context that is not adaptable to IServiceService should
         # fail.
-        ##self.assertRaises(ComponentLookupError, getServices, object())
+        self.assertRaises(ComponentLookupError, getServices, object())
 
     def test_getService(self):
         from zope.component import getService, getServices
@@ -147,11 +146,10 @@
         context = ConformsToIServiceService(servicemanager)
         self.assert_(getService(Adapters, context) is adapterservice)
 
-        # XXX enable this test before checking in
         # Using a context that is not adaptable to IServiceService should
         # fail.
-        ##self.assertRaises(ComponentLookupError,
-        ##                  getService, Adapters, object())
+        self.assertRaises(ComponentLookupError,
+                          getService, Adapters, object())
 
     def testAdapterInContext(self):
         class I1(Interface):

Modified: Zope3/branches/ZopeX3-3.0/src/zope/component/tests/test_factory.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/component/tests/test_factory.py	2004-08-12 14:56:23 UTC (rev 27051)
+++ Zope3/branches/ZopeX3-3.0/src/zope/component/tests/test_factory.py	2004-08-12 15:45:44 UTC (rev 27052)
@@ -25,6 +25,9 @@
 from zope.component.factory import Factory
 from placelesssetup import PlacelessSetup
 
+class IFunction(Interface):
+    pass
+
 class IKlass(Interface):
     pass
 
@@ -41,6 +44,7 @@
     def setUp(self):
         self._factory = Factory(Klass, 'Klass', 'Klassier')
         self._factory2 = Factory(lambda x: x, 'Func', 'Function')
+        self._factory3 = Factory(lambda x: x, 'Func', 'Function', (IFunction,))
 
     def testCall(self):
         kl = self._factory(3, foo=4)
@@ -48,19 +52,32 @@
         self.assertEqual(kl.args, (3, ))
         self.assertEqual(kl.kw, {'foo': 4})
         self.assertEqual(self._factory2(3), 3)
+        self.assertEqual(self._factory3(3), 3)
 
     def testTitleDescription(self):
         self.assertEqual(self._factory.title, 'Klass')
         self.assertEqual(self._factory.description, 'Klassier')
+        self.assertEqual(self._factory2.title, 'Func')
+        self.assertEqual(self._factory2.description, 'Function')
+        self.assertEqual(self._factory3.title, 'Func')
+        self.assertEqual(self._factory3.description, 'Function')
 
     def testGetInterfaces(self):
         implemented = self._factory.getInterfaces()
         self.assert_(implemented.isOrExtends(IKlass))
         self.assertEqual(list(implemented), [IKlass])
+        self.assertEqual(implemented.__name__,
+                         'zope.component.tests.test_factory.Klass')
+
         implemented2 = self._factory2.getInterfaces()
         self.assertEqual(list(implemented2), [])
+        self.assertEqual(implemented2.__name__, '<lambda>')
 
+        implemented3 = self._factory3.getInterfaces()
+        self.assertEqual(list(implemented3), [IFunction])
+        self.assertEqual(implemented3.__name__, '<lambda>')
 
+
 class TestFactoryZAPIFunctions(PlacelessSetup, unittest.TestCase):
 
     def setUp(self):

Modified: Zope3/branches/ZopeX3-3.0/src/zope/configuration/tests/test_backward.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/configuration/tests/test_backward.py	2004-08-12 14:56:23 UTC (rev 27051)
+++ Zope3/branches/ZopeX3-3.0/src/zope/configuration/tests/test_backward.py	2004-08-12 15:45:44 UTC (rev 27052)
@@ -11,7 +11,7 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-"""XXX short summary goes here.
+"""Test backward-compatiblity.
 
 $Id$
 """

Modified: Zope3/branches/ZopeX3-3.0/src/zope/configuration/tests/test_config.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/configuration/tests/test_config.py	2004-08-12 14:56:23 UTC (rev 27051)
+++ Zope3/branches/ZopeX3-3.0/src/zope/configuration/tests/test_config.py	2004-08-12 15:45:44 UTC (rev 27052)
@@ -11,7 +11,7 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-"""XXX short summary goes here.
+"""Test configuration machinery.
 
 $Id$
 """

Modified: Zope3/branches/ZopeX3-3.0/src/zope/configuration/tests/test_docutils.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/configuration/tests/test_docutils.py	2004-08-12 14:56:23 UTC (rev 27051)
+++ Zope3/branches/ZopeX3-3.0/src/zope/configuration/tests/test_docutils.py	2004-08-12 15:45:44 UTC (rev 27052)
@@ -11,7 +11,7 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-"""XXX short summary goes here.
+"""Doc Tests for for zope.configuration.docutils
 
 $Id$
 """

Modified: Zope3/branches/ZopeX3-3.0/src/zope/configuration/tests/test_xmlconfig.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/configuration/tests/test_xmlconfig.py	2004-08-12 14:56:23 UTC (rev 27051)
+++ Zope3/branches/ZopeX3-3.0/src/zope/configuration/tests/test_xmlconfig.py	2004-08-12 15:45:44 UTC (rev 27052)
@@ -11,7 +11,7 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-"""XXX short summary goes here.
+"""Test XML configuration (ZCML) machinery.
 
 $Id$
 """

Modified: Zope3/branches/ZopeX3-3.0/src/zope/configuration/xmlconfig.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/configuration/xmlconfig.py	2004-08-12 14:56:23 UTC (rev 27051)
+++ Zope3/branches/ZopeX3-3.0/src/zope/configuration/xmlconfig.py	2004-08-12 15:45:44 UTC (rev 27052)
@@ -419,17 +419,8 @@
     config.defineSimpleDirective(
         context, "includeOverrides", IInclude, includeOverrides, namespace="*")
 
-    # XXX zopeConfigure is deprecated; use configure in new ZCML instead
     config.defineGroupingDirective(
         context,
-        name="zopeConfigure",
-        namespace="*",
-        schema=IZopeConfigure,
-        handler=ZopeConfigure,
-        )
-
-    config.defineGroupingDirective(
-        context,
         name="configure",
         namespace="*",
         schema=IZopeConfigure,

Modified: Zope3/branches/ZopeX3-3.0/src/zope/dependencytool/finddeps.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/dependencytool/finddeps.py	2004-08-12 14:56:23 UTC (rev 27051)
+++ Zope3/branches/ZopeX3-3.0/src/zope/dependencytool/finddeps.py	2004-08-12 15:45:44 UTC (rev 27052)
@@ -227,7 +227,9 @@
                               packages=False):
     """Return a list of all cleaned dependencies in a path."""
     # zope and zope/app are too general to be considered.
-    # XXX why?  dependencies are dependencies.
+    # TODO: why?  dependencies are dependencies.
+    # Because otherwise it would just pick up zope as a dependency, but
+    # nothing else. We need a way to detect packages.
     if path.endswith('src/zope/') or path.endswith('src/zope/app/'):
         return deps
 
@@ -301,7 +303,9 @@
         elif opt in ('-d', '--dir'):
             cwd = os.getcwd()
             # This is for symlinks. Thanks to Fred for this trick.
-            # XXX wha????
+            # I often sym-link directories from other locations into the Zope
+            # source tree. This code is a bit Unix (or even bash) specific,
+            # but it is better than nothing. If you don't like it, ignore it.
             if os.environ.has_key('PWD'):
                 cwd = os.environ['PWD']
             options.path = os.path.normpath(os.path.join(cwd, arg))



More information about the Zope3-Checkins mailing list