Example #1
0
def get_cls_methods(object, name_prefix=''):
    """ return [{
        name:,
        doc:,
        argspec:,
        flag:,
        is_property:,
    }]
    """

    def make_obj(name, kind, cls, value, val):
        is_property = isinstance(val, property)

        return dict(
            name=name_prefix + name,
            doc=pydoc.getdoc(val),
            argspec=get_fn_argspec(val),
            flag='P' if is_property else get_method_flag(kind),
            is_property=is_property
        )

    # (name, kind, cls, value)
    methods = []
    for name, kind, cls, value in pydoc.classify_class_attrs(object):
        if cls is object and kind.endswith('method') and not name.startswith('_'):
            val = getattr(cls, name)
            if isinstance(val, models.Manager):
                if val.__class__ is not models.Manager:
                    methods.extend(get_cls_methods(val.__class__, name_prefix='{}.'.format(name)))
            else:
                methods.append(make_obj(name, kind, cls, value, val))

    return methods
Example #2
0
def get_cls_methods(object, name_prefix=''):
    """ return [{
        name:,
        doc:,
        argspec:,
        flag:,
        is_property:,
    }]
    """
    def make_obj(name, kind, cls, value, val):
        is_property = isinstance(val, property)

        return dict(name=name_prefix + name,
                    doc=pydoc.getdoc(val),
                    argspec=get_fn_argspec(val),
                    flag='P' if is_property else get_method_flag(kind),
                    is_property=is_property)

    # (name, kind, cls, value)
    methods = []
    for name, kind, cls, value in pydoc.classify_class_attrs(object):
        if cls is object and kind.endswith(
                'method') and not name.startswith('_'):
            val = getattr(cls, name)
            if isinstance(val, models.Manager):
                if val.__class__ is not models.Manager:
                    methods.extend(
                        get_cls_methods(val.__class__,
                                        name_prefix='{}.'.format(name)))
            else:
                methods.append(make_obj(name, kind, cls, value, val))

    return methods
Example #3
0
def shape_text(this_cls, doc=pydoc.plaintext):
    attrs = [(name, kind)
             for name, kind, cls, _ in pydoc.classify_class_attrs(this_cls)
             if cls == this_cls]
    attrs = [(name, kind) for name, kind in attrs
             if not (name.startswith("__") and name.endswith("__"))]
    method_names = [name for name, kind in attrs if kind == "method"]
    content = doc.indent("".join(
        [doc.document(getattr(this_cls, name)) for name in method_names]))
    mro = " <- ".join([cls.__name__ for cls in this_cls.mro()])
    return "\n".join([mro, content])
Example #4
0
def shape_text(this_cls, doc=pydoc.plaintext):
    attrs = [
        (name, kind) for name, kind, cls, _ in pydoc.classify_class_attrs(this_cls)
        if cls == this_cls
    ]
    attrs = [
        (name, kind) for name, kind in attrs if not (name.startswith("__") and name.endswith("__"))
    ]
    method_names = [name for name, kind in attrs if kind == "method"]
    content = doc.indent("".join([doc.document(getattr(this_cls, name)) for name in method_names]))
    mro = " <- ".join([cls.__name__ for cls in this_cls.mro()])
    return "\n".join([mro, content])
Example #5
0
def shape_text(this_cls, doc=pydoc.plaintext):
    attrs = [
        (name, kind) for name, kind, cls, _ in pydoc.classify_class_attrs(this_cls)
        if cls == this_cls
    ]
    attrs = [
        (name, kind) for name, kind in attrs if not (name.startswith("__") and name.endswith("__"))
    ]
    attrs = [(name, kind) for name, kind in attrs if not name.startswith("_")]
    method_names = [name for name, kind in attrs if kind == "method"]
    method_annotations = [
        "@OVERRIDE: " if any(c for c in this_cls.mro()[1:] if hasattr(c, name)) else ""
        for name in method_names
    ]
    method_docs = [
        prefix + doc.document(getattr(this_cls, name))
        for prefix, name in zip(method_annotations, method_names)
    ]

    content = doc.indent("".join(method_docs))
    mro = " <- ".join([cls.__name__ for cls in this_cls.mro()])
    return "\n".join([mro, content])
