示例#1
0
def test_math():
    """Test a docstring with Latex on it"""
    oinfo = object_info()
    oinfo['name'] = 'Foo'
    oinfo['docstring'] = 'This is some math :math:`a^2 = b^2 + c^2`'
    url = spxy.rich_repr(oinfo)
    _show_page(url)
示例#2
0
def test_no_render_math():
    """Test a docstring with Latex on it but without rendering it"""
    oinfo = object_info()
    oinfo['name'] = 'Foo'
    oinfo['docstring'] = 'This is a rational number :math:`\\frac{x}{y}`'
    dr.options['render_math'] = False
    url = spxy.rich_repr(oinfo)
    _show_page(url)
示例#3
0
def test_basic():
    """Test with an empty context"""
    oinfo = object_info()
    oinfo['name'] = 'Foo'
    oinfo['argspec'] = {}
    oinfo['docstring'] = 'A test'
    oinfo['type_name'] = 'Function'
    url = spxy.rich_repr(oinfo)
    _show_page(url)
示例#4
0
def test_plot():
    """Test the outline option"""
    docstring = """
.. plot::

   >>> import matplotlib.pyplot as plt
   >>> plt.plot([1,2,3], [4,5,6])
"""
    oinfo = object_info()
    oinfo['name'] = 'Foo'
    oinfo['docstring'] = docstring
    url = spxy.rich_repr(oinfo)
    _show_page(url)
示例#5
0
    def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
        """Compute a dict with detailed information about an object.

    This overrides the superclass method for two main purposes:
     * avoid calling str() or repr() on the object
     * use our custom repr

    Args:
      obj: object to inspect.
      oname: (optional) string reference to this object
      formatter: (optional) custom docstring formatter
      info: (optional) previously computed information about obj
      detail_level: (optional) 0 or 1; 1 means "include more detail"

    Returns:
      A dict with information about obj.
    """

        # We want to include the following list of keys for all objects:
        # * name
        # * found
        # * isclass
        # * string_form
        # * type_name
        #
        # For callables, we want to add a subset of:
        # * argspec
        # * call_docstring
        # * definition
        # * docstring
        # * file
        # * init_definition
        # * init_docstring
        # * source_end_line
        # * source_start_line
        # * source_definition
        #
        # For detail_level 1, we include:
        # * file
        # This can be expensive, as the stdlib mechanisms for looking up the file
        # containing obj may call repr(obj).
        #
        # NOTE: These keys should stay in sync with the corresponding list in our
        # frontend code.
        #
        # We want non-None values for:
        # * isalias
        # * ismagic
        # * namespace
        #
        # TODO(b/138128444): Handle class_docstring and call_def, or determine that
        # we're safe ignoring them.

        obj_type = type(obj)
        out = {
            'name': oname,
            'found': True,
            'is_class': inspect.isclass(obj),
            'string_form': None,
            # Fill in empty values.
            'docstring': None,
            'file': None,
            'isalias': False,
            'ismagic': info.ismagic if info else False,
            'namespace': info.namespace if info else '',
        }
        if detail_level >= self.str_detail_level:
            out['string_form'] = _safe_repr(obj)

        if getattr(info, 'ismagic', False):
            out['type_name'] = 'Magic function'
        else:
            out['type_name'] = obj_type.__name__

        # If the object is callable, we want to compute a docstring and related
        # information. We could exit early, but all the code below is in conditional
        # blocks, so there's no need.
        #
        # We can't simply call into the superclass method, as we need to avoid
        # (transitively) calling inspect.getfile(): this function will end up
        # calling repr() on our object.

        # We want to include a docstring if we don't have source, which happens
        # when:
        # * detail_level == 0, or
        # * detail_level == 1 but we can't find source
        # So we first try dealing with detail_level == 1, and then set
        # the docstring if no source is set.
        if detail_level == 1:
            # This should only ever happen if the user has asked for source (eg via
            # `obj??`), so we're OK with potentially calling repr for now.
            # TODO(b/138128444): Ensure we don't call str() or repr().
            source = _getsource(obj)
            if source is None and hasattr(obj, '__class__'):
                source = _getsource(obj.__class__)
            if source is not None:
                out['source'] = source
        if 'source' not in out:
            formatter = formatter or (lambda x: x)
            docstring = formatter(_getdoc(obj) or '<no docstring>')
            if docstring:
                out['docstring'] = docstring

        if _iscallable(obj):
            filename = oinspect.find_file(obj)
            if filename and (filename.endswith(
                ('.py', '.py3', '.pyc')) or '<ipython-input' in filename):
                out['file'] = filename

            line = oinspect.find_source_lines(obj)
            out['source_start_line'] = line
            # inspect.getsourcelines exposes the length of the source as well, which
            # can be used to highlight the entire code block, but find_source_lines
            # currently does not expose this. For now just highlight the first line.
            out['source_end_line'] = line

        # The remaining attributes only apply to classes or callables.
        if inspect.isclass(obj):
            # For classes with an __init__, we set init_definition and init_docstring.
            init = getattr(obj, '__init__', None)
            if init:
                init_docstring = _getdoc(init)
                if init_docstring and init_docstring != _BASE_INIT_DOC:
                    out['init_docstring'] = init_docstring
                init_def = self._getdef(init, oname)
                if init_def:
                    out['init_definition'] = init_def
                src_def = _get_source_definition(init)
                if src_def:
                    out['source_definition'] = src_def
            # For classes, the __init__ method is the method invoked on call, but
            # old-style classes may not have an __init__ method.
            if init:
                argspec = _getargspec_dict(init)
                if argspec:
                    out['argspec'] = argspec
        elif callable(obj):
            definition = self._getdef(obj, oname)
            if definition:
                out['definition'] = definition
            src_def = _get_source_definition(obj)
            if src_def:
                out['source_definition'] = src_def

            if not oinspect.is_simple_callable(obj):
                call_docstring = _getdoc(obj.__call__)
                if call_docstring and call_docstring != _BASE_CALL_DOC:
                    out['call_docstring'] = call_docstring

            out['argspec'] = _getargspec_dict(obj)

        return oinspect.object_info(**out)
示例#6
0
def test_empty_oinfo():
    """Test with totally empty oinfo"""
    oinfo = object_info()
    url = spxy.rich_repr(oinfo)
    _show_page(url)
示例#7
0
def test_no_doc():
    oinfo = object_info()
    oinfo['docstring'] = '<no docstring>'
    url = spxy.rich_repr(oinfo)
    _show_page(url)