[pywin32-checkins] pywin32/AutoDuck py2d.py,1.1,1.2
OLD project page for the Python extensions for Windows
Brought to you by:
mhammond
|
From: Mark H. <mha...@us...> - 2009-01-28 10:47:17
|
Update of /cvsroot/pywin32/pywin32/AutoDuck In directory ddv4jf1.ch3.sourceforge.com:/tmp/cvs-serv32745 Modified Files: py2d.py Log Message: improve .d generation for modules with doctests Index: py2d.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/AutoDuck/py2d.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** py2d.py 11 Sep 2004 07:43:38 -0000 1.1 --- py2d.py 28 Jan 2009 10:47:10 -0000 1.2 *************** *** 1,4 **** --- 1,8 ---- import sys import types + import re + + def ad_escape(s): + return re.sub(r"([^<]*)<([^>]*)>", r"\g<1>\\<\g<2>\\>", s) class DocInfo: *************** *** 19,23 **** info.default = "" if len(defs): ! info.default = defs.pop() ret.append(info) ret.reverse() --- 23,30 ---- info.default = "" if len(defs): ! default = repr(defs.pop()) ! # the default may be an object, so the repr gives '<...>' - and ! # the angle brackets screw autoduck. ! info.default = default.replace("<", "").replace(">", "") ret.append(info) ret.reverse() *************** *** 32,45 **** return ret def format_desc(desc): if not desc: return "" ! lines = desc.splitlines() ! chunks = [lines[0]] ! for line in lines[1:]: ! line = line.strip() ! if not line: ! line = "<nl>" ! chunks.append( "// " + line ) return "\n".join(chunks) --- 39,85 ---- return ret + def should_build_function(build_info): + return build_info.ob.__doc__ and not build_info.ob.__name__.startswith('_') + + # docstring aware paragraph generator. Isn't there something in docutils + # we can use? + def gen_paras(val): + chunks = [] + in_docstring = False + for line in val.splitlines(): + line = ad_escape(line.strip()) + if not line or (not in_docstring and line.startswith(">>> ")): + if chunks: + yield chunks + chunks = [] + if not line: + in_docstring = False + continue + in_docstring = True + chunks.append(line) + yield chunks or [''] + def format_desc(desc): + # A little complicated! Given the docstring for a module, we want to: + # write: + # 'first_para_of_docstring' + # '@comm next para of docstring' + # '@comm next para of docstring' ... etc + # BUT - also handling enbedded doctests, where we write + # '@iex >>> etc.' if not desc: return "" ! g = gen_paras(desc) ! first = g.next() ! chunks = [first[0]] ! chunks.extend(["// " + l for l in first[1:]]) ! for lines in g: ! first = lines[0] ! if first.startswith(">>> "): ! prefix = "// @iex \n// " ! else: ! prefix = "\n// @comm " ! chunks.append(prefix + first) ! chunks.extend(["// " + l for l in lines[1:]]) return "\n".join(chunks) *************** *** 55,59 **** if hasattr(ob, "__module__") and ob.__module__ != mod_name: continue ! if type(ob)==types.ClassType: classes.append(BuildInfo(name, ob)) elif type(ob)==types.FunctionType: --- 95,99 ---- if hasattr(ob, "__module__") and ob.__module__ != mod_name: continue ! if type(ob) in [types.ClassType, type]: classes.append(BuildInfo(name, ob)) elif type(ob)==types.FunctionType: *************** *** 63,68 **** --- 103,115 ---- info = BuildInfo(mod_name, mod) print >> fp, "// @module %s|%s" % (mod_name, format_desc(info.desc)) + functions = [f for f in functions if should_build_function(f)] for ob in functions: print >> fp, "// @pymeth %s|%s" % (ob.name, ob.short_desc) + for ob in classes: + # only classes with docstrings get printed. + if not ob.ob.__doc__: + continue + ob_name = mod_name + "." + ob.name + print >> fp, "// @pyclass %s|%s" % (ob.name, ob.short_desc) for ob in functions: print >> fp, "// @pymethod |%s|%s|%s" % (mod_name, ob.name, format_desc(ob.desc)) *************** *** 71,85 **** for ob in classes: ob_name = mod_name + "." + ob.name print >> fp, "// @object %s|%s" % (ob_name, format_desc(ob.desc)) func_infos = [] ! for n, o in ob.ob.__dict__.items(): ! if type(o)==types.FunctionType: info = BuildInfo(n, o) ! func_infos.append(info) for fi in func_infos: print >> fp, "// @pymeth %s|%s" % (fi.name, fi.short_desc) for fi in func_infos: print >> fp, "// @pymethod |%s|%s|%s" % (ob_name, fi.name, format_desc(fi.desc)) for ai in BuildArgInfos(fi.ob): print >> fp, "// @pyparm |%s|%s|%s" % (ai.name, ai.default, ai.short_desc) --- 118,142 ---- for ob in classes: + # only classes with docstrings get printed. + if not ob.ob.__doc__: + continue ob_name = mod_name + "." + ob.name print >> fp, "// @object %s|%s" % (ob_name, format_desc(ob.desc)) func_infos = [] ! # We need to iter the keys then to a getattr() so the funky descriptor ! # things work. ! for n in ob.ob.__dict__.iterkeys(): ! o = getattr(ob.ob, n) ! if isinstance(o, (types.FunctionType, types.MethodType)): info = BuildInfo(n, o) ! if should_build_function(info): ! func_infos.append(info) for fi in func_infos: print >> fp, "// @pymeth %s|%s" % (fi.name, fi.short_desc) for fi in func_infos: print >> fp, "// @pymethod |%s|%s|%s" % (ob_name, fi.name, format_desc(fi.desc)) + if hasattr(fi.ob, 'im_self') and fi.ob.im_self is ob.ob: + print >> fp, "// @comm This is a @classmethod." + print >> fp, "// @pymethod |%s|%s|%s" % (ob_name, fi.name, format_desc(fi.desc)) for ai in BuildArgInfos(fi.ob): print >> fp, "// @pyparm |%s|%s|%s" % (ai.name, ai.default, ai.short_desc) |