Example #6
0
	def docclass(self, cls, name=None, mod=None):
		"""Produce text documentation for the class object cls."""

		# the overall document, as a line-delimited list
		document = []

		# get the object's actual name, defaulting to the passed in name
		name = name or cls.__name__

		# get the object's bases
		bases = cls.__bases__

		# get the object's module
		mod = cls.__module__

		# get the object's MRO
		mro = [pydoc.classname(base, mod) for base in inspect.getmro(cls)]

		# get the object's classname, which should be printed
		classtitle = self.process_class_name(name, bases, mod)
		document.append(classtitle)
		document.append(self.underline)

		# get the object's docstring, which should be printed
		docstring = self.process_docstring(cls)
		document.append(docstring)

		# get all the attributes of the class
		attrs = []
		for name, kind, classname, value in pydoc.classify_class_attrs(cls):
			if pydoc.visiblename(name):
				attrs.append((name, kind, classname, value))

		# sort them into categories
		data, descriptors, methods = [], [], []
		for attr in attrs:
			if attr[1] == "data" and not attr[0].startswith("_"):
				data.append(attr)
			elif attr[1] == "data descriptor" and not attr[0].startswith("_"):
				descriptors.append(attr)
			elif "method" in attr[1] and not attr[2] is builtins.object:
				methods.append(attr)

		if data:
			# start the data section
			document.append(self.process_subsection(self.bold("data")))
			document.append(self.underline)

			# process your attributes
			for name, kind, classname, value in data:
				if hasattr(value, '__call__') or inspect.isdatadescriptor(value):
					doc = getdoc(value)
				else: 
					doc = None
				document.append(self.docother(getattr(cls, name), name, mod, maxlen=70, doc=doc) + '\n')

		if descriptors:
			# start the descriptors section
			document.append(self.process_subsection(self.bold("descriptors")))
			document.append(self.underline)

			# process your descriptors
			for name, kind, classname, value in descriptors:
				document.append(self._docdescriptor(name, value, mod))

		if methods:
			# start the methods section
			document.append(self.process_subsection(self.bold("methods")))
			document.append(self.underline)

			# process your methods
			for name, kind, classname, value in methods:
				document.append(self.document(getattr(cls, name), name, mod, cls))

		return "\n".join(document)		
Example #7
0
    def docclass(self, cls, name=None, mod=None):
        """Produce text documentation for the class object cls."""

        # the overall document, as a line-delimited list
        document = []

        # get the object's actual name, defaulting to the passed in name
        name = name or cls.__name__

        # get the object's bases
        bases = cls.__bases__

        # get the object's module
        mod = cls.__module__

        # get the object's MRO
        mro = [pydoc.classname(base, mod) for base in inspect.getmro(cls)]

        # get the object's classname, which should be printed
        classtitle = self.process_class_name(name, bases, mod)
        document.append(classtitle)
        document.append(self.underline)

        # get the object's docstring, which should be printed
        docstring = self.process_docstring(cls)
        document.append(docstring)

        # get all the attributes of the class
        attrs = []
        for name, kind, classname, value in pydoc.classify_class_attrs(cls):
            if pydoc.visiblename(name):
                attrs.append((name, kind, classname, value))

        # sort them into categories
        data, descriptors, methods = [], [], []
        for attr in attrs:
            if attr[1] == "data" and not attr[0].startswith("_"):
                data.append(attr)
            elif attr[1] == "data descriptor" and not attr[0].startswith("_"):
                descriptors.append(attr)
            elif "method" in attr[1] and not attr[2] is builtins.object:
                methods.append(attr)

        if data:
            # start the data section
            document.append(self.process_subsection(self.bold("data")))
            document.append(self.underline)

            # process your attributes
            for name, kind, classname, value in data:
                if hasattr(value,
                           '__call__') or inspect.isdatadescriptor(value):
                    doc = getdoc(value)
                else:
                    doc = None
                document.append(
                    self.docother(
                        getattr(cls, name), name, mod, maxlen=70, doc=doc) +
                    '\n')

        if descriptors:
            # start the descriptors section
            document.append(self.process_subsection(self.bold("descriptors")))
            document.append(self.underline)

            # process your descriptors
            for name, kind, classname, value in descriptors:
                document.append(self._docdescriptor(name, value, mod))

        if methods:
            # start the methods section
            document.append(self.process_subsection(self.bold("methods")))
            document.append(self.underline)

            # process your methods
            for name, kind, classname, value in methods:
                document.append(
                    self.document(getattr(cls, name), name, mod, cls))

        return "\n".join(document)
