r534 - in zope-docfindertab/trunk: . debian dtml help tests

Fabio Tranchitella kobold at alioth.debian.org
Tue Nov 28 12:33:38 CET 2006


Author: kobold
Date: 2006-11-28 12:33:38 +0100 (Tue, 28 Nov 2006)
New Revision: 534

Added:
   zope-docfindertab/trunk/config.py
   zope-docfindertab/trunk/patch_inspect.py
   zope-docfindertab/trunk/patch_zope.py
   zope-docfindertab/trunk/permissions.py
   zope-docfindertab/trunk/tests/runalltests.py
   zope-docfindertab/trunk/tests/testAnalyse.py
Removed:
   zope-docfindertab/trunk/DocFinder/
   zope-docfindertab/trunk/Patch.py
   zope-docfindertab/trunk/Permissions.py
   zope-docfindertab/trunk/funcs.py
   zope-docfindertab/trunk/tests/README.txt
Modified:
   zope-docfindertab/trunk/CHANGES.txt
   zope-docfindertab/trunk/README.txt
   zope-docfindertab/trunk/__init__.py
   zope-docfindertab/trunk/analyse.py
   zope-docfindertab/trunk/debian/changelog
   zope-docfindertab/trunk/dtml/showDocumentation.dtml
   zope-docfindertab/trunk/help/README.stx
   zope-docfindertab/trunk/tests/framework.py
   zope-docfindertab/trunk/tests/testDocFinderTab.py
   zope-docfindertab/trunk/version.txt
Log:


Modified: zope-docfindertab/trunk/CHANGES.txt
===================================================================
--- zope-docfindertab/trunk/CHANGES.txt	2006-11-28 11:32:40 UTC (rev 533)
+++ zope-docfindertab/trunk/CHANGES.txt	2006-11-28 11:33:38 UTC (rev 534)
@@ -1,5 +1,28 @@
+1.0.2
+Print a pretty None.
+
+1.0.1
+Don't show docstring of DateTime attributes.
+
+1.0
+Update to DocFinder 1.0.3.
+Require at least Python 2.3.
+Use logging instead of zLOG.
+Handle Acquisition.Acquired.
+Handle property, staticmethod, and classmethod.
+
+0.5.3
+Minor tweaks to the monkey patch and showDocumentation.dtml.
+Added 'bool' and 'complex' to simple types mapping.
+Don't display zope.interface internal attributes.
+
+0.5.2
+Format roles more nicely, remove duplicates and faux roles, sort.
+You can get the raw representation back by setting FORMAT_ROLES=0
+in config.py.
+
 0.5.0
-Renamed product to DocFinderTab. 
+Renamed product to DocFinderTab.
 Do not display docstrings but names of simple types in Python 2.3
 
 0.4.1

Deleted: zope-docfindertab/trunk/Patch.py
===================================================================
--- zope-docfindertab/trunk/Patch.py	2006-11-28 11:32:40 UTC (rev 533)
+++ zope-docfindertab/trunk/Patch.py	2006-11-28 11:33:38 UTC (rev 534)
@@ -1,62 +0,0 @@
-# DocFinderTab 0.5.0
-# (c) 2001-2004, Stefan H. Holek, stefan at epy.co.at
-# http://zope.org/Members/shh/DocFinderTab
-# License: ZPL
-# Zope: 2.3-2.7
-
-# Monkey patch wrapper around Dieter Maurer's DocFinder product
-# http://www.dieter.handshake.de/pyprojects/zope/DocFinder.html
-# Adds a Doc tab to all Zope objects
-
-# Thanks to Dieter for his input on how to make this work with 
-# PythonScripts and ExternalMethods, and for writing DocFinder 
-# in the first place.
-
-__doc__ = 'Add a Doc tab to all Zope objects'
-__version__ = '0.5.0'
-
-__refresh_module__ = 0
-
-try:
-
-    from Globals import HTMLFile
-    from App.Management import Tabs
-    from OFS.SimpleItem import Item
-    from analyse import DocFinder
-    from AccessControl import getSecurityManager
-    from AccessControl.PermissionRole import PermissionRole
-    from Permissions import ViewDocPermission, ViewDocDefaultRoles
-
-    def filtered_manage_options(self, REQUEST=None):
-        # Append a Doc tab to an object's management tabs
-        tabs = self._old_filtered_manage_options(REQUEST)
-        secman = getSecurityManager()
-        if len(tabs) and secman.checkPermission(ViewDocPermission, self.this()):
-            tabs.append( {'label': 'Doc', 
-                          'action': 'showDocumentation', 
-                          'help': ('DocFinderTab', 'README.stx')} )
-        return tabs
-
-    Tabs._old_filtered_manage_options = Tabs.filtered_manage_options
-    Tabs.filtered_manage_options = filtered_manage_options
-
-    showDocumentation = HTMLFile('dtml/showDocumentation', globals())
-
-    def analyseDocumentation(self, object, type='scripter', filter=''):
-        return DocFinder(object, type, filter)
-        
-    ViewDocRoles = PermissionRole(ViewDocPermission, ViewDocDefaultRoles)
-
-    Item.showDocumentation = showDocumentation
-    Item.showDocumentation__roles__ = ViewDocRoles
-    Item.analyseDocumentation = analyseDocumentation
-    Item.analyseDocumentation__roles__ = ViewDocRoles
-
-    from zLOG import LOG, INFO
-    LOG('DocFinderTab', INFO, 'Applied patch version %s.' % __version__)
-
-except:
-
-    import traceback
-    traceback.print_exc()
-

Deleted: zope-docfindertab/trunk/Permissions.py
===================================================================
--- zope-docfindertab/trunk/Permissions.py	2006-11-28 11:32:40 UTC (rev 533)
+++ zope-docfindertab/trunk/Permissions.py	2006-11-28 11:33:38 UTC (rev 534)
@@ -1,12 +0,0 @@
-# DocFinderTab 0.5.0
-# (c) 2001-2004, Stefan H. Holek, stefan at epy.co.at
-# http://zope.org/Members/shh/DocFinderTab
-# License: ZPL
-# Zope: 2.3-2.7
-
-__doc__ = 'Add a Doc tab to all Zope objects'
-__version__ = '0.5.0'
-
-ViewDocPermission = 'View documentation'
-ViewDocDefaultRoles = ('Manager',)
- 

Modified: zope-docfindertab/trunk/README.txt
===================================================================
--- zope-docfindertab/trunk/README.txt	2006-11-28 11:32:40 UTC (rev 533)
+++ zope-docfindertab/trunk/README.txt	2006-11-28 11:33:38 UTC (rev 534)
@@ -1,18 +1,18 @@
 
