py2d.py :  » Windows » pyExcelerator » pywin32-214 » AutoDuck » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Windows » pyExcelerator 
pyExcelerator » pywin32 214 » AutoDuck » py2d.py
import sys
import types
import re

def ad_escape(s):
    return re.sub(r"([^<]*)<([^>]*)>", r"\g<1>\\<\g<2>\\>", s)

class DocInfo:
    def __init__(self, name, ob):
        self.name = name
        self.ob = ob
        self.short_desc = ""
        self.desc = ""

def BuildArgInfos(ob):
    ret = []
    vars = list(ob.func_code.co_varnames[:ob.func_code.co_argcount])
    vars.reverse() # for easier default checking.
    defs = list(ob.func_defaults or [])
    for i, n in enumerate(vars):
        info = DocInfo(n, ob)
        info.short_desc = info.desc = n
        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()
    return ret

def BuildInfo(name, ob):
    ret = DocInfo(name, ob)
    docstring = ob.__doc__ or ""
    ret.desc = ret.short_desc = docstring.strip()
    if ret.desc:
        ret.short_desc = ret.desc.splitlines()[0]
    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)

def build_module(fp, mod_name):
    __import__(mod_name)
    mod = sys.modules[mod_name]
    functions = []
    classes = []
    constants = []
    for name, ob in mod.__dict__.items():
        if name.startswith("_"):
            continue
        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:
            functions.append(BuildInfo(name, ob))
        elif name.upper()==name and type(ob) in (int, str):
            constants.append( (name, ob) )
    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))
        for ai in BuildArgInfos(ob.ob):
            print >> fp, "// @pyparm |%s|%s|%s" % (ai.name, ai.default, ai.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, "// @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)
                
    for (name, val) in constants:
        desc = "%s = %r" % (name, val)
        if type(val) in (int, long):
            desc += " (0x%x)" % (val,)
        print >> fp, "// @const %s|%s|%s" % (mod_name, name, desc)

def main(fp, args):
    print >> fp, "// @doc"
    for arg in args:
        build_module(sys.stdout, arg)

if __name__=='__main__':
    main(sys.stdout, sys.argv[1:])
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.