Example #8
0
    def docclass(self, object, name=None, mod=None, *ignored):
        """Produce Markdown documentation for a given class object."""
        realname = object.__name__
        name = name or realname
        bases = object.__bases__

        def makename(c, m=object.__module__):
            return pydoc.classname(c, m)

        if name == realname:
            title = 'class ' + realname
        else:
            title = name + ' = class ' + realname
        if bases:
            parents = map(makename, bases)
            title = title + '(%s)' % ', '.join(parents)
        title = self.header(title, self.hlevel, name, 'class')

        self.hlevel += 1

        doc = pydoc.getdoc(object)
        contents = doc and [doc + '\n'] or []
        push = contents.append

        # List the mro, if non-trivial.
        mro = pydoc.deque(inspect.getmro(object))
        if len(mro) > 2:
            push("Method resolution order:\n")
            for base in mro:
                push('* ' + makename(base))
            push('')

        # Cute little class to pump out a horizontal rule between sections.
        class HorizontalRule:
            def __init__(self):
                self.needone = 0

            def maybe(self):
                if self.needone:
                    push('-' * 70 + '\n')
                self.needone = 1

        hr = HorizontalRule()

        def spill(msg, attrs, predicate):
            ok, attrs = pydoc._split_list(attrs, predicate)
            if ok:
                hr.maybe()
                push(msg)
                for name, kind, homecls, value in ok:
                    try:
                        value = getattr(object, name)
                    except Exception:
                        # Some descriptors may meet a failure in their __get__.
                        # (bug #1785)
                        push(self._docdescriptor(name, value, mod))
                    else:
                        push(self.document(value, name, mod, object))
            return attrs

        def spilldescriptors(msg, attrs, predicate):
            ok, attrs = pydoc._split_list(attrs, predicate)
            if ok:
                hr.maybe()
                push(msg)
                for name, kind, homecls, value in ok:
                    push(self._docdescriptor(name, value, mod))
            return attrs

        def spilldata(msg, attrs, predicate):
            ok, attrs = pydoc._split_list(attrs, predicate)
            if ok:
                hr.maybe()
                push(msg)
                for name, kind, homecls, value in ok:
                    if (hasattr(value, '__call__')
                            or inspect.isdatadescriptor(value)):
                        doc = pydoc.getdoc(value)
                    else:
                        doc = None
                    push(
                        self.docother(getattr(object, name),
                                      name,
                                      mod,
                                      maxlen=70,
                                      doc=doc) + '\n')
            return attrs

        attrs = filter(lambda data: pydoc.visiblename(data[0], obj=object),
                       pydoc.classify_class_attrs(object))
        while attrs:
            if mro:
                thisclass = mro.popleft()
            else:
                thisclass = attrs[0][2]
            attrs, inherited = pydoc._split_list(attrs,
                                                 lambda t: t[2] is thisclass)

            if thisclass is pydoc.__builtin__.object:
                attrs = inherited
                continue
            elif thisclass is object:
                tag = "defined here"
            else:
                tag = "inherited from %s" % pydoc.classname(
                    thisclass, object.__module__)

            # Sort attrs by name.
            attrs.sort()

            # Pump out the attrs, segregated by kind.
            attrs = spill("Methods %s:\n" % tag, attrs,
                          lambda t: t[1] == 'method')
            attrs = spill("Class methods %s:\n" % tag, attrs,
                          lambda t: t[1] == 'class method')
            attrs = spill("Static methods %s:\n" % tag, attrs,
                          lambda t: t[1] == 'static method')
            attrs = spilldescriptors("Data descriptors %s:\n" % tag, attrs,
                                     lambda t: t[1] == 'data descriptor')
            attrs = spilldata("Data and other attributes %s:\n" % tag, attrs,
                              lambda t: t[1] == 'data')
            assert attrs == []
            attrs = inherited

        self.hlevel -= 1

        contents = '\n'.join(contents)
        if not contents:
            return title
        return title + contents.rstrip() + '\n'
