[Happydoc-checkins] CVS: HappyDoc3/happydoclib packagetree.py,NONE,1.1 test_packagetree.py,NONE,1.1
Brought to you by:
doughellmann,
krlosaqp
From: Doug H. <dou...@us...> - 2002-12-29 18:35:17
|
Update of /cvsroot/happydoc/HappyDoc3/happydoclib In directory sc8-pr-cvs1:/tmp/cvs-serv28702/happydoclib Modified Files: scanner.py test_scanner.py Added Files: packagetree.py test_packagetree.py Log Message: Move PackageTree to its own file. --- NEW FILE: packagetree.py --- #!/usr/bin/env python # # $Id: packagetree.py,v 1.1 2002/12/29 18:35:14 doughellmann Exp $ # # Copyright 2002 Doug Hellmann. # # # 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 that both that copyright notice and this permission # notice appear in supporting documentation, and that the name of Doug # Hellmann not be used in advertising or publicity pertaining to # distribution of the software without specific, written prior # permission. # # DOUG HELLMANN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, # INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN # NO EVENT SHALL DOUG HELLMANN 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. # """Tree representing the input data. """ __rcs_info__ = { # # Creation Information # 'module_name' : '$RCSfile: packagetree.py,v $', 'rcs_id' : '$Id: packagetree.py,v 1.1 2002/12/29 18:35:14 doughellmann Exp $', 'creator' : 'Doug Hellmann <do...@he...>', 'project' : 'HappyDoc', 'created' : 'Sun, 29-Dec-2002 12:37:53 EST', # # Current Information # 'author' : '$Author: doughellmann $', 'version' : '$Revision: 1.1 $', 'date' : '$Date: 2002/12/29 18:35:14 $', } try: __version__ = __rcs_info__['version'].split(' ')[1] except: __version__ = '0.0' # # Import system modules # import mimetypes import os import re import UserDict # # Import Local modules # import happydoclib from happydoclib.status import statusMessage from happydoclib.trace import trace from happydoclib.utils import * # # Module # TRACE_LEVEL=2 # # Initialize extensions for mimetypes that we know about but which are # not standard. # mimetypes.types_map['.stx'] = 'text/x-structured' class PackageTree(UserDict.UserDict): """Tree of package information. Access each child node using the standard mapping de-reference syntax ([], .get(), etc.). """ parser_mapping = { 'text/x-python' : 'parsePythonInput', 'text/plain' : 'parsePlainTextInput', 'text/x-structured' : 'parseStructuredTextInput', } def __init__(self, parent, name): trace.into('PackageTree', '__init__', parent=parent, name=name, outputLevel=TRACE_LEVEL, ) UserDict.UserDict.__init__(self) self.parent = parent self.name = os.path.basename(name) trace.write('self.name=%s' % self.name, outputLevel=TRACE_LEVEL) self.canonical_name = name trace.outof(outputLevel=TRACE_LEVEL) return def __repr__(self): base_str = UserDict.UserDict.__repr__(self) return '<%s %s: %s>' % (self.__class__.__name__, self.getName(), base_str) # # Parsing methods # def parsePythonInput(self): trace.into('PackageTree', 'parsePythonInput', outputLevel=TRACE_LEVEL) # # Derive the filename for this module. # filename = self.getInputFilename() statusMessage('Parsing: %s' % filename) # # Figure out if there is a parent node for the # documentation suite. # package_parent = self.getParent() if package_parent and hasattr(package_parent, 'module_info'): docs_parent = package_parent.module_info else: docs_parent = None trace.writeVar(docs_parent=docs_parent, outputLevel=TRACE_LEVEL) docs = happydoclib.parseinfo.getDocs( parent=docs_parent, fileName=filename, ) self.module_info = docs trace.outof(outputLevel=TRACE_LEVEL) return def parsePlainTextInput(self): trace.into('PackageTree', 'parsePlainTextInput', outputLevel=TRACE_LEVEL, ) # # Derive the filename for this module. # filename = self.getInputFilename() trace.writeVar(filename=filename, outputLevel=TRACE_LEVEL) statusMessage('Importing preformatted file: %s' % filename) #f = open(filename, 'rt') #body = f.read() #f.close() #packageTreeNode.preformatted_text = body trace.outof(outputLevel=TRACE_LEVEL) return def parseStructuredTextInput(self): trace.into('PackageTree', 'parseStructuredTextInput', outputLevel=TRACE_LEVEL) self.parsePlainTextInput() trace.outof(outputLevel=TRACE_LEVEL) return def parseInput(self): """Get whatever information is appropriate from the input file. """ trace.into('PackageTree', 'parseInput', outputLevel=TRACE_LEVEL) if os.path.isdir(self.getInputFilename()): trace.write('directory', outputLevel=TRACE_LEVEL) trace.outof(outputLevel=TRACE_LEVEL) return mimetype, encoding = self.getMimeType() try: parse_method_name = self.parser_mapping[mimetype] except KeyError: # # Don't know what to do with this file. # statusMessage('Not parsing input %s with mimetype %s' % ( self.getInputFilename(), mimetype, ), 2) else: # # Call the parse method # parse_method = getattr(self, parse_method_name) parse_method() trace.outof(outputLevel=TRACE_LEVEL) return # # Data retrieval methods # def getMimeType(self): """Returns the (mimetype, encoding) setting for this node. """ trace.into('PackageTreeNode', 'getMimeType', name=self.name, outputLevel=TRACE_LEVEL, ) input_filename = self.getInputFilename() mimetype = mimetypes.guess_type(input_filename) if mimetype == (None, None): if isSomethingThatLooksLikeDirectory(input_filename): mimetype = ('application/x-directory', None) trace.outof(mimetype, outputLevel=TRACE_LEVEL) return mimetype def getName(self): """Returns the name of this tree node. """ return self.name def getCanonicalName(self): """Returns the canonical, full, name of the this tree node. """ return self.canonical_name def getInputFilename(self): """Returns the original input filename that created the node. """ trace.into('PackageTree', 'getInputFilename', outputLevel=TRACE_LEVEL) node_path = self.getPath(1) trace.writeVar(node_path=node_path, outputLevel=TRACE_LEVEL) filename = apply(os.path.join, node_path) trace.writeVar(filename=filename, outputLevel=TRACE_LEVEL) trace.outof(filename, outputLevel=TRACE_LEVEL) return filename def getRelativeFilename(self): """Returns the filename relative to the root of the input area. """ trace.into('PackageTree', 'getRelativeFilename', outputLevel=TRACE_LEVEL) node_path = self.getPath() trace.writeVar(node_path=node_path, outputLevel=TRACE_LEVEL) filename = apply(os.path.join, node_path) trace.writeVar(filename=filename, outputLevel=TRACE_LEVEL) trace.outof(filename, outputLevel=TRACE_LEVEL) return filename def _unquoteString(self, str): "Remove surrounding quotes from a string." str = str.strip() while ( str and (str[0] == str[-1]) and str[0] in ('"', "'") ): str = str[1:-1] return str def getDocStringAndFormat(self): # # Are we a python module? # if hasattr(self, 'module_info'): docstring = self.module_info.getDocString() docstring = self._unquoteString(docstring) format = self.module_info.getDocStringFormat() return (docstring, format) # # Are we a text file? # mimetype, encoding = self.getMimeType() if mimetype in ('text/plain', 'text/x-structured'): input_filename = self.getInputFilename() readme_text = open(input_filename, 'rt').read() format = 'StructuredText' return (readme_text, format) # # Look inside sub-nodes # for name in ('__init__.py', 'README.txt', 'README.stx'): trace.write('looking for %s' % name, outputLevel=TRACE_LEVEL) node = self.get(name) if node is not None: return node.getDocStringAndFormat() return ('', 'StructuredText') _summary_pattern = re.compile(r'^\s*([^\n]+)\n') def getSummaryAndFormat(self): if hasattr(self, 'module_info'): return self.module_info.getSummaryAndFormat() else: text, format = self.getDocStringAndFormat() text = text.strip() # # Remove surrounding quotes, if present. # while text and (text[0] in ('"', "'")): text = text[1:] while text and (text[-1] in ('"', "'")): text = text[:-1] # # Pull out the first line, and return it if # we can find it. Otherwise, return the whole # string since that means that the whole thing # is just one line. # matchObj = self._summary_pattern.search(text) if matchObj: return (matchObj.group(0).strip(), format) else: return (text, format) # # Tree methods # def getParent(self): """Returns the parent node for this tree. If there is no parent (root of the tree), returns None. """ return self.parent def getPath(self, useCanonicalName=0): """Return the path from the root to this node. Returns a tuple of node names, beginning with the root node and ending with this node. """ trace.into('PackageTree', 'getPath', useCanonicalName=useCanonicalName, outputLevel=TRACE_LEVEL+1, ) parent = self.getParent() trace.writeVar(parent=parent, outputLevel=TRACE_LEVEL+1, ) if parent: parent_path = parent.getPath(useCanonicalName=useCanonicalName) else: parent_path = () trace.writeVar(parent_path=parent_path, outputLevel=TRACE_LEVEL+1, ) if useCanonicalName: name = self.getCanonicalName() else: name = self.getName() path = parent_path + (name,) trace.outof(path, outputLevel=TRACE_LEVEL+1, ) return path def getPathToNode(self, otherNode): """Returns a sequence of nodes to be traversed to reach the otherNode. The sequence assumes that traversal begins at the current node. A '..' indicates moving up to the parent one level. """ my_path = self.getPath() other_path = otherNode.getPath() if my_path == other_path: return () # # Strip the top parts of the paths which match. # while my_path and other_path and my_path[0] == other_path[0]: my_path = my_path[1:] other_path = other_path[1:] if self.items(): is_file = 0 else: is_file = 1 going_up = ('..',) * (len(my_path) - is_file) relative_path = going_up + other_path return relative_path def findNodeFromDottedName(self, dottedNodeName, tryParent=1): """Find the node referenced by the dotted name given. The dottedNodeName 'happydoclib.scanner' retuns the node for this module. If the named node cannot be found, the return value is None. """ trace_level=TRACE_LEVEL trace.into('PackageTree', 'findNodeFromDottedName', dottedNodeName=dottedNodeName, outputLevel=trace_level, ) name_parts = dottedNodeName.split('.') name = name_parts[0] trace.write('name=%s' % name, outputLevel=trace_level, ) trace.writeVar(name=name, outputLevel=trace_level, ) named_node = None # # Is someone looking for us? # if (named_node is None): if (name == self.getName()): trace.write('Matched ourself', outputLevel=trace_level, ) named_node = self if (named_node is None): trace.write('Checking %s as child' % name, outputLevel=trace_level, ) named_node = self.get(name) if (named_node is None): trace.write('Checking %s.py as child' % name, outputLevel=trace_level, ) named_node = self.get('%s.py' % name) if (named_node is None) and tryParent: # # Try the parent with the whole name # parent = self.getParent() if parent: trace.write('Checking for %s in parent' % name, outputLevel=trace_level, ) named_node = parent.findNodeFromDottedName(dottedNodeName) # # Do we need to process the remainder of the original name? # if named_node and (len(name_parts) > 1): remainder = '.'.join(name_parts[1:]) trace.write('Handling remainder (%s)' % remainder, outputLevel=trace_level, ) named_node = named_node.findNodeFromDottedName(remainder, tryParent=0) if named_node is not None: trace.outof(named_node.getName(), outputLevel=trace_level, ) else: trace.outof(outputLevel=trace_level) return named_node def addSubNode(self, name): """Insert a child node under this node. Create a new PackageTree node, set its parent to be ourself, and save it as one of our children. """ trace.into('PackageTree', 'addSubNode', name=name, outputLevel=TRACE_LEVEL) new_node = PackageTree(self, name) self[name] = new_node trace.outof(outputLevel=TRACE_LEVEL) return new_node def getSubNodes(self, mimetype=None): """Returns the children of this node. If mimetype is not none, returns only the children with that mimetype. """ if mimetype is None: return self.values() else: if not hasattr(self, 'grouped_children'): self.grouped_children = {} for node in self.values(): mimetype, encoding = node.getMimeType() group = self.grouped_children.setdefault(mimetype, []) group.append(node) return self.grouped_children.get(mimetype, []) def walk(self, callback): """Walk the PackageTree, calling the callback at each node. """ callback(self) for child in self.values(): child.walk(callback) return --- NEW FILE: test_packagetree.py --- #!/usr/bin/env python # # $Id: test_packagetree.py,v 1.1 2002/12/29 18:35:14 doughellmann Exp $ # # Copyright 2002 Doug Hellmann. # # # 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 that both that copyright notice and this permission # notice appear in supporting documentation, and that the name of Doug # Hellmann not be used in advertising or publicity pertaining to # distribution of the software without specific, written prior # permission. # # DOUG HELLMANN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, # INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN # NO EVENT SHALL DOUG HELLMANN 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. # """Tests for packagetree module. """ __rcs_info__ = { # # Creation Information # 'module_name' : '$RCSfile: test_packagetree.py,v $', 'rcs_id' : '$Id: test_packagetree.py,v 1.1 2002/12/29 18:35:14 doughellmann Exp $', 'creator' : 'Doug Hellmann <do...@he...>', 'project' : 'HappyDoc', 'created' : 'Sun, 29-Dec-2002 12:41:21 EST', # # Current Information # 'author' : '$Author: doughellmann $', 'version' : '$Revision: 1.1 $', 'date' : '$Date: 2002/12/29 18:35:14 $', } try: __version__ = __rcs_info__['version'].split(' ')[1] except: __version__ = '0.0' # # Import system modules # import os import unittest # # Import Local modules # from happydoclib.scanner import Scanner from happydoclib.packagetree import PackageTree # # Module # class PackageTreeTestCase(unittest.TestCase): def testGetInputFilename(self): scanner = Scanner(['TestCases/testScanner']) trees = scanner.getPackageTrees() expected_tree = trees[0] self.failUnlessEqual( expected_tree.getName(), 'testScanner', 'First level tree got %s instead of testScanner' % expected_tree.getName(), ) level_one = expected_tree['levelOne'] self.failUnlessEqual( level_one.getName(), 'levelOne', 'First sub-level tree got %s instead of levelOne' % level_one.getName(), ) self.failUnlessEqual(level_one.getInputFilename(), 'TestCases/testScanner/levelOne', ) level_two = level_one['levelTwo'] self.failUnlessEqual( level_two.getName(), 'levelTwo', 'First sub-level tree got %s instead of levelTwo' % level_two.getName(), ) self.failUnlessEqual(level_two.getInputFilename(), 'TestCases/testScanner/levelOne/levelTwo', ) return def testPackageTreePath(self): scanner = Scanner(['TestCases/testScanner']) trees = scanner.getPackageTrees() expected_tree = trees[0] dir_one = expected_tree['levelOne'] dir_one_path = dir_one.getPath() self.failUnlessEqual(dir_one_path, ('testScanner', 'levelOne', )) dir_two = expected_tree['levelOne']['levelTwo'] dir_two_path = dir_two.getPath() self.failUnlessEqual(dir_two_path, ('testScanner', 'levelOne', 'levelTwo', )) module_two = expected_tree['levelOne']['levelTwo']['two.py'] module_two_path = module_two.getPath() self.failUnlessEqual(module_two_path, ('testScanner', 'levelOne', 'levelTwo', 'two.py', ), ) return def testPackageTreePath(self): cwd = os.getcwd() input_dir = os.path.join(cwd, 'TestCases/testScanner') scanner = Scanner([input_dir]) trees = scanner.getPackageTrees() expected_tree = trees[0] module_two = expected_tree['levelOne']['levelTwo']['two.py'] module_two_path = module_two.getPath(1) self.failUnlessEqual(module_two_path, (input_dir, 'levelOne', 'levelTwo', 'two.py', ), ) return def testPackageTreeIgnore(self): scanner = Scanner(['TestCases/testScanner'], ['ignoreme.py']) trees = scanner.getPackageTrees() level_one = trees[0]['levelOne'] try: ignoring = level_one['ignoreme.py'] except KeyError: pass else: self.fail('Still have ignoreme.py') return def testPackageTreeIgnoreTestFiles(self): scanner = Scanner(['happydoclib'], ['^tests.py$', '^test_.*py$', ]) trees = scanner.getPackageTrees() level_one = trees[0] for name in ('tests.py', 'test_scanner.py', ): try: ignoring = level_one[name] except KeyError: pass else: self.fail('Still have %s' % name) return def testPackageTreeName(self): tree = PackageTree(None, 'tree1') self.failUnlessEqual('tree1', tree.getName(), 'Names do not match.') return def testPackageTreeNameNotCanonical(self): tree = PackageTree(None, '/full/path/to/tree1') self.failUnlessEqual('tree1', tree.getName(), 'Names do not match.') return def testPackageTreeNameCanonical(self): tree = PackageTree(None, '/full/path/to/tree1') self.failUnlessEqual('/full/path/to/tree1', tree.getCanonicalName(), 'Names do not match.') return def testPackageTreeParent(self): tree = PackageTree(None, 'tree1') self.failUnlessEqual(None, tree.getParent(), 'Parents do not match.') return class PackageTreeRelativePathTestCase(unittest.TestCase): def setUp(self): cwd = os.getcwd() input_dir = os.path.join(cwd, 'TestCases/testScanner') scanner = Scanner([input_dir]) trees = scanner.getPackageTrees() expected_tree = trees[0] self.expected_tree = expected_tree return def testSelf(self): target = self.expected_tree['levelOne']['levelTwo']['two.py'] start = self.expected_tree['levelOne']['levelTwo']['two.py'] relative_path = start.getPathToNode(target) self.failUnlessEqual(relative_path, (), ) return def testParentDirOfModuleDir(self): target = self.expected_tree['levelOne'] start = self.expected_tree['levelOne']['levelTwo']['two.py'] relative_path = start.getPathToNode(target) self.failUnlessEqual(relative_path, ('..', ), ) return def testModuleSameDir(self): target = self.expected_tree['levelOne']['one.py'] start = self.expected_tree['levelOne']['ignoreme.py'] relative_path = start.getPathToNode(target) self.failUnlessEqual(relative_path, ('one.py', ), ) return def testModuleParentDir(self): target = self.expected_tree['levelOne']['one.py'] start = self.expected_tree['levelOne']['levelTwo']['two.py'] relative_path = start.getPathToNode(target) self.failUnlessEqual(relative_path, ('..', 'one.py', ), ) return def testParentDirOfDir(self): target = self.expected_tree['levelOne'] start = self.expected_tree['levelOne']['levelTwo'] relative_path = start.getPathToNode(target) self.failUnlessEqual(relative_path, ('..', ), ) return class PackageTreeSummaryAndDocStringTests(unittest.TestCase): def setUp(self): input_dir = os.path.join('TestCases', 'testScanner') output_dir = '/tmp/foo' scanner = Scanner([input_dir]) self.scanner = scanner return def tearDown(self): del self.scanner return def testGetReadmeTextForDirectoryInit(self): trees = self.scanner.getPackageTrees() expected_tree = trees[0]['readme_from_init'] actual, format = expected_tree.getDocStringAndFormat() expected_format = 'StructuredText' expected = 'This is the __init__.py file for readme_from_init.' self.failUnlessEqual(actual, expected) return def testGetReadmeTextForDirectoryDotTxt(self): trees = self.scanner.getPackageTrees() expected_tree = trees[0]['readme_from_readme'] actual, format = expected_tree.getDocStringAndFormat() expected_format = 'StructuredText' expected = 'This is the README.txt file for readme_from_readme.\n' self.failUnlessEqual(actual, expected) return def testGetReadmeTextForDirectoryDotStx(self): trees = self.scanner.getPackageTrees() expected_tree = trees[0]['readme_from_stx'] actual, format = expected_tree.getDocStringAndFormat() expected_format = 'StructuredText' expected = 'This is the README.stx file for readme_from_stx.\n' self.failUnlessEqual(actual, expected) return class PackageTreeFindNodeTestCase(unittest.TestCase): def setUp(self): cwd = os.getcwd() input_dir = os.path.join(cwd, 'TestCases/testScanner') scanner = Scanner([input_dir]) trees = scanner.getPackageTrees() expected_tree = trees[0] self.expected_tree = expected_tree return def _testFind(self, name, start, target): found = start.findNodeFromDottedName(name) if not found: self.fail('Did not find anything') self.failUnlessEqual(found, target) return def testFindSelf(self): self._testFind('levelOne', self.expected_tree['levelOne'], self.expected_tree['levelOne'], ) return def testFindChild(self): self._testFind('levelTwo', self.expected_tree['levelOne'], self.expected_tree['levelOne']['levelTwo'], ) return def testFindSelfDotChild(self): self._testFind('levelOne.levelTwo', self.expected_tree['levelOne'], self.expected_tree['levelOne']['levelTwo'], ) return def testFindParent(self): self._testFind('levelOne', self.expected_tree['levelOne']['levelTwo'], self.expected_tree['levelOne'], ) return def testFindSibling(self): self._testFind('readme_from_readme', self.expected_tree['levelOne'], self.expected_tree['readme_from_readme'], ) return def testFindAunt(self): self._testFind('readme_from_readme', self.expected_tree['levelOne']['levelTwo'], self.expected_tree['readme_from_readme'], ) return def testFindNeice(self): self._testFind('levelOne.levelTwo', self.expected_tree['readme_from_readme'], self.expected_tree['levelOne']['levelTwo'], ) return def testFindNotThere(self): name = 'levelOne.levelTwo.notThereAtAll' start = self.expected_tree['readme_from_readme'] found = start.findNodeFromDottedName(name) if found: self.fail('Found something unexpected') return if __name__ == '__main__': unittest.main() Index: scanner.py =================================================================== RCS file: /cvsroot/happydoc/HappyDoc3/happydoclib/scanner.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** scanner.py 29 Dec 2002 17:30:58 -0000 1.13 --- scanner.py 29 Dec 2002 18:35:14 -0000 1.14 *************** *** 59,66 **** # import glob - import mimetypes import os import re - import UserDict # --- 59,64 ---- *************** *** 68,71 **** --- 66,70 ---- # import happydoclib + from happydoclib.packagetree import PackageTree from happydoclib.status import statusMessage from happydoclib.trace import trace *************** *** 76,527 **** # ! # ! # Initialize extensions for mimetypes that we know about but which are ! # not standard. ! # ! mimetypes.types_map['.stx'] = 'text/x-structured' ! ! class PackageTree(UserDict.UserDict): ! """Tree of package information. ! ! Access each child node using the standard mapping de-reference ! syntax ([], .get(), etc.). ! """ ! ! parser_mapping = { ! 'text/x-python' : 'parsePythonInput', ! 'text/plain' : 'parsePlainTextInput', ! 'text/x-structured' : 'parseStructuredTextInput', ! } ! ! def __init__(self, parent, name): ! trace.into('PackageTree', '__init__', ! parent=parent, ! name=name, ! ) ! UserDict.UserDict.__init__(self) ! ! self.parent = parent ! ! self.name = os.path.basename(name) ! trace.write('self.name=%s' % self.name) ! self.canonical_name = name ! ! trace.outof() ! return ! ! def __repr__(self): ! base_str = UserDict.UserDict.__repr__(self) ! return '<%s %s: %s>' % (self.__class__.__name__, self.getName(), base_str) ! ! # ! # Parsing methods ! # ! ! def parsePythonInput(self): ! trace.into('PackageTree', 'parsePythonInput') ! # ! # Derive the filename for this module. ! # ! filename = self.getInputFilename() ! statusMessage('Parsing: %s' % filename) ! ! # ! # Figure out if there is a parent node for the ! # documentation suite. ! # ! package_parent = self.getParent() ! if package_parent and hasattr(package_parent, 'module_info'): ! docs_parent = package_parent.module_info ! else: ! docs_parent = None ! ! trace.writeVar(docs_parent=docs_parent) ! ! docs = happydoclib.parseinfo.getDocs( ! parent=docs_parent, ! fileName=filename, ! ) ! ! self.module_info = docs ! ! trace.outof() ! return ! ! def parsePlainTextInput(self): ! trace.into('PackageTree', 'parsePlainTextInput', ! ) ! # ! # Derive the filename for this module. ! # ! filename = self.getInputFilename() ! trace.writeVar(filename=filename) ! ! statusMessage('Importing preformatted file: %s' % filename) ! ! #f = open(filename, 'rt') ! #body = f.read() ! #f.close() ! ! #packageTreeNode.preformatted_text = body ! ! trace.outof() ! return ! ! def parseStructuredTextInput(self): ! trace.into('PackageTree', 'parseStructuredTextInput') ! self.parsePlainTextInput() ! trace.outof() ! return ! ! def parseInput(self): ! """Get whatever information is appropriate from the input file. ! """ ! trace.into('PackageTree', 'parseInput') ! ! if os.path.isdir(self.getInputFilename()): ! trace.write('directory') ! trace.outof() ! return ! ! mimetype, encoding = self.getMimeType() ! try: ! parse_method_name = self.parser_mapping[mimetype] ! except KeyError: ! # ! # Don't know what to do with this file. ! # ! statusMessage('Not parsing input %s with mimetype %s' % ( ! self.getInputFilename(), ! mimetype, ! ), 2) ! else: ! # ! # Call the parse method ! # ! parse_method = getattr(self, parse_method_name) ! parse_method() ! ! trace.outof() ! return ! ! # ! # Data retrieval methods ! # ! ! def getMimeType(self): ! """Returns the (mimetype, encoding) setting for this node. ! """ ! trace.into('PackageTreeNode', 'getMimeType', ! name=self.name, ! ) ! ! input_filename = self.getInputFilename() ! mimetype = mimetypes.guess_type(input_filename) ! ! if mimetype == (None, None): ! if isSomethingThatLooksLikeDirectory(input_filename): ! mimetype = ('application/x-directory', None) ! ! trace.outof(mimetype) ! return mimetype ! ! def getName(self): ! """Returns the name of this tree node. ! """ ! return self.name ! ! def getCanonicalName(self): ! """Returns the canonical, full, name of the this tree node. ! """ ! return self.canonical_name ! ! def getInputFilename(self): ! """Returns the original input filename that created the node. ! """ ! trace.into('PackageTree', 'getInputFilename') ! ! node_path = self.getPath(1) ! trace.writeVar(node_path=node_path) ! filename = apply(os.path.join, node_path) ! trace.writeVar(filename=filename) ! ! trace.outof(filename) ! return filename ! ! def getRelativeFilename(self): ! """Returns the filename relative to the root of the input area. ! """ ! trace.into('PackageTree', 'getRelativeFilename') ! ! node_path = self.getPath() ! trace.writeVar(node_path=node_path) ! filename = apply(os.path.join, node_path) ! trace.writeVar(filename=filename) ! ! trace.outof(filename) ! return filename ! ! def _unquoteString(self, str): ! "Remove surrounding quotes from a string." ! str = str.strip() ! while ( str ! and ! (str[0] == str[-1]) ! and ! str[0] in ('"', "'") ! ): ! str = str[1:-1] ! return str ! ! def getDocStringAndFormat(self): ! # ! # Are we a python module? ! # ! if hasattr(self, 'module_info'): ! docstring = self.module_info.getDocString() ! docstring = self._unquoteString(docstring) ! format = self.module_info.getDocStringFormat() ! return (docstring, format) ! ! # ! # Are we a text file? ! # ! mimetype, encoding = self.getMimeType() ! if mimetype in ('text/plain', 'text/x-structured'): ! input_filename = self.getInputFilename() ! readme_text = open(input_filename, 'rt').read() ! format = 'StructuredText' ! return (readme_text, format) ! ! # ! # Look inside sub-nodes ! # ! for name in ('__init__.py', 'README.txt', 'README.stx'): ! trace.write('looking for %s' % name) ! node = self.get(name) ! if node is not None: ! return node.getDocStringAndFormat() ! ! return ('', 'StructuredText') ! ! _summary_pattern = re.compile(r'^\s*([^\n]+)\n') ! def getSummaryAndFormat(self): ! if hasattr(self, 'module_info'): ! return self.module_info.getSummaryAndFormat() ! else: ! text, format = self.getDocStringAndFormat() ! text = text.strip() ! # ! # Remove surrounding quotes, if present. ! # ! while text and (text[0] in ('"', "'")): ! text = text[1:] ! while text and (text[-1] in ('"', "'")): ! text = text[:-1] ! # ! # Pull out the first line, and return it if ! # we can find it. Otherwise, return the whole ! # string since that means that the whole thing ! # is just one line. ! # ! matchObj = self._summary_pattern.search(text) ! if matchObj: ! return (matchObj.group(0).strip(), format) ! else: ! return (text, format) ! ! ! # ! # Tree methods ! # ! ! def getParent(self): ! """Returns the parent node for this tree. ! ! If there is no parent (root of the tree), returns None. ! """ ! return self.parent ! ! def getPath(self, useCanonicalName=0): ! """Return the path from the root to this node. ! ! Returns a tuple of node names, beginning with the root node ! and ending with this node. ! """ ! trace.into('PackageTree', 'getPath', ! useCanonicalName=useCanonicalName, ! outputLevel=2, ! ) ! ! parent = self.getParent() ! trace.writeVar(parent=parent, ! outputLevel=2, ! ) ! if parent: ! parent_path = parent.getPath(useCanonicalName=useCanonicalName) ! else: ! parent_path = () ! ! trace.writeVar(parent_path=parent_path, ! outputLevel=2, ! ) ! ! if useCanonicalName: ! name = self.getCanonicalName() ! else: ! name = self.getName() ! ! path = parent_path + (name,) ! ! trace.outof(path, ! outputLevel=2, ! ) ! return path ! ! def getPathToNode(self, otherNode): ! """Returns a sequence of nodes to be traversed to reach the otherNode. ! ! The sequence assumes that traversal begins at the current node. ! A '..' indicates moving up to the parent one level. ! """ ! my_path = self.getPath() ! other_path = otherNode.getPath() ! if my_path == other_path: ! return () ! ! # ! # Strip the top parts of the paths which match. ! # ! while my_path and other_path and my_path[0] == other_path[0]: ! my_path = my_path[1:] ! other_path = other_path[1:] ! ! if self.items(): ! is_file = 0 ! else: ! is_file = 1 ! ! going_up = ('..',) * (len(my_path) - is_file) ! ! relative_path = going_up + other_path ! ! return relative_path ! ! def findNodeFromDottedName(self, dottedNodeName, tryParent=1): ! """Find the node referenced by the dotted name given. ! ! The dottedNodeName 'happydoclib.scanner' retuns the node for ! this module. If the named node cannot be found, the return ! value is None. ! """ ! trace_level=1 ! trace.into('PackageTree', 'findNodeFromDottedName', ! dottedNodeName=dottedNodeName, ! outputLevel=trace_level, ! ) ! ! name_parts = dottedNodeName.split('.') ! name = name_parts[0] ! ! trace.write('name=%s' % name, ! outputLevel=trace_level, ! ) ! trace.writeVar(name=name, ! outputLevel=trace_level, ! ) ! ! named_node = None ! ! # ! # Is someone looking for us? ! # ! if (named_node is None): ! if (name == self.getName()): ! trace.write('Matched ourself', ! outputLevel=trace_level, ! ) ! named_node = self ! ! if (named_node is None): ! trace.write('Checking %s as child' % name, ! outputLevel=trace_level, ! ) ! named_node = self.get(name) ! ! if (named_node is None): ! trace.write('Checking %s.py as child' % name, ! outputLevel=trace_level, ! ) ! named_node = self.get('%s.py' % name) ! ! if (named_node is None) and tryParent: ! # ! # Try the parent with the whole name ! # ! parent = self.getParent() ! if parent: ! trace.write('Checking for %s in parent' % name, ! outputLevel=trace_level, ! ) ! named_node = parent.findNodeFromDottedName(dottedNodeName) ! ! # ! # Do we need to process the remainder of the original name? ! # ! if named_node and (len(name_parts) > 1): ! remainder = '.'.join(name_parts[1:]) ! trace.write('Handling remainder (%s)' % remainder, ! outputLevel=trace_level, ! ) ! named_node = named_node.findNodeFromDottedName(remainder, ! tryParent=0) ! ! if named_node is not None: ! trace.outof(named_node.getName(), ! outputLevel=trace_level, ! ) ! else: ! trace.outof(outputLevel=trace_level) ! return named_node ! ! def addSubNode(self, name): ! """Insert a child node under this node. ! ! Create a new PackageTree node, set its parent to be ourself, ! and save it as one of our children. ! """ ! trace.into('PackageTree', 'addSubNode', name=name) ! new_node = PackageTree(self, name) ! self[name] = new_node ! trace.outof() ! return new_node ! ! def getSubNodes(self, mimetype=None): ! """Returns the children of this node. ! ! If mimetype is not none, returns only the children with that ! mimetype. ! """ ! if mimetype is None: ! return self.values() ! else: ! if not hasattr(self, 'grouped_children'): ! self.grouped_children = {} ! for node in self.values(): ! mimetype, encoding = node.getMimeType() ! group = self.grouped_children.setdefault(mimetype, []) ! group.append(node) ! return self.grouped_children.get(mimetype, []) ! ! def walk(self, callback): ! """Walk the PackageTree, calling the callback at each node. ! """ ! callback(self) ! for child in self.values(): ! child.walk(callback) ! return ! ! class Scanner: --- 75,79 ---- # ! TRACE_LEVEL=2 class Scanner: *************** *** 541,544 **** --- 93,97 ---- ignorePatterns=ignorePatterns, includeComments=includeComments, + outputLevel=TRACE_LEVEL, ) *************** *** 564,568 **** self._parsePackageTree() ! trace.outof() return --- 117,121 ---- self._parsePackageTree() ! trace.outof(outputLevel=TRACE_LEVEL) return *************** *** 586,591 **** trace.into('Scanner', 'buildPackageTree', directoryName=directoryName, ! parent=parent, ) package_tree_name = os.path.basename(directoryName) --- 139,152 ---- trace.into('Scanner', 'buildPackageTree', directoryName=directoryName, ! #parent=parent, ! outputLevel=TRACE_LEVEL, ) + + if parent is not None: + trace.writeVar(parent=parent.getName(), + outputLevel=TRACE_LEVEL) + else: + trace.writeVar(parent=parent, + outputLevel=TRACE_LEVEL) package_tree_name = os.path.basename(directoryName) *************** *** 598,604 **** if ignore_re.search(package_tree_name): trace.write('Ignoring because "%s" matched %s' % (package_tree_name, ! ignore_re.pattern) ) ! trace.outof() return None --- 159,166 ---- if ignore_re.search(package_tree_name): trace.write('Ignoring because "%s" matched %s' % (package_tree_name, ! ignore_re.pattern), ! outputLevel=TRACE_LEVEL, ) ! trace.outof(outputLevel=TRACE_LEVEL) return None *************** *** 618,622 **** # Get directory contents # ! trace.write('Scanning %s' % directoryName) pattern = os.path.join(directoryName, '*') contents = glob.glob(pattern) --- 180,185 ---- # Get directory contents # ! trace.write('Scanning %s' % directoryName, ! outputLevel=TRACE_LEVEL) pattern = os.path.join(directoryName, '*') contents = glob.glob(pattern) *************** *** 628,632 **** self.buildPackageTree(subnode_name, tree) ! trace.outof() return tree --- 191,195 ---- self.buildPackageTree(subnode_name, tree) ! trace.outof(outputLevel=TRACE_LEVEL) return tree Index: test_scanner.py =================================================================== RCS file: /cvsroot/happydoc/HappyDoc3/happydoclib/test_scanner.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** test_scanner.py 28 Dec 2002 16:41:31 -0000 1.9 --- test_scanner.py 29 Dec 2002 18:35:14 -0000 1.10 *************** *** 61,65 **** # Import Local modules # ! from happydoclib.scanner import Scanner, PackageTree --- 61,65 ---- # Import Local modules # ! from happydoclib.scanner import Scanner *************** *** 195,540 **** self.failUnlessEqual(mimetype, ('text/x-structured', None)) - return - - def testGetInputFilename(self): - scanner = Scanner(['TestCases/testScanner']) - - trees = scanner.getPackageTrees() - - expected_tree = trees[0] - self.failUnlessEqual( - expected_tree.getName(), - 'testScanner', - 'First level tree got %s instead of testScanner' % expected_tree.getName(), - ) - - level_one = expected_tree['levelOne'] - self.failUnlessEqual( - level_one.getName(), - 'levelOne', - 'First sub-level tree got %s instead of levelOne' % level_one.getName(), - ) - self.failUnlessEqual(level_one.getInputFilename(), - 'TestCases/testScanner/levelOne', - ) - - level_two = level_one['levelTwo'] - self.failUnlessEqual( - level_two.getName(), - 'levelTwo', - 'First sub-level tree got %s instead of levelTwo' % level_two.getName(), - ) - self.failUnlessEqual(level_two.getInputFilename(), - 'TestCases/testScanner/levelOne/levelTwo', - ) - - return - - def testPackageTreePath(self): - scanner = Scanner(['TestCases/testScanner']) - - trees = scanner.getPackageTrees() - expected_tree = trees[0] - - dir_one = expected_tree['levelOne'] - dir_one_path = dir_one.getPath() - self.failUnlessEqual(dir_one_path, - ('testScanner', - 'levelOne', - )) - - dir_two = expected_tree['levelOne']['levelTwo'] - dir_two_path = dir_two.getPath() - self.failUnlessEqual(dir_two_path, - ('testScanner', - 'levelOne', - 'levelTwo', - )) - - module_two = expected_tree['levelOne']['levelTwo']['two.py'] - - module_two_path = module_two.getPath() - self.failUnlessEqual(module_two_path, - ('testScanner', - 'levelOne', - 'levelTwo', - 'two.py', - ), - ) - return - - def testPackageTreePath(self): - cwd = os.getcwd() - input_dir = os.path.join(cwd, 'TestCases/testScanner') - scanner = Scanner([input_dir]) - - trees = scanner.getPackageTrees() - expected_tree = trees[0] - - module_two = expected_tree['levelOne']['levelTwo']['two.py'] - - module_two_path = module_two.getPath(1) - self.failUnlessEqual(module_two_path, - (input_dir, - 'levelOne', - 'levelTwo', - 'two.py', - ), - ) - return - - def testPackageTreeIgnore(self): - scanner = Scanner(['TestCases/testScanner'], ['ignoreme.py']) - - trees = scanner.getPackageTrees() - level_one = trees[0]['levelOne'] - - try: - ignoring = level_one['ignoreme.py'] - except KeyError: - pass - else: - self.fail('Still have ignoreme.py') - - return - - def testPackageTreeIgnoreTestFiles(self): - scanner = Scanner(['happydoclib'], ['^tests.py$', - '^test_.*py$', - ]) - - trees = scanner.getPackageTrees() - level_one = trees[0] - - for name in ('tests.py', - 'test_scanner.py', - ): - try: - ignoring = level_one[name] - except KeyError: - pass - else: - self.fail('Still have %s' % name) - - return - - def testPackageTreeName(self): - tree = PackageTree(None, 'tree1') - self.failUnlessEqual('tree1', tree.getName(), - 'Names do not match.') - return - - def testPackageTreeNameNotCanonical(self): - tree = PackageTree(None, '/full/path/to/tree1') - self.failUnlessEqual('tree1', tree.getName(), - 'Names do not match.') - return - - def testPackageTreeNameCanonical(self): - tree = PackageTree(None, '/full/path/to/tree1') - self.failUnlessEqual('/full/path/to/tree1', tree.getCanonicalName(), - 'Names do not match.') - return - - def testPackageTreeParent(self): - tree = PackageTree(None, 'tree1') - self.failUnlessEqual(None, tree.getParent(), - 'Parents do not match.') - return - - class ScannerRelativePathTestCase(unittest.TestCase): - - def setUp(self): - cwd = os.getcwd() - input_dir = os.path.join(cwd, 'TestCases/testScanner') - scanner = Scanner([input_dir]) - - trees = scanner.getPackageTrees() - expected_tree = trees[0] - self.expected_tree = expected_tree - return - - def testSelf(self): - target = self.expected_tree['levelOne']['levelTwo']['two.py'] - start = self.expected_tree['levelOne']['levelTwo']['two.py'] - - relative_path = start.getPathToNode(target) - self.failUnlessEqual(relative_path, - (), - ) - return - - def testParentDirOfModuleDir(self): - target = self.expected_tree['levelOne'] - start = self.expected_tree['levelOne']['levelTwo']['two.py'] - - relative_path = start.getPathToNode(target) - self.failUnlessEqual(relative_path, - ('..', - ), - ) - return - - def testModuleSameDir(self): - target = self.expected_tree['levelOne']['one.py'] - start = self.expected_tree['levelOne']['ignoreme.py'] - - relative_path = start.getPathToNode(target) - self.failUnlessEqual(relative_path, - ('one.py', - ), - ) - return - - def testModuleParentDir(self): - target = self.expected_tree['levelOne']['one.py'] - start = self.expected_tree['levelOne']['levelTwo']['two.py'] - - relative_path = start.getPathToNode(target) - self.failUnlessEqual(relative_path, - ('..', - 'one.py', - ), - ) - return - - def testParentDirOfDir(self): - target = self.expected_tree['levelOne'] - start = self.expected_tree['levelOne']['levelTwo'] - - relative_path = start.getPathToNode(target) - self.failUnlessEqual(relative_path, - ('..', - ), - ) - return - - - class ScannerSummaryAndDocStringTests(unittest.TestCase): - - def setUp(self): - input_dir = os.path.join('TestCases', 'testScanner') - output_dir = '/tmp/foo' - - scanner = Scanner([input_dir]) - - self.scanner = scanner - return - - def tearDown(self): - del self.scanner - return - - def testGetReadmeTextForDirectoryInit(self): - trees = self.scanner.getPackageTrees() - expected_tree = trees[0]['readme_from_init'] - - actual, format = expected_tree.getDocStringAndFormat() - - expected_format = 'StructuredText' - expected = 'This is the __init__.py file for readme_from_init.' - - self.failUnlessEqual(actual, expected) - return - - def testGetReadmeTextForDirectoryDotTxt(self): - trees = self.scanner.getPackageTrees() - expected_tree = trees[0]['readme_from_readme'] - - actual, format = expected_tree.getDocStringAndFormat() - - expected_format = 'StructuredText' - expected = 'This is the README.txt file for readme_from_readme.\n' - - self.failUnlessEqual(actual, expected) - return - - def testGetReadmeTextForDirectoryDotStx(self): - trees = self.scanner.getPackageTrees() - expected_tree = trees[0]['readme_from_stx'] - - actual, format = expected_tree.getDocStringAndFormat() - - expected_format = 'StructuredText' - expected = 'This is the README.stx file for readme_from_stx.\n' - - self.failUnlessEqual(actual, expected) - return - - class ScannerFindNodeTestCase(unittest.TestCase): - - def setUp(self): - cwd = os.getcwd() - input_dir = os.path.join(cwd, 'TestCases/testScanner') - scanner = Scanner([input_dir]) - - trees = scanner.getPackageTrees() - expected_tree = trees[0] - self.expected_tree = expected_tree - return - - def _testFind(self, name, start, target): - found = start.findNodeFromDottedName(name) - if not found: - self.fail('Did not find anything') - self.failUnlessEqual(found, target) - return - - def testFindSelf(self): - self._testFind('levelOne', - self.expected_tree['levelOne'], - self.expected_tree['levelOne'], - ) - return - - def testFindChild(self): - self._testFind('levelTwo', - self.expected_tree['levelOne'], - self.expected_tree['levelOne']['levelTwo'], - ) - return - - def testFindSelfDotChild(self): - self._testFind('levelOne.levelTwo', - self.expected_tree['levelOne'], - self.expected_tree['levelOne']['levelTwo'], - ) - return - - def testFindParent(self): - self._testFind('levelOne', - self.expected_tree['levelOne']['levelTwo'], - self.expected_tree['levelOne'], - ) - return - - def testFindSibling(self): - self._testFind('readme_from_readme', - self.expected_tree['levelOne'], - self.expected_tree['readme_from_readme'], - ) - return - - def testFindAunt(self): - self._testFind('readme_from_readme', - self.expected_tree['levelOne']['levelTwo'], - self.expected_tree['readme_from_readme'], - ) - return - - def testFindNeice(self): - self._testFind('levelOne.levelTwo', - self.expected_tree['readme_from_readme'], - self.expected_tree['levelOne']['levelTwo'], - ) - return - - def testFindNotThere(self): - name = 'levelOne.levelTwo.notThereAtAll' - start = self.expected_tree['readme_from_readme'] - found = start.findNodeFromDottedName(name) - - if found: - self.fail('Found somethi... [truncated message content] |