-DocFinderTab 0.5.0
+DocFinderTab 1.0.2
 
 This product ows nearly everything to Dieter Maurer's DocFinder
-product (version 0.4).
+product (version 1.0.3).
 
 http://www.dieter.handshake.de/pyprojects/zope/DocFinder.html
-   
+
 I just put some sugar on it ;-)
 
 To install extract the tarball into your Products directory and
 restart Zope. This will add a "Doc" tab to every object's managment
-screens. Now go to an object's management screen, click the "Doc" 
+screens. Now go to an object's management screen, click the "Doc"
 tab and start exploring.
 
 See the online help for a detailed explanation of what you can
-do with DocFinderTab.
+do with DocFinderTab (or read help/README.txt).
 

Modified: zope-docfindertab/trunk/__init__.py
===================================================================
--- zope-docfindertab/trunk/__init__.py	2006-11-28 11:32:40 UTC (rev 533)
+++ zope-docfindertab/trunk/__init__.py	2006-11-28 11:33:38 UTC (rev 534)
@@ -1,8 +1,8 @@
-# DocFinderTab 0.5.0
-# (c) 2001-2004, Stefan H. Holek, stefan at epy.co.at
+# DocFinderTab 1.0.2
+# (c) 2001-2006, Stefan H. Holek, stefan at epy.co.at
 # http://zope.org/Members/shh/DocFinderTab
 # License: ZPL
-# Zope: 2.3-2.7
+# Zope: 2.6-2.10
 
 # Monkey patch wrapper around Dieter Maurer's DocFinder product
 # http://www.dieter.handshake.de/pyprojects/zope/DocFinder.html
@@ -13,12 +13,12 @@
 # in the first place.
 
 __doc__ = 'Add a Doc tab to all Zope objects'
-__version__ = '0.5.0'
+__version__ = '1.0.2'
 
 __refresh_module__ = 0
 
 from AccessControl.Permission import registerPermissions
-from Permissions import ViewDocPermission, ViewDocDefaultRoles
+from permissions import ViewDocPermission, ViewDocDefaultRoles
 
 def initialize(context):
     # Register the helpfile
@@ -29,6 +29,9 @@
     # Register our permission
     registerPermissions(((ViewDocPermission, (), ViewDocDefaultRoles),))
 
+# Apply the inspect module patch
+import patch_inspect
+
 # Apply the DocFinderTab patch
-import Patch
+import patch_zope
 

Modified: zope-docfindertab/trunk/analyse.py
===================================================================
--- zope-docfindertab/trunk/analyse.py	2006-11-28 11:32:40 UTC (rev 533)
+++ zope-docfindertab/trunk/analyse.py	2006-11-28 11:33:38 UTC (rev 534)
@@ -1,4 +1,4 @@
-# Copyright (C) 2001 by Dr. Dieter Maurer <dieter at handshake.de>
+# Copyright (C) 2001-2003 by Dr. Dieter Maurer <dieter at handshake.de>
 # D-66386 St. Ingbert, Eichendorffstr. 23, Germany
 #
 #			All Rights Reserved
@@ -8,7 +8,7 @@
 # provided that the above copyright notice and this permission
 # notice appear in all copies, modified copies and in
 # supporting documentation.
-# 
+#
 # Dieter Maurer DISCLAIMS ALL WARRANTIES WITH
 # REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL Dieter Maurer
@@ -25,38 +25,67 @@
 DETAIL_SCRIPTER= 'scripter'
 DETAIL_WEB= 'web'
 
-import sys
+from Products.DocFinderTab.config import FILTER_ROLES   # DFT
+from Products.DocFinderTab.config import FILTER_METHODS # DFT
 
+from inspect import isclass, ismethod, \
+     isfunction, ismethoddescriptor, \
+     getmro, \
+     getargspec, formatargspec, \
+     getcomments
+import re, types
 
-from funcs import func_prop_tuple
-from string import join, replace
-import re
-from types import IntType, DictType
 from AccessControl.SecurityInfo import ClassSecurityInfo, \
      ACCESS_PUBLIC, ACCESS_PRIVATE, ACCESS_NONE
-from ExtensionClass import Base
+from Acquisition import aq_base, Implicit
+from Acquisition import Acquired                # DFT
+from ComputedAttribute import ComputedAttribute # DFT
+from DateTime import DateTime                   # DFT
 
 # DFT
-try:
-    simple_types = {str: 1, unicode: 1, int: 1, float: 1, long: 1,
-                    tuple: 1, list: 1, dict: 1}
-except:
-    simple_types = None
+simple_types = {types.StringType: 1, types.IntType: 1,
+                types.LongType: 1, types.FloatType: 1,
+                types.TupleType: 1, types.ListType: 1,
+                types.DictType: 1, types.NoneType: 1}
 
+try: simple_types[types.UnicodeType] = 1
+except: pass
+try: simple_types[types.BooleanType] = 1
+except: pass
+try: simple_types[types.ComplexType] = 1
+except: pass
+try: simple_types[set] = 1
+except: pass
+try: simple_types[frozenset] = 1
+except: pass
+try: simple_types[ComputedAttribute] = 1
+except: pass
 