Example #9
0
    def docclass(self, object, name=None, mod=None, *ignored):
        """Produce text documentation for a given class object."""
        realname = object.__name__
        name = name or realname
        bases = object.__bases__

        def makename(c, m=object.__module__):
            return classname(c, m)

        if name == realname:
            title = 'class ' + self.bold(realname)
        else:
            title = self.bold(name) + ' = class ' + realname
        if bases:
            parents = map(makename, bases)
            title = title + '(%s)' % ', '.join(parents)
        title += ':'

        contents = []
        push = contents.append

        doc = getdoc(object)
        if doc:
            push(f'"""\n{doc}\n"""')

        # List the mro, if non-trivial.
        mro = deque(inspect.getmro(object))
        if len(mro) > 2:
            push("\n## Method resolution order:")
            for i, base in enumerate(mro, 1):
                push(f'# {i}) ' + makename(base))
            push('')

        # Cute little class to pump out a horizontal rule between sections.
        class HorizontalRule:
            def __init__(self):
                self.needone = 0

            def maybe(self):
                if self.needone:
                    push('# ' + '-' * 68)
                self.needone = 1

        hr = HorizontalRule()

        def spill(msg, attrs, predicate):
            ok, attrs = _split_list(attrs, predicate)
            if ok:
                hr.maybe()
                push('# ' + msg)
                for name, kind, homecls, value in ok:
                    try:
                        value = getattr(object, name)
                    except Exception:
                        # Some descriptors may meet a failure in their __get__.
                        # (bug #1785)
                        push(self._docdescriptor(name, value, mod))
                    else:
                        push(self.document(value, name, mod, object))
            return attrs

        def spilldescriptors(msg, attrs, predicate):
            ok, attrs = _split_list(attrs, predicate)
            if ok:
                hr.maybe()
                push('# ' + msg)
                for name, kind, homecls, value in ok:
                    push(self._docdescriptor(name, value, mod))
            return attrs

        def spilldata(msg, attrs, predicate):
            ok, attrs = _split_list(attrs, predicate)
            if ok:
                hr.maybe()
                push('# ' + msg)
                for name, kind, homecls, value in ok:
                    if callable(value) or inspect.isdatadescriptor(value):
                        doc = getdoc(value)
                    else:
                        doc = None
                    try:
                        obj = getattr(object, name)
                    except AttributeError:
                        obj = homecls.__dict__[name]
                    push(
                        self.docother(obj, name, mod, maxlen=70, doc=doc) +
                        '\n')
            return attrs

        attrs = [(name, kind, cls, value)
                 for name, kind, cls, value in classify_class_attrs(object)
                 if visiblename(name, obj=object)]

        while attrs:
            if mro:
                thisclass = mro.popleft()
            else:
                thisclass = attrs[0][2]
            attrs, inherited = _split_list(attrs, lambda t: t[2] is thisclass)

            if thisclass is builtins.object:
                attrs = inherited
                continue
            elif thisclass is object:
                tag = "defined here"
            else:
                tag = "inherited from %s" % classname(thisclass,
                                                      object.__module__)

            sort_attributes(attrs, object)

            # Pump out the attrs, segregated by kind.
            attrs = spill("Methods %s:\n" % tag, attrs,
                          lambda t: t[1] == 'method')
            attrs = spill("Class methods %s:\n" % tag, attrs,
                          lambda t: t[1] == 'class method')
            attrs = spill("Static methods %s:\n" % tag, attrs,
                          lambda t: t[1] == 'static method')
            attrs = spilldescriptors("Data descriptors %s:\n" % tag, attrs,
                                     lambda t: t[1] == 'data descriptor')
            attrs = spilldata("Data and other attributes %s:\n" % tag, attrs,
                              lambda t: t[1] == 'data')

            assert attrs == []
            attrs = inherited

        contents = '\n'.join(contents) or 'pass'
        return '\n' + title + '\n' + self.indent(contents.rstrip(),
                                                 '    ') + '\n'
Example #10
0
    def docclass(self, cls, name=None, mod=None):
        """Produce markdown documentation for the class obj cls."""

        # the overall document, as a line-delimited list
        document = []

        # get the obj's actual name, defaulting to the passed in name
        name = name or cls.__name__

        # get the obj's bases
        bases = cls.__bases__

        # get the obj's module
        mod = cls.__module__

        # get the obj's classname, which should be printed
        classtitle = self.process_class_name(name, bases, mod)
        document.append(classtitle)

        # get the obj's docstring, which should be printed
        docstring = self.process_docstring(cls)
        document.append(self.process_subsection("description"))
        document.append(self.underline)
        document.append(docstring)

        # get all the attributes of the class
        attrs = []
        for name, kind, classname, value in pydoc.classify_class_attrs(cls):
            if pydoc.visiblename(name):
                if kind is not __builtin__.object:
                    if classname == cls:
                        obj = (name, kind, classname, value)
                        attrs.append(obj)

        # sort them into categories
        data = [attr for attr in attrs if attr[1] == "data"]
        descriptors = [attr for attr in attrs if attr[1] == "data descriptor"]
        methods = [attr for attr in attrs if "method" in attr[1]]

        # start the data section
        if data:
            document.append(self.process_subsection("data"))
            document.append(self.underline)

        # process your attributes
        for name, kind, classname, value in data:
            document.append(self.document(getattr(cls, name), name, mod, cls))

        # start the descriptors section
        if descriptors:
            document.append(self.process_subsection("descriptors"))
            document.append(self.underline)

        # process your descriptors
        for _ in descriptors:
            document.append(self._docdescriptor(name, value, mod))

        # start the methods section
        if methods:
            document.append(self.process_subsection("methods"))
            document.append(self.underline)

        # process your methods
        for f in methods:
            if not f[0].startswith("__"):
                document.append(self.docroutine(f[-1]))

        return "\n".join(document).replace('\n', '\n> ')
