]> git.saurik.com Git - wxWidgets.git/blobdiff - wxPython/wx/py/wxd/decorator.py
Merged the wxPy_newswig branch into the HEAD branch (main trunk)
[wxWidgets.git] / wxPython / wx / py / wxd / decorator.py
diff --git a/wxPython/wx/py/wxd/decorator.py b/wxPython/wx/py/wxd/decorator.py
new file mode 100644 (file)
index 0000000..1139d0b
--- /dev/null
@@ -0,0 +1,93 @@
+"""Decorator utility for documentation and shell scripting."""
+
+__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
+__cvsid__ = "$Id$"
+__revision__ = "$Revision$"[11:-2]
+
+
+import inspect
+
+try:
+    True
+except NameError:
+    True = 1==1
+    False = 1==0
+
+def decorate(real, decoration):
+    """Decorate real module with docstrings from decoration module."""
+    realdict = real.__dict__
+    for item in decoration.__dict__.values():
+        if inspect.isclass(item):
+            decorateClass(item, realdict)
+        elif inspect.isfunction(item):
+            decorateFunction(item, realdict)
+
+def decorateClass(item, realdict):
+    classname = item.__name__
+    if not classname.startswith('wx'):
+        classname = 'wx' + classname
+    try:
+        wxclass = realdict[classname]
+    except:
+        # print classname
+        pass
+    else:
+        if item.__doc__:
+            wxclass.__doc__ = item.__doc__
+        # Get attributes from only the item's local dictionary!
+        for attrname, attr in item.__dict__.items():
+            # If the attribute has a docstring, and the wx class has a
+            # matching attribute.
+            if hasattr(attr, '__doc__') and hasattr(wxclass, attrname):
+                if inspect.isfunction(attr):
+                    # Class methods are functions.
+                    doc = getdoc(attr, drop=True)
+                    # Is getattr() okay, or do we want to only look in
+                    # the wxclass.__dict__ and wxclassPtr.__dict__?
+                    wxattr = getattr(wxclass, attrname)
+                    # Our class code may be defined incorrectly, and
+                    # the wxattr may not actually be a class method,
+                    # but that's okay because the following attempt
+                    # will simply fail.
+                    try:
+                        func = wxattr.im_func
+                        func.__doc__ = doc
+                    except:
+                        pass
+
+def decorateFunction(item, realdict):
+    funcname = item.__name__
+    if funcname in realdict.keys():
+        func = realdict[funcname]
+        doc = getdoc(item, drop=False)
+        try:
+            # Built-in functions have a read-only docstring. :-(
+            func.__doc__ = doc
+        except:
+            # print funcname
+            pass
+
+def getdoc(attr, drop=False):
+    """Return a docstring for attr, which should be a method."""
+    doc = ''
+    if attr.__doc__:
+        doc = inspect.getdoc(attr).strip()
+    name = attr.__name__
+    # tip is a string with name(argspec), like: "SetLabel(label)"
+    tip = ''
+    argspec = apply(inspect.formatargspec, inspect.getargspec(attr))
+    # The first parameter to a method is a reference to an instance,
+    # usually coded as "self", and is usually passed automatically by
+    # Python and therefore we want to drop it.
+    temp = argspec.split(',')
+    if len(temp) == 1:  # No other arguments.
+        argspec = '()'
+    elif drop:  # Drop the first argument.
+        argspec = '(' + ','.join(temp[1:]).lstrip()
+    else:
+        argspec = ','.join(temp).lstrip()
+    tip = name + argspec
+    firstline = doc.split('\n')[0].lstrip()
+    if tip != firstline:
+        doc = '%s\n\n%s' % (tip, doc)
+    return doc