"Fossies" - the Fresh Open Source Software Archive

Member "reportlab-3.5.23/tests/test_docstrings.py" (7 Mar 2017, 6428 Bytes) of package /linux/privat/reportlab-3.5.23.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

    1 #!/usr/bin/env python
    2 #Copyright ReportLab Europe Ltd. 2000-2017
    3 #see license.txt for license details
    4 
    5 """This is a test on a package level that find all modules,
    6 classes, methods and functions that do not have a doc string
    7 and lists them in individual log files.
    8 
    9 Currently, methods with leading and trailing double underscores
   10 are skipped.
   11 """
   12 from reportlab.lib.testutils import setOutDir,SecureTestCase, GlobDirectoryWalker, outputfile, printLocation
   13 setOutDir(__name__)
   14 import os, sys, glob, re, unittest, inspect
   15 import reportlab
   16 from reportlab.lib.utils import rl_exec, isPy3, isPyPy
   17 
   18 def typ2is(typ):
   19     return getattr(inspect,'is'+typ)
   20 
   21 _typ2key={
   22         'module':lambda x: (x[0],getattr(x[1],'__name__',''),getattr(x[1],'__path__',getattr(x,'__file__',''))),
   23         'class':lambda x: (x[0],getattr(x[1],'__name__',''),getattr(x[1],'__module__','')),
   24         'method':lambda x: (x[0],getattr(x[1],'__name__',''),getattr(x[1],'__module__','')),
   25         'function':lambda x: (x[0],getattr(x[1],'__name__',''),'???' if isPyPy else x[1].__code__.co_filename),
   26         }
   27 def typ2key(typ):
   28     return _typ2key[typ]
   29 
   30 def obj2typ(obj):
   31     for typ in ('function','module','class','method'):
   32         if typ2is(typ)(obj): return typ
   33     return None
   34 
   35 
   36 def getClass(obj):
   37     try:
   38         return obj.__self__.__class__
   39     except:
   40         try:
   41             return obj.im_class
   42         except:
   43             return None
   44 
   45 from pkgutil import iter_modules
   46 def walk_packages_ex(path=None, prefix='', onerror=None, cond=None):
   47     def seen(p, m={}):
   48         if p in m:
   49             return True
   50         m[p] = True
   51 
   52     for importer, name, ispkg in iter_modules(path, prefix):
   53         if cond and not cond(importer,name,ispkg): continue
   54         yield importer, name, ispkg
   55 
   56         if ispkg:
   57             try:
   58                 __import__(name)
   59             except ImportError:
   60                 if onerror is not None:
   61                     onerror(name)
   62             except Exception:
   63                 if onerror is not None:
   64                     onerror(name)
   65                 else:
   66                     raise
   67             else:
   68                 path = getattr(sys.modules[name], '__path__', None) or []
   69 
   70                 # don't traverse path items we've seen before
   71                 path = [p for p in path if not seen(p)]
   72 
   73                 for item in walk_packages_ex(path, name+'.', onerror, cond):
   74                     yield item
   75 
   76 def rl_module(i,name,pkg):
   77     return name=='reportlab' or name.startswith('reportlab.')
   78 
   79 rl_modules = None
   80 def getRLModules():
   81     "Get a list of all objects defined *somewhere* in a package."
   82     global rl_modules
   83     if rl_modules is None:
   84         rl_modules = []
   85         for _,name,_ in walk_packages_ex(cond=rl_module):
   86             rl_modules.append(name)
   87     return rl_modules
   88 
   89 def getObjects(objects,lookup,mName,modBn,tobj):
   90     ttyp = obj2typ(tobj)
   91     for n in dir(tobj):
   92         obj = getattr(tobj,n,None)
   93         try:
   94             if obj in lookup: continue
   95         except:
   96             continue
   97         typ = obj2typ(obj)
   98         if typ in ('function','method'):
   99             if not isPyPy and os.path.splitext(obj.__code__.co_filename)[0]==modBn:
  100                 lookup[obj] = 1
  101                 objects.setdefault(typ if typ=='function' and ttyp=='module' else 'method',[]).append((mName,obj))
  102         elif typ=='class':
  103             if obj.__module__==mName:
  104                 lookup[obj] = 1
  105                 objects.setdefault(typ,[]).append((mName,obj))
  106                 getObjects(objects,lookup,mName,modBn,obj)
  107 
  108 def getModuleObjects(modules):
  109     objects = {}
  110     lookup = {}
  111     for mName in modules:
  112         try:
  113             NS = {}
  114             rl_exec("import %s as module" % mName,NS)
  115         except ImportError:
  116             continue
  117         else:
  118             module = NS['module']
  119         if module in lookup: continue
  120 
  121         lookup[module] = 1
  122         objects.setdefault('module',[]).append((mName, module))
  123         modBn = os.path.splitext(module.__file__)[0]
  124         getObjects(objects,lookup,mName,modBn,module)
  125     return objects
  126 
  127 class DocstringTestCase(SecureTestCase):
  128     "Testing if objects in the ReportLab package have docstrings."
  129 
  130     def setUp(self):
  131         SecureTestCase.setUp(self)
  132         self.modules = getRLModules()
  133         self.objects = getModuleObjects(self.modules)
  134 
  135     def _writeLogFile(self, typ):
  136         "Write log file for different kind of documentable objects."
  137 
  138         objects = self.objects.get(typ,[])
  139         objects.sort(key=typ2key(typ))
  140 
  141         expl = {'function':'functions',
  142                 'class':'classes',
  143                 'method':'methods',
  144                 'module':'modules'}[typ]
  145 
  146         path = outputfile("test_docstrings-%s.log" % expl)
  147         file = open(path, 'w')
  148         file.write('No doc strings found for the following %s below.\n\n' % expl)
  149         p = re.compile('__.+__')
  150 
  151         lines = []
  152         for name, obj in objects:
  153             if typ == 'method':
  154                 n = obj.__name__
  155                 # Skip names with leading and trailing double underscores.
  156                 if p.match(n):
  157                     continue
  158 
  159             if not obj.__doc__ or len(obj.__doc__) == 0:
  160                 if typ == 'function':
  161                     lines.append("%s.%s\n" % (name, obj.__name__))
  162                 elif typ == 'class':
  163                     lines.append("%s.%s\n" % (obj.__module__, getattr(obj,'__qualname__',getattr(obj,'__name__','[unknown __name__]'))))
  164                 else:
  165                     lines.append("%s\n" % (getattr(obj,'__qualname__',getattr(obj,'__name__','[unknown __name__]'))))
  166 
  167         lines.sort()
  168         for line in lines:
  169             file.write(line)
  170 
  171         file.close()
  172 
  173     def test0(self):
  174         "Test if functions have a doc string."
  175         self._writeLogFile('function')
  176 
  177     def test1(self):
  178         "Test if classes have a doc string."
  179         self._writeLogFile('class')
  180 
  181     def test2(self):
  182         "Test if methods have a doc string."
  183         self._writeLogFile('method')
  184 
  185     def test3(self):
  186         "Test if modules have a doc string."
  187         self._writeLogFile('module')
  188 
  189 def makeSuite():
  190     suite = unittest.TestSuite()
  191     loader = unittest.TestLoader()
  192     if sys.platform[:4] != 'java': suite.addTest(loader.loadTestsFromTestCase(DocstringTestCase))
  193     return suite
  194 
  195 #noruntests
  196 if __name__ == "__main__":
  197     unittest.TextTestRunner().run(makeSuite())
  198     printLocation()