Example #11
0
 def __get_clazz_attributes(cls, clazz) -> list:
     return [(name, kind, clz, value)
             for name, kind, clz, value in pydoc.classify_class_attrs(clazz)
             if DLibraryDoc.__show_clazz_attribute(clazz, name, clz)]
Example #12
0
 def update_event(self, inp=-1):
     self.set_output_val(0, pydoc.classify_class_attrs(self.input(0)))
Example #13
0
    def docclass(self, cls, name=None, mod=None):
        """Produce text documentation for the class object cls."""

        # the overall document, as a line-delimited list
        document = []

        # get the object's actual name, defaulting to the passed in name
        name = name or cls.__name__

        # get the object's bases
        bases = cls.__bases__

        # get the object's module
        mod = cls.__module__

        # get the object's MRO
        mro = [pydoc.classname(base, mod) for base in inspect.getmro(cls)]

        # get the object's classname, which should be printed
        classtitle = self.process_class_name(name, bases, mod)
        document.append(classtitle)
        document.append(self.underline)

        # get the object's docstring, which should be printed
        docstring = self.process_docstring(cls)
        document.append(docstring)

        # get all the attributes of the class
        attrs = []
        for name, kind, classname, value in pydoc.classify_class_attrs(cls):
            if pydoc.visiblename(name):
                #if kind is not builtins.object:
                if classname == cls:
                    obj = (name, kind, classname, value)
                    attrs.append(obj)

        # sort them into categories
        data = [attr for attr in attrs if attr[1] == "data"]
        descriptors = [attr for attr in attrs if attr[1] == "data descriptor"]
        methods = [attr for attr in attrs if "method" in attr[1]]

        # start the data section
        document.append(self.process_subsection("data"))
        document.append(self.underline)

        # process your attributes
        for name, kind, classname, value in data:
            document.append(self.document(getattr(cls, name), name, mod, cls))

        # start the descriptors section
        document.append(self.process_subsection("descriptors"))
        document.append(self.underline)

        # process your descriptors
        for desc in descriptors:
            document.append(self._docdescriptor(name, value, mod))

        # start the methods section
        document.append(self.process_subsection("methods"))
        document.append(self.underline)

        # process your methods
        for f in methods:
            if not f[0].startswith("__"):
                document.append(self.docroutine(f[-1]))

        return "\n".join(document)