-class DocFinder(Base):
+_marker = {}
+
+
+class Doc(Implicit):
   '''determine the documentation of an object.
 
-  Doc is maintained in a two level structure:
+  The documentation is described by a 'Doc' instance.
+  It maintains.
 
-   1 classes, the object is build from, in inheritance order
+   path -- the physical path of the documented object or 'None'
 
-     each class is described by a 'ClassDoc' instance
+   title -- the title of the documented object or ''
 
-   2 for each class, the attributes defined by the class
-     
-     each attribute is described by a 'AttributeDoc' instance.
+   obj -- the documented object
 
+   classes -- a two level sequence structure:
+
+     1. classes, the object is build from, in message resolution order (mro).
+
+        each class is described by a 'ClassDoc' instance
+
+     2. for each class, the attributes defined by the class
+
+        each attribute is described by a 'AttributeDoc' instance.
+
   The documentation does not include instance level attributes
   (they are too many). However, it does provide
   summary information about access to unprotected attributes
@@ -69,18 +98,35 @@
   _classDict= None
 
   _secInfo= ClassSecurityInfo()
-  _secInfo.declarePublic('__getitem__','__len__','tpValues', 'tpId')
+  _secInfo.declarePublic(
+    'ObjToDoc__', 'DocType__', 'DocMethodRe__', 'Path', 'Title',
+    '__getitem__','__len__','tpValues', 'tpId',
+    )
 
   def __init__(self, obj, detail_type=DETAIL_SCRIPTER, method_filter= None):
+    # note info for presentation
+    self._ObjToDoc__= obj
+    self._DocType__= detail_type
+    self._DocMethodRe__= method_filter
+    # path -- either the path to 'obj' or its 'repr'
+    try: path= '/'.join(obj.getPhysicalPath())
+    except AttributeError: path= repr(obj)
+    # work around for a bug in 'string.translate' (does not like empty string)
+    if not path: path='/'
+    self._Path= path
+    # title -- either 'obj.title' or 'obj.Title' or ''
+    try: title= aq_base(obj).title
+    except AttributeError:
+      try: title= aq_base(obj).Title # for CMF
+      except AttributeError: title= ''
+    self._Title= title
     # encode type
     t= detail_type
-    if type(t) == type(''):
+    if isinstance(t, basestring):
       if t == DETAIL_PROGRAMMER: t= 10
       elif t == DETAIL_WEB: t= -10
       else: t= 0
 
-    # print 'DocFinder: ', detail_type, t; sys.stdout.flush()
-
     # try to get a name
     name= None
     i= getattr(obj,'getId',None) or getattr(obj,'id',None) or getattr(obj,'__name__',None)
@@ -97,7 +143,6 @@
 
     # temporary members
     self._obj= obj
-    self._seenclasses= {}
     self._attributes= {}
     self._check= self._makeUnprotectedChecker()
 
@@ -107,24 +152,30 @@
     ic._append(AttributeDoc('-- unprotected attributes --',self._attrRoles(),obj= obj))
     self._classes.append(ic)
 
-    self._analyseClassStructure(c)
+    for cl in _getMro(c): self._analyseClass(cl)
 
     # delete temporaries
     del self._obj
-    del self._seenclasses
     del self._attributes
     del self._check
 
 
+  def ObjToDoc__(self): return self._ObjToDoc__
+  def DocType__(self): return self._DocType__
+  def DocMethodRe__(self): return self._DocMethodRe__
+  def Path(self): return self._Path
+  def Title(self): return self._Title
+
+
   def __getitem__(self,k):
     '''allow access by both integer as well as class names.'''
-    if type(k) is IntType: return self._classes[k]
+    if isinstance(k, int): return self._classes[k]
     if self._classDict is None:
       cd= self._classDict= {}
       for c in self._classes: cd[c._name]= c
-    return self._classDict[k]
+    return self._classDict[k].__of__(self)
 
-  
+
   def __len__(self):
     '''the length of the classes.'''
     return len(self._classes)
@@ -132,38 +183,36 @@
 
   def tpValues(self):
     '''tuple of classes for tree display.'''
-    return tuple(self._classes)
+    return [c.__of__(self) for c in self._classes]
 
   def tpId(self):
     return self._name
 
 
-  def _analyseClassStructure(self, c):
-    '''analyse class *c* including base classes.'''
-
-    if self._seenclasses.has_key(c): return
-    self._seenclasses[c]= None
-
-    self._analyseClass(c)
-
-    for b in c.__bases__:
-      self._analyseClassStructure(b)
-
-
   def _analyseClass(self, c,
                     _omit= {'__doc__': None, '__module__': None,
                             '__allow_access_to_unprotected_subobjects__': None,
-                            'showDocumentation': None,      # DFT
-                            'analyseDocumentation': None,   # DFT
+                            '__dict__': None,                   # DFT
+                            '__weakref__': None,                # DFT
+                            '__slots__': None,                  # DFT
+                            '__slotnames__': None,              # DFT
+                            '__implements__': None,             # DFT
+                            '__implements_advice_data__': None, # DFT
+                            '__implemented__': None,            # DFT
+                            '__provides__': None,               # DFT
+                            '__providedBy__': None,             # DFT
+                            'showDocumentation': None,          # DFT
+                            'analyseDocumentation': None,       # DFT
                             }.has_key,
                     _allow= {'__len__': None,
+                            '__nonzero__': None,    # DFT
                             '__str__': None,
                             '__getitem__': None,
                             '__call__': None,
                             }.has_key,
                     ):
     '''analyse *c*.'''
-    cd= ClassDoc(c.__name__, getattr(c,'__doc__',None),_getLoc(c))
+    cd= ClassDoc(c.__name__, getattr(c,'__doc__',None),_getLoc(c),_getComment(c))
     attributes= self._attributes; seen= attributes.has_key
     check= self._check; o= self._obj; filter= self._method_filter
 
@@ -174,14 +223,14 @@
       if self._type <= 5:
         if k[0] == '_' and not _allow(k): continue
       if filter and not filter(k): continue
-      r= getattr(o,k+'__roles__', check(k))
+      r= getattr(o,k+'__roles__', check(k,v))
       if self._type <= 0 and _isPrivat(r): continue
       # something interesting
       a= AttributeDoc(k,r,v,o)
       if self._type <= -5 and not a.Doc(): continue
       cd._append(a)
 
-    if filter and not cd: return  # DFT
+    if filter and not cd: return    # DFT
     cd._finish()
     self._classes.append(cd)
 
@@ -189,17 +238,16 @@
   def _makeUnprotectedChecker(self):
     roles= getattr(self._obj,'__roles__', ACCESS_PUBLIC)
     allow= getattr(self._obj,'__allow_access_to_unprotected_subobjects__', 0)
-    if type(allow) is IntType:
+    if isinstance(allow, (int, bool)):
       if not allow: roles= ACCESS_PRIVATE
-      def check(name,roles=roles): return roles
-    elif type(allow) is DictType:
-      def check(name, check=allow.get, roles=roles, priv= ACCESS_PRIVATE):
-        if check(name): return roles
+      def check(name, value, roles=roles): return roles
+    elif isinstance(allow, dict):
+      def check(name, value, allow=allow.get, roles=roles, priv= ACCESS_PRIVATE):
+        if allow(name): return roles
         return priv
     else:
-      def check(name, obj= self._obj, allow= allow, roles=roles, priv= ACCESS_PRIVATE):
-        v= getattr(obj,name)
-        if allow(name,v): return roles
+      def check(name, value, allow=allow, roles=roles, priv= ACCESS_PRIVATE):
+        if allow(name, value): return roles
         return priv
     return check
 
@@ -207,17 +255,22 @@
   def _attrRoles(self):
     roles= getattr(self._obj,'__roles__', ACCESS_PUBLIC)
     allow= getattr(self._obj,'__allow_access_to_unprotected_subobjects__', 0)
-    if type(allow) is IntType:
+    if isinstance(allow, (int, bool)):
       if not allow: roles= ACCESS_PRIVATE
-    elif type(allow) is DictType: roles= 'Restricted (Dict)'
+    elif isinstance(allow, dict): roles= 'Restricted (Dict)'
     else: roles= 'Restricted (Func)'
     return roles
 
+  # may be necessary for 'ZTUtils.Tree.TreeMaker'
+  def tpId(self):
+    return self._Path
 
-DocFinder._secInfo.apply(DocFinder)
 
 
-class ClassDoc(Base):
+Doc._secInfo.apply(Doc)
+
+
+class ClassDoc(Implicit):
   """the documentation of a class.
 
   It consists of a 'Name', 'Doc', 'Module' and a list of attributes,
@@ -225,25 +278,28 @@
   """
 
   _secInfo= ClassSecurityInfo()
-  _secInfo.declarePublic('__getitem__','__len__','tpValues', 'tpId', 'Name', 'Doc', 'Module')
+  _secInfo.declarePublic('__getitem__','__len__','tpValues', 'tpId',
+                         'Name', 'Doc', 'Module','Comment', 'FullName',
+                         )
 
   _AttrDict= None
 
-  def __init__(self,name,doc=None,mod=None):
+  def __init__(self,name,doc=None,mod=None,comment=None):
     self._name= name
     self._doc= doc
     self._mod= mod
     self._attrs= []
+    self._comment= comment
 
   def __getitem__(self,k):
     '''allow access by both integer as well as attr names.'''
-    if type(k) is IntType: return self._attrs[k]
+    if isinstance(k, int): return self._attrs[k]
     if self._AttrDict is None:
       cd= self._AttrDict= {}
       for c in self._attrs: cd[c._name]= c
-    return self._AttrDict[k]
+    return self._AttrDict[k].__of__(self)
 
-  
+
   def __len__(self):
     '''the length of the classes.'''
     return len(self._attrs)
@@ -251,7 +307,7 @@
 
   def tpValues(self):
     '''tuple of attributes for tree display.'''
-    return tuple(self._attrs)
+    return [a.__of__(self) for a in self._attrs]
 
   def tpId(self):
     '''use name as id.'''
@@ -270,7 +326,15 @@
     '''the module the class is defined in.'''
     return self._mod
 
+  def Comment(self):
+    '''the comment preceeding the class.'''
+    return self._comment
 
+  def FullName(self):
+    '''the full class name (to be used with 'showCodeFor').'''
+    return '%s.%s' % (self.Module(),self.Name())
+
+
   def _append(self,attr):
     '''append *attr*.'''
     self._attrs.append(attr)
@@ -285,7 +349,7 @@
 
 
 
-class AttributeDoc(Base):
+class AttributeDoc(Implicit):
   """the documentation of an attribute.
 
   It consists of a 'Name', 'Roles', 'Args', 'Doc' and 'Type'.
@@ -294,33 +358,32 @@
   _secInfo= ClassSecurityInfo()
   _secInfo.declarePublic('tpValues', 'tpId',
                          'Name', 'Roles', 'Args', 'Doc', 'Type', 'DocOrType',
-                         'Permission',
+                         'Comment', 'Permission', 'FullName',
                          )
 
   _knownPermission= 0
 
-  def __init__(self,name,roles,value= None, obj= None):
-    if value is not None:
+  def __init__(self,name,roles,value= _marker, obj= None):
+    arguments= doc= comment= type= ''
+    if value is not _marker:
       # determine arguments and documentation, if possible
-      arguments= doc= ''
-      try:
-        (n,a,doc)= func_prop_tuple(value)
-        arguments= join(a,', ')
+      try: arguments= _findArgSpec(value)
       except: pass
-      try: doc= _getDoc(value)  # DFT
+      try: doc= _getDoc(value)        # DFT
       except: pass
+      # determine comment if possible
+      comment= _getComment(value)
       type= _getType(value)
-    else: doc= arguments= type= ''
 
+    try: roles= _getRoles(roles)    # DFT
+    except: pass
     self._name= name
-    if roles is ACCESS_PUBLIC: roles= 'public'
-    elif roles == ACCESS_PRIVATE: roles= 'private'
-    elif roles is ACCESS_NONE: roles= 'none'
     self._roles= roles
     self._arguments= arguments
     self._doc= doc
     self._type= type
     self._obj= obj
+    self._comment= comment
 
   def Name(self):
     '''the attribute name'''
@@ -353,23 +416,31 @@
     '''either the Doc (prefered) or the Type.'''
     return self.Doc() or self.Type()
 
+  def FullName(self):
+    '''the full class name (to be used with 'showCodeFor').'''
+    return '%s.%s' % (self.aq_inner.aq_parent.FullName(),self.Name())
+
   def Permission(self):
     '''return the permission protecting the attribute, 'None' if not directly protected.'''
     if self._knownPermission: return self._permission
     p= None
-    if self._obj:
+    if self._obj is not None:
       name= self._name
       if name[:3] == '-- ': name= ''
       p= _lookup(self._obj, name+'__roles__')
       if p is not None:
         try:
-          p= replace(p[1]._p[1:-11],'_',' ')
+          p= p[1]._p[1:-11].replace('_',' ')
         except: p= '-- explicit --'
     self._permission= p; self._knownPermission= 1
     return p
 
+  def Comment(self):
+    '''the comment preceeding the attribute.'''
+    return self._comment
 
 
+
 AttributeDoc._secInfo.apply(AttributeDoc)
 
 
@@ -381,28 +452,92 @@
   '''return location (module) of class *c*.'''
   return getattr(c,'__module__',None)
 
+def _getComment(obj):
+  '''return comment preceeding *obj*.'''
+  try: return getcomments(obj)
+  except: return ''
 
+
 def _getType(v):
   '''return a nice representation of the *v* type.'''
   tn= type(v).__name__
-  if tn == 'instance': tn= '%s %s' % (v.__class__.__name__,tn)
-  elif tn == 'instance method': tn= '%s %s' % (v.im_class.__name__,tn)
+  if tn == 'instance':
+    tn= '%s %s' % (v.__class__.__name__,tn)
+  elif tn == 'instance method':
+    tn= '%s %s' % (v.im_class.__name__,tn)
   return tn
 
 
 def _getClass(obj):
   '''return the class of *obj*.'''
-  return hasattr(obj,'_klass') and obj._klass or obj.__class__
+  m= {}
+  if getattr(obj,'_klass',m) is not m:
+    return obj._klass
+  else:
+    return obj.__class__
 
 
+_MROCache= {}
+def _getMro(class_):
+  '''*class_* s method resolution order (cached).'''
+  mro= _MROCache.get(class_)
+  if mro is None:
+    mro= _MROCache[class_]= getmro(class_)
+  return mro
+
+
 # DFT
 def _getDoc(obj, simple_types=simple_types):
     '''return the docstring of *obj*.'''
-    if simple_types is not None and type(obj) in simple_types:
-        return _getType(obj)
+    if obj is Acquired:
+        return 'Acquisition.Acquired'
+    if obj is None:
+        return 'None'
+    if isinstance(obj, DateTime):
+        return 'DateTime'
+    if simple_types.has_key(type(obj)) or not _isNonPrimitive(obj):
+        return ''
+    if isinstance(obj, (staticmethod, classmethod)):
+        return obj.__get__(obj).__doc__
+    if FILTER_METHODS:
+        if isfunction(obj) or ismethod(obj) or ismethoddescriptor(obj):
+            if not obj.__doc__: return 'method'
     return obj.__doc__
 
 
+# DFT
+def _getRoles(roles):
+    '''return nice names for *roles*.'''
+    if FILTER_ROLES:
+        if roles is ACCESS_PUBLIC: roles= 'public'
+        elif roles == ACCESS_PRIVATE: roles= 'private'
+        elif roles is ACCESS_NONE: roles= 'none'
+        else: roles= _filterRoles(roles)
+    else:
+        if roles is ACCESS_PUBLIC: roles= 'ACCESS_PUBLIC'
+        elif roles == ACCESS_PRIVATE: roles= 'ACCESS_PRIVATE'
+        elif roles is ACCESS_NONE: roles= 'ACCESS_NONE'
+    return roles
+
+
+# DFT
+def _filterRoles(roles):
+    '''filter out faux roles.'''
+    if not isinstance(roles, (list, tuple)):
+        return roles
+
+    def fauxRole(role):
+        return role.startswith('_') and role.endswith('_Permission')
+
+    unique= {}
+    for role in roles:
+        if not fauxRole(role):
+            unique[role]= 1
+    roles= unique.keys()
+    roles.sort()
+    return '(%s)' % ', '.join(roles)
+
+
 def _lookup(obj,key):
   '''emulate Pythons name lookup; return pair (class,attr) or 'None'.'''
   m= {}
@@ -414,9 +549,27 @@
 
 
 def _lookupClassHierarchy(c,k,m):
-  v= c.__dict__.get(k,m)
-  if v is not m: return (c,v)
-  for c in c.__bases__:
-    v= _lookupClassHierarchy(c,k,m)
-    if v is not None: return v
+  for cl in _getMro(c):
+    v= cl.__dict__.get(k,m)
+    if v is not m: return (cl,v)
   return None
+
+
+def _id(self): return self
+
+def _findArgSpec(maybeFunction):
+  '''the argument specification for *maybeFunction* or an exception.'''
+  if isclass(maybeFunction):
+    maybeFunction= getattr(maybeFunction,'__init__',_id)
+  if isinstance(maybeFunction, (staticmethod, classmethod)):  # DFT
+    maybeFunction= maybeFunction.__get__(maybeFunction)
+  if ismethod(maybeFunction):
+    maybeFunction= maybeFunction.im_func
+  return formatargspec(*getargspec(maybeFunction))[1:-1]    # DFT
+
+try:
+  from ZPublisher.BaseRequest import typeCheck
+  _isNonPrimitive= typeCheck
+except ImportError:
+  def _isNonPrimitive(value): return 1
+

Copied: zope-docfindertab/trunk/config.py (from rev 533, zope-docfindertab/branches/upstream/current/config.py)

Modified: zope-docfindertab/trunk/debian/changelog
===================================================================
--- zope-docfindertab/trunk/debian/changelog	2006-11-28 11:32:40 UTC (rev 533)
+++ zope-docfindertab/trunk/debian/changelog	2006-11-28 11:33:38 UTC (rev 534)
@@ -1,3 +1,10 @@
+zope-docfindertab (1.0.2-1) unstable; urgency=low
+
+  * New maintainer. (Closes: #389313)
+  * New upstream release.
+
+ -- Fabio Tranchitella <kobold at debian.org>  Tue, 28 Nov 2006 12:32:48 +0100
+
 zope-docfindertab (0.5.0-3) unstable; urgency=low
 
   * QA upload. (Ack NMU: Closes: #370763,#370772,#372749,#368188,#332171)

Modified: zope-docfindertab/trunk/dtml/showDocumentation.dtml
===================================================================
--- zope-docfindertab/trunk/dtml/showDocumentation.dtml	2006-11-28 11:32:40 UTC (rev 533)
+++ zope-docfindertab/trunk/dtml/showDocumentation.dtml	2006-11-28 11:33:38 UTC (rev 534)
@@ -1,3 +1,4 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
 <dtml-let target__="_.has_key('ObjToDoc__') and ObjToDoc__ or this()">
 
 <dtml-if "REQUEST.has_key('expert__')">
@@ -22,8 +23,13 @@
   <dtml-call "RESPONSE.setCookie('DF_filter', filter__, path='/')">
 </dtml-if>
 
-<html><head><title>Documentation for object <dtml-var "target__.getId()" html_quote></title>
+<html><head><title>Documentation for <dtml-var "target__.getId()" html_quote></title>
 <dtml-comment> The following is partially ripped from manage_page_header </dtml-comment>
+<dtml-unless management_page_charset>
+<dtml-call "REQUEST.set('management_page_charset','iso-8859-1')">
+</dtml-unless>
+<meta http-equiv="content-type" content="text/html;charset=&dtml-management_page_charset;" />
+<dtml-call "RESPONSE.setHeader('content-type','text/html;charset='+management_page_charset)">
 <dtml-let ag="_.string.lower(REQUEST.get('HTTP_USER_AGENT', ''))"
           find="_.string.find"
           is_nav4="ag[:9]=='mozilla/4' and find(ag,'msie')<0"
@@ -48,37 +54,40 @@
 <style type="text/css">
 <!--
 body                  { background-color: white; }
-form                  { padding: 0; margin: 0; }
+form                  { padding: 0px; margin: 0px; }
 .list-header          { background-color: #6699cc; border: none; }
 .row-hilite           { background-color: #cfcfcf; border: none; }
-.row-normal           { background-color: #efefef; border: none; } 
-                              /* t r  b l */
-.list-header h3       { padding: 0 0  3 0; margin: 0; }
-.list-header p        { padding: 0 0 15 0; margin: 0; }
-.list-header .nodoc   { padding: 0 0 13 0; margin: 0; }
-.list-header .module  { padding: 0 0  6 0; margin: 0; color: black; }
-.row-hilite  p        { padding: 4 2  4 2; margin: 0; }
-.row-normal  p        { padding: 4 2  4 2; margin: 0; }
+.row-normal           { background-color: #efefef; border: none; }
+                              /* t   r    b   l */
+.list-header h3       { padding: 0px 0px  3px 0px; margin: 0px; }
+.list-header p        { padding: 0px 0px 15px 0px; margin: 0px; }
+.list-header .nodoc   { padding: 0px 0px 13px 0px; margin: 0px; }
+.list-header .module  { padding: 0px 0px  6px 0px; margin: 0px; color: black; }
+.row-hilite  p        { padding: 4px 2px  4px 2px; margin: 0px; }
+.row-normal  p        { padding: 4px 2px  4px 2px; margin: 0px; }
 .black                { color: black; }
 .structured-text      { color: #333333; }
-.structured-text h1   { padding: 2 0  2 0; margin: 0; font-size: 12pt; color: #333333; }  
-.structured-text h2   { padding: 2 0  2 0; margin: 0; font-size: 11pt; color: #333333; }  
-.structured-text h3   { padding: 2 0  2 0; margin: 0; font-size: 10pt; color: #333333; }  
-.structured-text h4   { padding: 2 0  2 0: margin: 0; font-size: 10pt; color: #333333; font-style: italic; }  
-.structured-text ul   { margin-top: 5; margin-bottom: 5; font-size: 10pt; color: #333333; }  
-.structured-text ol   { margin-top: 5; margin-bottom: 5; font-size: 10pt; color: #333333; }  
+.structured-text h1   { padding: 2px 0px  2px 0px; margin: 0px; font-size: 12pt; color: #333333; }
+.structured-text h2   { padding: 2px 0px  2px 0px; margin: 0px; font-size: 11pt; color: #333333; }
+.structured-text h3   { padding: 2px 0px  2px 0px; margin: 0px; font-size: 10pt; color: #333333; }
+.structured-text h4   { padding: 2px 0px  2px 0px; margin: 0px; font-size: 10pt; color: #333333; font-style: italic; }
+.structured-text h5   { padding: 2px 0px  2px 0px; margin: 0px; font-size: 10pt; color: #555555; font-style: italic; }
+.structured-text h6   { padding: 2px 0px  2px 0px; margin: 0px; font-size: 10pt; color: #555555; font-style: italic; }
+.structured-text ul   { margin-top: 5px; margin-bottom: 5px; font-size: 10pt; color: #333333; }
+.structured-text ol   { margin-top: 5px; margin-bottom: 5px; font-size: 10pt; color: #333333; }
+.structured-text dl   { margin-top: 5px; margin-bottom: 5px; font-size: 10pt; color: #333333; }
 <dtml-if is_msiewin>
-  .filter-box         { padding: 0; margin: 0; line-height: 10pt; font-size: 8pt; font-family: Arial,Helvetica,sans-serif; height: 13pt; }
-  .expert-box         { margin-left: 0; height: 13pt; }
-  .shortp             { padding-top: 0.8em; margin-top: 0; }
+  .filter-box         { padding: 0px; margin: 0px; line-height: 10pt; font-size: 8pt; font-family: Arial,Helvetica,sans-serif; height: 13pt; }
+  .expert-box         { margin-left: 0px; height: 13pt; }
+  .shortp             { padding-top: 0.8em; margin-top: 0px; }
 <dtml-elif is_win>
-  .filter-box         { padding: 0; margin: 0; line-height: 10pt; font-size: 8pt; font-family: Arial,Helvetica,sans-serif; }
+  .filter-box         { padding: 0px; margin: 0px; line-height: 10pt; font-size: 8pt; font-family: Arial,Helvetica,sans-serif; }
 </dtml-if>
 <dtml-if is_camino>
-  .filter-box         { padding: 0; margin: 0; line-height: 10pt; font-size: 8pt; font-family: Arial,Helvetica,sans-serif; }
-  .expert-box         { margin-top: 1; margin-left: 0; height: 10pt; }
-<dtml-elif is_mozilla> 
-  .expert-box         { margin-top: 1; margin-left: 2; }
+  .filter-box         { padding: 0px; margin: 0px; line-height: 10pt; font-size: 8pt; font-family: Arial,Helvetica,sans-serif; }
+  .expert-box         { margin-top: 1px; margin-left: 0px; height: 10pt; }
+<dtml-elif is_mozilla>
+  .expert-box         { margin-top: 1px; margin-left: 2px; }
 </dtml-if>
 -->
 </style>
@@ -101,7 +110,7 @@
 <form action="&dtml-URL0;">
 <tr valign="top">
   <td class="std-text" width=100%>
-    Documentation for <b><dtml-with "target__"><dtml-var meta_type html_quote></dtml-with></b> object 
+    Documentation for <b><dtml-with "target__"><dtml-var meta_type html_quote></dtml-with></b> object
     <dtml-if "_.hasattr(target__, 'title_and_id')">
       <b><dtml-var "target__.title_and_id()" html_quote></b>
     <dtml-else>
@@ -172,13 +181,11 @@
         </td>
         <td &dtml.-td_args__; width="40%">
           <span class="form-element">
-            <dtml-let doc="Doc()">
-              <dtml-if "doc and _.string.strip(doc)">
-                <span class=structured-text><dtml-var doc fmt="structured-text"></span>
-              <dtml-else>
-                <dtml-if Type><p><dtml-var Type></p><dtml-else>&nbsp;</dtml-if>
-              </dtml-if>
-            </dtml-let>
+            <dtml-if Doc>
+              <span class=structured-text><dtml-var Doc fmt="structured-text"></span>
+            <dtml-else>
+              <dtml-if Type><p><dtml-var Type></p><dtml-else>&nbsp;</dtml-if>
+            </dtml-if>
           </span>
 	<dtml-call "REQUEST.set('row__', row__+1)">
       </dtml-let td_args__>

Deleted: zope-docfindertab/trunk/funcs.py
===================================================================
--- zope-docfindertab/trunk/funcs.py	2006-11-28 11:32:40 UTC (rev 533)
+++ zope-docfindertab/trunk/funcs.py	2006-11-28 11:33:38 UTC (rev 534)
@@ -1,77 +0,0 @@
-# Copyright (C) 1997-2001 by Dr. Dieter Maurer <dieter at hit.handshake.de>
-# D-66386 St. Ingbert, Eichendorffstr. 23, Germany
-#
-#			All Rights Reserved
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose and without fee is hereby granted,
-# provided that the above copyright notice appear in all copies and
-# modified copies and that
-# both that copyright notice and this permission notice appear in
-# supporting documentation.
-# 
-# Dieter Maurer DISCLAIMS ALL WARRANTIES WITH
-# REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL Dieter Maurer
-# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
-# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
-# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-# PERFORMANCE OF THIS SOFTWARE.
-"""Function auxiliaries"""
-
-import types, string
-
-# copied from Python header file
-CO_OPTIMIZED = 0x0001
-CO_NEWLOCALS = 0x0002
-CO_VARARGS = 0x0004
-CO_VARKEYWORDS = 0x0008
-
-def func_props(f,detail='a',name=None):
-  """returns a string describing the function, method or class *f*
-
-  *detail* controls how much properties are included:
-    ''		only the functions name
-    'a'		includes the functions arguments
-    'd'	        the functions first line of documentation
-    'D'		includes the functions complete documentation
-    several options can be concatenated"""
-  (n,a,d)= func_prop_tuple(f)
-  if name is None: name= n
-  args= 'a' in detail and '(' + string.join(a,',') + ')' or ''
-  doc= ''
-  if d:
-    if 'D' in detail: doc= '\n  ' + d
-    elif 'd' in detail: doc= ': ' + d
-  return name + args + doc
-
-
-def func_prop_tuple(f):
-  name=f.__name__
-  doc=f.__doc__
-  t=type(f)
-  if t is types.MethodType: f= f.im_func
-  elif t is types.ClassType:
-    try:
-      f= f.__init__.im_func
-      if f.__doc__: doc=f.__doc__
-    except: f= _emptyfunc
-  c=f.func_code
-  n=c.co_argcount
-  a=list(c.co_varnames[:n])
-  if f.func_defaults:
-    i=n-len(f.func_defaults)
-    for d in f.func_defaults:
-      a[i]= a[i] + '=' + repr(d)
-      i= i+1
-  if c.co_flags & CO_VARARGS:
-    a.append('*' + c.co_varnames[n])
-    n= n+1
-  if c.co_flags & CO_VARKEYWORDS:
-    a.append('**' + c.co_varnames[n])
-    n= n+1
-  if t is types.ClassType: del(a[0])
-  return (name, a, doc)
-    
-def _emptyfunc(self): pass    

Modified: zope-docfindertab/trunk/help/README.stx
===================================================================
--- zope-docfindertab/trunk/help/README.stx	2006-11-28 11:32:40 UTC (rev 533)
+++ zope-docfindertab/trunk/help/README.stx	2006-11-28 11:33:38 UTC (rev 534)
@@ -1,14 +1,15 @@
 Release Notes
 
-    DocFinderTab 0.5.0
+    DocFinderTab 1.0.2
 
 Description
 
-    You can use the "Doc" view to ask Zope for documentation about its objects.
+    You can use the **Doc** tab to ask Zope for documentation about its objects.
 
     This product makes Dieter Maurer's 
     <a href="http://www.dieter.handshake.de/pyprojects/zope/DocFinder.html" target=_blank>DocFinder</a>
     available from a ZMI management tab.  
+
     DocFinder's introspection capabilities make it an important part of the Zopista's 
     toolbox:
 
@@ -26,8 +27,8 @@
 
     - **Attribute** names, roles, arguments, and docstrings.
 
-    DocFinder treats docstrings as structured text which allows you to put nicely formatted 
-    documentation right into the source files, while having it available at the click of a mouse.
+    DocFinder treats docstrings as structured text. This allows you to put nicely formatted 
+    documentation right into the source files, while having it instantly availabe TTW.
 
 Controls
 
@@ -53,14 +54,15 @@
 
 Permission Names
 
-    If you start Zope with 'ZOPE_SECURITY_POLICY' set to 'PYTHON', DocFinder will furthermore
-    return the names of **permissions** protecting the individual attributes.
+    Since Zope 2.7 DocFinder returns the names of **permissions** protecting individual attributes.
 
-    If no permission name is available, DocFinder will indicate the presence of an
-    explicit security declaration for the respective attribute (expert mode only).
+    In earlier versions you had to start Zope with 'ZOPE_SECURITY_POLICY' set to 'PYTHON' to
+    see the permission names.
 
+    If no permission name is available, DocFinder will indicate the presence of
+    explicit security declarations for the respective attributes (expert mode only).
+
 Security
 
-    You can control access to the "Doc" tab via the "View documentation" permission.
+    You can control access to the **Doc** tab via the *View documentation* permission.
 
-

Copied: zope-docfindertab/trunk/patch_inspect.py (from rev 533, zope-docfindertab/branches/upstream/current/patch_inspect.py)

Copied: zope-docfindertab/trunk/patch_zope.py (from rev 533, zope-docfindertab/branches/upstream/current/patch_zope.py)

Copied: zope-docfindertab/trunk/permissions.py (from rev 533, zope-docfindertab/branches/upstream/current/permissions.py)

Deleted: zope-docfindertab/trunk/tests/README.txt
===================================================================
--- zope-docfindertab/trunk/tests/README.txt	2006-11-28 11:32:40 UTC (rev 533)
+++ zope-docfindertab/trunk/tests/README.txt	2006-11-28 11:33:38 UTC (rev 534)
@@ -1,14 +0,0 @@
-
-Tests for DocFinderTab
-
-The tests can be run either directly, e.g.
-
-  python testDocFinderTab.py
-
-or with the testrunner utility, e.g.
-
-  python /Zope/utilities/testrunner.py -qa
-
-Note that you must have the ZopeTestCase 
-package installed.
-

Modified: zope-docfindertab/trunk/tests/framework.py
===================================================================
--- zope-docfindertab/trunk/tests/framework.py	2006-11-28 11:32:40 UTC (rev 533)
+++ zope-docfindertab/trunk/tests/framework.py	2006-11-28 11:33:38 UTC (rev 534)
@@ -1,44 +1,53 @@
 ##############################################################################
 #
-# ZopeTestCase 
+# Copyright (c) 2005 Zope Corporation and Contributors. All Rights Reserved.
 #
-# COPY THIS FILE TO YOUR 'tests' DIRECTORY.
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (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.
 #
-# This version of framework.py will use the SOFTWARE_HOME
-# environment variable to locate Zope and the Testing package.
-#
-# If the tests are run in an INSTANCE_HOME installation of Zope,
-# Products.__path__ and sys.path with be adjusted to include the
-# instance's Products and lib/python directories respectively.
-#
-# If you explicitly set INSTANCE_HOME prior to running the tests,
-# auto-detection is disabled and the specified path will be used 
-# instead.
-#
-# If the 'tests' directory contains a custom_zodb.py file, INSTANCE_HOME
-# will be adjusted to use it.
-#
-# If you set the ZEO_INSTANCE_HOME environment variable a ZEO setup 
-# is assumed, and you can attach to a running ZEO server (via the 
-# instance's custom_zodb.py).
-#
 ##############################################################################
-#
-# The following code should be at the top of every test module:
-#
-# import os, sys
-# if __name__ == '__main__':
-#     execfile(os.path.join(sys.path[0], 'framework.py'))
-#
-# ...and the following at the bottom:
-#
-# if __name__ == '__main__':
-#     framework()
-#
-##############################################################################
+"""ZopeTestCase framework
 
-__version__ = '0.2.3'
+COPY THIS FILE TO YOUR 'tests' DIRECTORY.
 
+This version of framework.py will use the SOFTWARE_HOME
+environment variable to locate Zope and the Testing package.
+
+If the tests are run in an INSTANCE_HOME installation of Zope,
+Products.__path__ and sys.path with be adjusted to include the
+instance's Products and lib/python directories respectively.
+
+If you explicitly set INSTANCE_HOME prior to running the tests,
+auto-detection is disabled and the specified path will be used 
+instead.
+
+If the 'tests' directory contains a custom_zodb.py file, INSTANCE_HOME
+will be adjusted to use it.
+
+If you set the ZEO_INSTANCE_HOME environment variable a ZEO setup 
+is assumed, and you can attach to a running ZEO server (via the 
+instance's custom_zodb.py).
+
+The following code should be at the top of every test module:
+
+  import os, sys
+  if __name__ == '__main__':
+      execfile(os.path.join(sys.path[0], 'framework.py'))
+
+...and the following at the bottom:
+
+  if __name__ == '__main__':
+      framework()
+
+$Id: framework.py,v 1.3 2006/02/18 15:43:19 stefan Exp $
+"""
+
+__version__ = '0.2.4'
+
 # Save start state
 #
 __SOFTWARE_HOME = os.environ.get('SOFTWARE_HOME', '')

Copied: zope-docfindertab/trunk/tests/runalltests.py (from rev 533, zope-docfindertab/branches/upstream/current/tests/runalltests.py)

Copied: zope-docfindertab/trunk/tests/testAnalyse.py (from rev 533, zope-docfindertab/branches/upstream/current/tests/testAnalyse.py)

Modified: zope-docfindertab/trunk/tests/testDocFinderTab.py
===================================================================
--- zope-docfindertab/trunk/tests/testDocFinderTab.py	2006-11-28 11:32:40 UTC (rev 533)
+++ zope-docfindertab/trunk/tests/testDocFinderTab.py	2006-11-28 11:33:38 UTC (rev 534)
@@ -8,16 +8,16 @@
 
 from Testing import ZopeTestCase
 
+ZopeTestCase.installProduct('DocFinderTab')
+
 from AccessControl import Unauthorized
-from Products.DocFinderTab.Permissions import ViewDocPermission
+from Products.DocFinderTab.permissions import ViewDocPermission
 
 standard_permissions = ZopeTestCase.standard_permissions
-access_permissions   = [ViewDocPermission] 
-all_permissions      = standard_permissions+access_permissions
+access_permissions = [ViewDocPermission]
+all_permissions = standard_permissions + access_permissions
 
-ZopeTestCase.installProduct('DocFinderTab')
 
-
 class TestDocFinderTab(ZopeTestCase.ZopeTestCase):
 
     def test_00_ItemPatched(self):
@@ -33,7 +33,7 @@
             dummy = self.folder.restrictedTraverse('showDocumentation')
         except Unauthorized:
             self.fail('Access to showDocumentation was denied')
-            
+
     def test_02_AccessDenied(self):
         'showDocumentation should be protected'
         self.setPermissions(standard_permissions)
@@ -43,7 +43,7 @@
             pass
         else:
             self.fail('Access to showDocumentation was allowed')
-            
+
     def test_03_ManagerAccessAllowed(self):
         'showDocumentation should be accessible to Managers'
         self.setRoles(['Manager'])
@@ -51,7 +51,7 @@
             dummy = self.folder.restrictedTraverse('showDocumentation')
         except Unauthorized:
             self.fail('Access to showDocumentation was denied to Manager')
-            
+
     def test_04_ManagerAccessDenied(self):
         'showDocumentation should be protected from Managers'
         self.folder.manage_permission(ViewDocPermission, ['Owner'], acquire=0)
@@ -62,7 +62,7 @@
             pass
         else:
             self.fail('Access to showDocumentation was allowed to Manager')
-            
+
     def test_05_AccessAllowed(self):
         'analyseDocumentation should be accessible'
         self.setPermissions(standard_permissions+access_permissions)
@@ -70,7 +70,7 @@
             dummy = self.folder.restrictedTraverse('analyseDocumentation')
         except Unauthorized:
             self.fail('Access to analyseDocumentation was denied')
-            
+
     def test_06_AccessDenied(self):
         'analyseDocumentation should be protected'
         self.setPermissions(standard_permissions)
@@ -80,7 +80,7 @@
             pass
         else:
             self.fail('Access to analyseDocumentation was allowed')
-            
+
     def test_07_ManagerAccessAllowed(self):
         'analyseDocumentation should be accessible to Managers'
         self.setRoles(['Manager'])
@@ -88,7 +88,7 @@
             dummy = self.folder.restrictedTraverse('analyseDocumentation')
         except Unauthorized:
             self.fail('Access to analyseDocumentation was denied to Manager')
-            
+
     def test_08_ManagerAccessDenied(self):
         'analyseDocumentation should be protected from Managers'
         self.folder.manage_permission(ViewDocPermission, ['Owner'], acquire=0)
@@ -99,13 +99,13 @@
             pass
         else:
             self.fail('Access to analyseDocumentation was allowed to Manager')
-            
+
     # b/w compatibility clutch
     if not hasattr(ZopeTestCase.ZopeTestCase, 'setPermissions'):
         setPermissions = ZopeTestCase.ZopeTestCase._setPermissions
         setRoles = ZopeTestCase.ZopeTestCase._setRoles
 
-            
+
 def test_suite():
     from unittest import TestSuite, makeSuite
     suite = TestSuite()

Modified: zope-docfindertab/trunk/version.txt
===================================================================
--- zope-docfindertab/trunk/version.txt	2006-11-28 11:32:40 UTC (rev 533)
+++ zope-docfindertab/trunk/version.txt	2006-11-28 11:33:38 UTC (rev 534)
@@ -1 +1 @@
-0.5.0
+1.0.2




More information about the pkg-zope-commits mailing list