Changeset 33
- Timestamp:
- 05/31/06 17:32:14 (7 years ago)
- Files:
-
- branches/mk/cheesecake/codeparser.py (modified) (5 diffs)
- branches/mk/tests/_helper_cheesecake.py (added)
- branches/mk/tests/data/module1.py (modified) (2 diffs)
- branches/mk/tests/test_code_parser.py (modified) (4 diffs)
- branches/mk/tests/test_count_files.py (modified) (1 diff)
- branches/mk/tests/test_index_docstrings.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/mk/cheesecake/codeparser.py
r32 r33 1 1 import os 2 import re 3 2 4 from model import System, Module, Class, Function, parseFile, processModuleAst 3 5 6 def use_reST(text): 7 """Return True if text includes reST and False otherwise. 8 9 See http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html 10 for reference. 11 12 >>> use_reST("String with *emphasis*.") 13 True 14 >>> use_reST("*Multi-word emphasis.*") 15 True 16 >>> use_reST("How about testing **strong string**?") 17 True 18 >>> use_reST("Some *noisy!* punctuation") 19 True 20 >>> use_reST("**characters?**, in the way.") 21 True 22 >>> use_reST("Don\'t forget ``inline literals``.") 23 True 24 >>> use_reST("This is reST (hyperlink_).") 25 True 26 >>> use_reST("This is (`quite long hyperlink`_).") 27 True 28 >>> use_reST("* Bullet\\n* List\\n") 29 True 30 >>> use_reST(":Field: list\\n:indeed: it is\\n") 31 True 32 33 >>> use_reST("Plain string.") 34 False 35 >>> use_reST("Do some math: 2 * 2a* 2 = 8a") 36 False 37 >>> use_reST("Not*really*strong.") 38 False 39 >>> use_reST("Interpreted `text` is widely used as quotes, so exclude it.") 40 False 41 >>> use_reST("Not a :field:.") 42 False 43 """ 44 def compile(pattern, user_map=None): 45 """Compile a regex pattern using default or user mapping. 46 """ 47 48 # Word in reST can also contain hyphens and punctuation characters. 49 mapping = {'ALPHA': r'[-.,?!\w]', 'WORD': r'[-.,?!\s\w]', 50 'START': r'(^|\s)', 'END': r'([.,?!\s]|$)'} 51 52 if user_map: 53 mapping = mapping.copy() 54 mapping.update(user_map) 55 56 def sub(text, mapping): 57 for From, To in mapping.iteritems(): 58 text = text.replace(From, To) 59 return text 60 61 return re.compile(sub(pattern, mapping), re.LOCALE | re.VERBOSE) 62 63 def inline_markup(start, end=None, mapping=None): 64 if not end: 65 end = start 66 return compile(r'''(START %(start)s ALPHA %(end)s END) | 67 (START %(start)s ALPHA WORD* ALPHA %(end)s END)'''\ 68 % {'start': start, 'end': end}, mapping) 69 70 def line_markup(start, end=None): 71 return inline_markup(start, end, mapping={'ALPHA': r'[-.,?!\s\w]', 72 'START': r'(\n|^)[\ \t]*', 73 'END': r''}) 74 75 emphasis_pattern = inline_markup(r'\*') 76 strong_pattern = inline_markup(r'\*\*') 77 inline_pattern = inline_markup(r'``') 78 hyperlink_pattern = inline_markup(r'\(', r'_\)', 79 {'ALPHA': r'\w', 'WORD': r'[-.\w]'}) 80 long_hyperlink_pattern = inline_markup(r'\(`', r'`_\)') 81 field_pattern = line_markup(r':') 82 bullet_pattern = line_markup(r'\*', r'') 83 84 rest_patterns = [strong_pattern, 85 emphasis_pattern, 86 inline_pattern, 87 hyperlink_pattern, 88 long_hyperlink_pattern, 89 field_pattern, 90 bullet_pattern] 91 92 for pattern in rest_patterns: 93 if re.search(pattern, text): 94 return True 95 96 return False 97 98 4 99 class CodeParser(object): 5 """ 6 Information about the structure of a Python module 100 """Information about the structure of a Python module. 7 101 8 102 * Collects modules, classes, methods, functions and associated docstrings … … 20 114 self.method_func = [] 21 115 self.functions = [] 22 self.docstrings = {} 116 self.docstrings = [] # objects that have docstrings 117 self.rest_docstrings = [] # objects that have docstrings with reST 23 118 24 119 (path, filename) = os.path.split(pyfile) … … 41 136 self.method_func.append(fullname) 42 137 if isinstance(obj.docstring, str) and obj.docstring.strip(): 43 self.docstrings[fullname] = 1 138 self.docstrings.append(fullname) 139 if use_reST(obj.docstring): 140 self.rest_docstrings.append(fullname) 44 141 45 142 for method_or_func in self.method_func: … … 59 156 60 157 def object_count(self): 61 """ 62 Return number of objects found in this module 158 """Return number of objects found in this module. 63 159 160 Objects include: 64 161 * module 65 162 * classes … … 74 171 75 172 def docstring_count(self): 173 """Return number of docstrings found in this module 76 174 """ 77 Return number of docstrings found in this module 175 return len(self.docstrings) 176 177 def rest_docstring_count(self): 178 """Return number of reST docstrings found in this module 78 179 """ 79 return len(self. docstrings.keys())180 return len(self.rest_docstrings) 80 181 81 182 def functions_called(self): branches/mk/tests/data/module1.py
r32 r33 36 36 pass 37 37 38 def method5(self): 39 """Method with few definitions. 40 41 :Word: And its definition. 42 """ 43 pass 44 38 45 class Class2: 39 46 … … 71 78 """ 72 79 pass 80 81 def func7(): 82 "Time to get *a bit* of reST." 83 pass branches/mk/tests/test_code_parser.py
r32 r33 2 2 3 3 import _path_cheesecake 4 from _helper_cheesecake import set 5 4 6 from cheesecake.codeparser import CodeParser 5 7 … … 22 24 "module1.Class1.method2", 23 25 "module1.Class1.method3", 24 "module1.Class1.method4"] 26 "module1.Class1.method4", 27 "module1.Class1.method5",] 25 28 26 29 def test_functions(self): … … 31 34 "module1.func4", 32 35 "module1.__func5__", 33 "module1.func6"] 36 "module1.func6", 37 "module1.func7"] 34 38 35 39 def test_count(self): 36 assert self.code1.object_count() == 15 37 assert self.code1.docstring_count() == 12 40 assert self.code1.object_count() == 17 41 assert self.code1.docstring_count() == 14 42 assert self.code1.rest_docstring_count() == 2 38 43 39 44 def test_docstrings(self): … … 47 52 "module1.Class1.method2", 48 53 "module1.Class1.method3", 54 "module1.Class1.method5", 49 55 "module1.func1", 50 56 "module1.func2", 51 57 "module1.func3", 52 58 "module1.__func5__", 59 "module1.func7", 53 60 ] 54 61 55 objects_without_docstrings = [ 56 "module1.Class1.method4", 57 "module1.func4", 58 "module1.func6", 62 objects_with_rest_docstrings = [ 63 "module1.Class1.method5", 64 "module1.func7", 59 65 ] 60 66 61 67 print self.code1.docstrings 62 68 63 for obj in objects_with_docstrings: 64 assert self.code1.docstrings.get(obj) == 1 65 66 for obj in objects_without_docstrings: 67 assert not self.code1.docstrings.get(obj) 69 assert set(objects_with_docstrings) == set(self.code1.docstrings) 70 assert set(objects_with_rest_docstrings) == set(self.code1.rest_docstrings) branches/mk/tests/test_count_files.py
r29 r33 1 1 2 2 from _mockup_cheesecake import MockupCheesecakeTest 3 4 if 'set' not in dir(__builtins__): 5 from sets import Set as set 3 from _helper_cheesecake import set 6 4 7 5 branches/mk/tests/test_index_docstrings.py
r2 r33 1 import os 2 from math import ceil 3 1 4 import _path_cheesecake 2 5 from cheesecake.cheesecake_index import Cheesecake, CodeParser 3 import os 4 from math import ceil 6 5 7 datadir = os.path.abspath(os.path.join(os.path.dirname(__file__), "data")) 6 8 7 class TestIndexDocstrings :9 class TestIndexDocstrings(object): 8 10 def setUp(self): 9 11 self.cheesecake = Cheesecake(path=os.path.join(datadir, "package1.tar.gz"))