Example #14
0
    def docclass(self, object, name=None, mod=None, *ignored):
        """Produce text documentation for a given class object."""
        realname = object.__name__
        name = name or realname
        bases = object.__bases__

        def makename(c, m=object.__module__):
            return classname(c, m)

        if name == realname:
            title = 'class ' + self.bold(realname)
        else:
            title = self.bold(name) + ' = class ' + realname
        if bases:
            parents = map(makename, bases)
            title = title + '(%s)' % ', '.join(parents)

        contents = []
        push = contents.append

        try:
            signature = inspect.signature(object)
        except (ValueError, TypeError):
            signature = None
        if signature:
            argspec = str(signature)
            if argspec and argspec != '()':
                push(name + argspec)

        doc = getdoc(object)
        if doc:
            push(self.indent(doc.splitlines()[0]))

        # List the mro, if non-trivial.
        mro = deque(inspect.getmro(object))
        if len(mro) > 2:
            push("Method resolution order:")
            for base in mro:
                push('    ' + makename(base))

        # List the built-in subclasses, if any:
        subclasses = sorted((str(cls.__name__)
                             for cls in type.__subclasses__(object)
                             if not cls.__name__.startswith("_")
                             and cls.__module__ == "builtins"),
                            key=str.lower)
        no_of_subclasses = len(subclasses)
        MAX_SUBCLASSES_TO_DISPLAY = 4
        if subclasses:
            push("Built-in subclasses:")
            for subclassname in subclasses[:MAX_SUBCLASSES_TO_DISPLAY]:
                push('    ' + subclassname)
            if no_of_subclasses > MAX_SUBCLASSES_TO_DISPLAY:
                push('    ... and ' +
                     str(no_of_subclasses - MAX_SUBCLASSES_TO_DISPLAY) +
                     ' other subclasses')
            push('')

        def header(msg):
            push(f"\n{msg}\n" + ("-" * len(msg)))

        def spill(msg, attrs, predicate):
            ok, attrs = _split_list(attrs, predicate)
            if ok:
                header(msg)
                for name, kind, homecls, value in ok:
                    try:
                        value = getattr(object, name)
                    except Exception:
                        # Some descriptors may meet a failure in their __get__.
                        # (bug #1785)
                        push(self.docdata(value, name, mod))
                    else:
                        push(self.document(value, name, mod, object))
            return attrs

        def spilldescriptors(msg, attrs, predicate):
            ok, attrs = _split_list(attrs, predicate)
            if ok:
                header(msg)
                for name, kind, homecls, value in ok:
                    push(self.docdata(value, name, mod))
            return attrs

        def spilldata(msg, attrs, predicate):
            ok, attrs = _split_list(attrs, predicate)
            if ok:
                header(msg)
                for name, kind, homecls, value in ok:
                    if callable(value) or inspect.isdatadescriptor(value):
                        doc = getdoc(value)
                    else:
                        doc = None
                    try:
                        obj = getattr(object, name)
                    except AttributeError:
                        obj = homecls.__dict__[name]
                    push(self.docother(obj, name, mod, maxlen=70, doc=doc))
            return attrs

        attrs = [(name, kind, cls, value)
                 for name, kind, cls, value in classify_class_attrs(object)
                 if visiblename(name, obj=object)]

        while attrs:
            if mro:
                thisclass = mro.popleft()
            else:
                thisclass = attrs[0][2]
            attrs, inherited = _split_list(attrs, lambda t: t[2] is thisclass)

            if object is not builtins.object and thisclass is builtins.object:
                attrs = inherited
                continue
            elif thisclass is object:
                tag = "defined here"
            else:
                tag = "inherited from %s" % classname(thisclass,
                                                      object.__module__)

            sort_attributes(attrs, object)

            # Pump out the attrs, segregated by kind.
            attrs = spill("Methods %s" % tag, attrs,
                          lambda t: t[1] == 'method')
            attrs = spill("Class methods %s" % tag, attrs,
                          lambda t: t[1] == 'class method')
            attrs = spill("Static methods %s" % tag, attrs,
                          lambda t: t[1] == 'static method')
            attrs = spilldescriptors("Readonly properties %s" % tag, attrs,
                                     lambda t: t[1] == 'readonly property')
            attrs = spilldescriptors("Data descriptors %s" % tag, attrs,
                                     lambda t: t[1] == 'data descriptor')
            attrs = spilldata("Data and other attributes %s" % tag, attrs,
                              lambda t: t[1] == 'data')

            assert attrs == []
            attrs = inherited

        contents = '\n'.join(contents)
        if not contents:
            return title + '\n'
        return title + '\n' + self.indent(contents.rstrip(), ' |  ') + '\n'
Example #15
0
 def get_attrs(obj):
     all_attrs = filter(lambda data: pydoc.visiblename(data[0], obj=obj),
                        pydoc.classify_class_attrs(obj))
     return filter(lambda data: data[2] == obj, all_attrs)
