<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def doc(obj, of_class=None):
 """ Get parsed documentation for an object as a dict. This includes arguments spec, as well as the parsed data from the docstring. ```python from exdoc import doc ``` The `doc()` function simply fetches documentation for an object, which can be * Module * Class * Function or method * Property The resulting dictionary includes argument specification, as well as parsed docstring: ```python def f(a, b=1, *args):
 ''' Simple function : param a: First : type a: int : param b: Second : type b: int : param args: More numbers : returns: nothing interesting : rtype: bool : raises ValueError: hopeless condition ''' from exdoc import doc doc(f) # -> { 'module': '__main__', 'name': 'f', 'qualname': 'f', # qualified name: e.g. <class>.<method> 'signature': 'f(a, b=1, *args)', 'qsignature': 'f(a, b=1, *args)', # qualified signature 'doc': 'Simple function', 'clsdoc': '', # doc from the class (used for constructors) # Exceptions 'exc': [ {'doc': 'hopeless condition', 'name': 'ValueError'} ], # Return value 'ret': {'doc': 'nothing interesting', 'type': 'bool'}, # Arguments 'args': [ {'doc': 'First', 'name': 'a', 'type': 'int'}, {'default': 1, 'doc': 'Second', 'name': 'b', 'type': 'int'}, {'doc': 'More numbers', 'name': '*args', 'type': None} ], } ``` Note: in Python 3, when documenting a method of a class, pass the class to the `doc()` function as the second argument: ```python doc(cls.method, cls) ``` This is necessary because in Python3 methods are not bound like they used to. Now, they are just functions. :type obj: ModuleType|type|Callable|property :param of_class: A class whose method is being documented. :type of_class: class|None :rtype: Docstring|FDocstring """

    # Special care about properties
    if isinstance(obj, property):
        docstr = doc(obj.fget)
        # Some hacks for properties
        docstr.signature = docstr.qsignature= obj.fget.__name__
        docstr.args = docstr.args[1:]
        return docstr

    # Module
    module = inspect.getmodule(obj)
    if module:
        module = module.__name__

    # Not callable: e.g. modules
    if not callable(obj):
        if hasattr(obj, '__name__'):
            return data.Docstring(qualname=obj.__name__, doc=getdoc(obj))
        else:
            return None

    # Callables
    qualname, fun, of_class = _get_callable(obj, of_class)
    docstr = _docspec(fun, module=module, qualname=qualname, of_class=of_class)

    # Class? Get doc
    if inspect.isclass(obj):
        # Get class doc
        clsdoc = getdoc(obj)
        # Parse docstring and merge into constructor doc
        if clsdoc:
            # Parse docstring
            clsdoc = _doc_parse(clsdoc, module=module, qualname=qualname)

            # Store clsdoc always
            docstr.clsdoc = clsdoc.doc

            # Merge exceptions list
            docstr.exc.extend(clsdoc.exc)

            # If constructor does not have it's own docstr -- copy it from the clsdoc
            if not docstr.doc:
                docstr.doc = docstr.clsdoc

            # Merge arguments: type, doc
            for a_class in clsdoc.args:
                for a_constructor in docstr.args:
                    if a_class.name.lstrip('*') == a_constructor.name.lstrip('*'):
                        a_constructor.type = a_class.type
                        a_constructor.doc = a_class.doc

    # Finish
    return docstr