Example #16
0
    def docclass(self,
                 object,
                 name=None,
                 mod=None,
                 funcs={},
                 classes={},
                 *ignored):
        """Produce HTML documentation for a class object."""

        level = 2  # FIXME: use passed level in the future

        realname = object.__name__
        name = name or realname
        bases = object.__bases__
        doc = self.getdoc(object)

        components = {}

        def spill(msg, attrs, predicate):
            # `ok` are attributes to handle, `attrs` is what's left
            ok, attrs = pydoc._split_list(attrs, predicate)
            if ok:
                result = msg
                for name, kind, homecls, value in ok:
                    try:
                        value = getattr(object, name)
                    except Exception:
                        # Some descriptors may meet a failure in their __get__.
                        # (bug #1785)
                        result += self._docdescriptor(name, value, mod)
                    else:
                        result += self.document(value, name, mod, funcs,
                                                classes, mdict, object)

                # NOTE: this is that important side-effect you're looking for!
                components['docs'].append(result)

            return attrs

        def spilldescriptors(msg, attrs, predicate):

            # `ok` are attributes to handle, `attrs` is what's left
            ok, attrs = pydoc._split_list(attrs, predicate)
            if ok:
                result = msg
                for name, kind, homecls, value in ok:
                    result += self._docdescriptor(name, value, mod)

                # NOTE: this is that important side-effect you're looking for!
                components['docs'].append(result)

            return attrs

        def spilldata(msg, attrs, predicate):
            # `ok` are attributes to handle, `attrs` is what's left
            ok, attrs = pydoc._split_list(attrs, predicate)
            if ok:

                result = msg
                for name, kind, homecls, value in ok:
                    base = self.docother(getattr(object, name), name, mod)
                    if (hasattr(value, '__call__')
                            or inspect.isdatadescriptor(value)):
                        doc = getattr(value, "__doc__", None)
                    else:
                        doc = None
                    if doc is None:
                        result += '<dl><dt>%s</dt></dl>\n' % base
                    else:
                        doc = self.markup(self.getdoc(value), self.preformat,
                                          funcs, classes, mdict)
                        doc = '<dd>%s</dd>' % doc
                        result += '<dl><dt>%s%s</dl>\n' % (base, doc)

                # NOTE: this is that important side-effect you're looking for!
                components['docs'].append(result)

            return attrs

        mro = collections.deque(inspect.getmro(object))
        if len(mro) > 2:
            components[
                'mro'] = '<dl class="mro"><dt>Method resolution order:</dt>'
            for base in mro:
                components['mro'] += '<dd>%s</dd>' % self.classlink(
                    base, object.__module__)
            components['mro'] += '</dl>'

        attrs = filter(lambda data: pydoc.visiblename(data[0], obj=object),
                       pydoc.classify_class_attrs(object))
        mdict = {}
        for key, kind, homecls, value in attrs:
            mdict[key] = anchor = '#' + name + '-' + key
            try:
                value = getattr(object, name)
            except Exception:
                # Some descriptors may meet a failure in their __get__.
                # (bug #1785)
                pass
            try:
                # The value may not be hashable (e.g., a data attr with
                # a dict or list value).
                mdict[value] = anchor
            except TypeError:
                pass

        components['docs'] = []  # populated in spill* functions

        while attrs:
            if mro:
                thisclass = mro.popleft()
            else:
                thisclass = attrs[0][2]
            attrs, inherited = pydoc._split_list(attrs,
                                                 lambda t: t[2] is thisclass)

            # if thisclass is __builtin__.object: # 2.7 only, no clue why it wasn't just `object` in the first place.
            if thisclass is __builtin__.object:
                attrs = inherited
                continue
            elif thisclass is object:
                tag = ''
            else:
                tag = 'from %s' % self.classlink(thisclass, object.__module__)

            # Sort attrs by name.
            try:
                attrs.sort(key=lambda t: t[0])
            except TypeError:
                attrs.sort(lambda t1, t2: cmp(t1[0], t2[0]))  # 2.3 compat

            attrs = spill('<h4 class="head-methods">Methods %s</h4>' % tag,
                          attrs, lambda t: t[1] == 'method')
            attrs = spill(
                '<h4 class="head-class-methods">Class methods %s</h4>' % tag,
                attrs, lambda t: t[1] == 'class method')
            attrs = spill(
                '<h4 class="head-static-methods">Static methods %s</h4>' % tag,
                attrs, lambda t: t[1] == 'static method')
            attrs = spilldescriptors(
                '<h4 class="head-desc">Descriptors %s</h4>' % tag, attrs,
                lambda t: t[1] == 'data descriptor')
            attrs = spilldata(
                '<h4 class="head-attrs">Attributes %s</h4>' % tag, attrs,
                lambda t: t[1] == 'data')
            assert attrs == []
            attrs = inherited

        if name == realname:
            title = '<a name="%s" href="#%s">class <span class="class-name">%s</span></a>' % (
                name, name, realname)
        else:
            title = '<span class="class-name">%s</span> = <a name="%s" href="#%s">class %s</a>' % (
                name, name, name, realname)

        if bases:
            parents = []
            for base in bases:
                parents.append(self.classlink(base, object.__module__))
            title = title + '(%s)' % ', '.join(parents)

        result = '<dt class="class">%s</dt>' % self.heading(level, title)

        result += '<dd class="class">'
        result += '<dd>\n%s\n</dd>' % doc
        if 'mro' in components:
            result += '  <div class="mro">%(mro)s</div>' % components

        result += '\n  '.join(components['docs'])

        result += '</dd>'

        return result
Example #17
0
        def docclass(self,
                     object,
                     name=None,
                     mod=None,
                     funcs={},
                     classes={},
                     *ignored):
            """Produce HTML documentation for a class object."""
            realname = object.__name__
            name = name or realname
            bases = object.__bases__

            contents = []
            push = contents.append

            # Cute little class to pump out a horizontal rule between sections.
            class HorizontalRule:
                def __init__(self):
                    self.needone = 0

                def maybe(self):
                    if self.needone:
                        push('<hr>\n')
                    self.needone = 1

            hr = HorizontalRule()

            # List the mro, if non-trivial.
            mro = deque(inspect.getmro(object))
            if len(mro) > 2:
                hr.maybe()
                push('<dl><dt>Method resolution order:</dt>\n')
                for base in mro:
                    push('<dd>%s</dd>\n' %
                         self.classlink(base, object.__module__))
                push('</dl>\n')

            def spill(msg, attrs, predicate):
                ok, attrs = _split_list(attrs, predicate)
                if ok:
                    hr.maybe()
                    push(msg)
                    for name, kind, homecls, value in ok:
                        try:
                            value = getattr(object, name)
                        except Exception:
                            # Some descriptors may meet a failure
                            # in their __get__.
                            # (bug aroberge/mod_pydoc#1785)
                            push(self._docdescriptor(name, value, mod))
                        else:
                            push(
                                self.document(value, name, mod, funcs, classes,
                                              mdict, object))
                        push('\n')
                return attrs

            def spilldescriptors(msg, attrs, predicate):
                ok, attrs = _split_list(attrs, predicate)
                if ok:
                    hr.maybe()
                    push(msg)
                    for name, kind, homecls, value in ok:
                        push(self._docdescriptor(name, value, mod))
                return attrs

            def spilldata(msg, attrs, predicate):
                ok, attrs = _split_list(attrs, predicate)
                if ok:
                    hr.maybe()
                    push(msg)
                    for name, kind, homecls, value in ok:
                        base = self.docother(getattr(object, name), name, mod)
                        if callable(value) or inspect.isdatadescriptor(value):
                            doc = getattr(value, "__doc__", None)
                        else:
                            doc = None
                        if doc is None:
                            push('<dl><dt>%s</dt><dd></dd></dl>\n' % base)
                        else:
                            doc = self.markup(getdoc(value), self.preformat,
                                              funcs, classes, mdict)
                            doc = '<dd><code>%s</code></dd>' % doc
                            push('<dl><dt>%s%s</dt></dl>\n' % (base, doc))
                        push('\n')
                return attrs

            attrs = [(name, kind, cls, value)
                     for name, kind, cls, value in classify_class_attrs(object)
                     if visiblename(name, obj=object)]

            mdict = {}
            for key, kind, homecls, value in attrs:
                mdict[key] = anchor = '#' + name + '-' + key
                try:
                    value = getattr(object, name)
                except Exception:
                    # Some descriptors may meet a failure in their __get__.
                    # (bug #1785)
                    pass
                try:
                    # The value may not be hashable (e.g., a data attr with
                    # a dict or list value).
                    mdict[value] = anchor
                except TypeError:
                    pass

            while attrs:
                if mro:
                    thisclass = mro.popleft()
                else:
                    thisclass = attrs[0][2]
                attrs, inherited = _split_list(attrs,
                                               lambda t: t[2] is thisclass)

                if thisclass is builtins.object:
                    attrs = inherited
                    continue
                elif thisclass is object:
                    tag = 'defined here'
                else:
                    tag = 'inherited from %s' % self.classlink(
                        thisclass, object.__module__)
                tag += ':<br>\n'

                # Sort attrs by name.
                attrs.sort(key=lambda t: t[0])

                # Pump out the attrs, segregated by kind.
                attrs = spill('Methods %s' % tag, attrs,
                              lambda t: t[1] == 'method')
                attrs = spill('Class methods %s' % tag, attrs,
                              lambda t: t[1] == 'class method')
                attrs = spill('Static methods %s' % tag, attrs,
                              lambda t: t[1] == 'static method')
                attrs = spilldescriptors('Data descriptors %s' % tag, attrs,
                                         lambda t: t[1] == 'data descriptor')
                attrs = spilldata('Data and other attributes %s' % tag, attrs,
                                  lambda t: t[1] == 'data')
                assert attrs == []
                attrs = inherited

            contents = ''.join(contents)

            if name == realname:
                title = '<span id="%s" class="signature"> class %s</span>' % (
                    name, realname)
            else:
                title = (
                    '%s = <span id="%s" class="signature">class %s</span>' %
                    (name, name, realname))
            if bases:
                parents = []
                for base in bases:
                    parents.append(self.classlink(base, object.__module__))
                title = title + '(%s)' % ', '.join(parents)
            doc = self.markup(getdoc(object), self.preformat, funcs, classes,
                              mdict)
            doc = doc and '<code>%s<br>&nbsp;</code>' % doc

            return self.html_section(title,
                                     contents,
                                     3,
                                     doc,
                                     css_class="docclass")