Beispiel #1
0
 def visit_doctest_block(self, node: Node) -> None:
     pysrc = node[0].astext()
     if node.get('codeblock'):
         self.body.append(flatten(colorize_codeblock(pysrc)))
     else:
         self.body.append(flatten(colorize_doctest(pysrc)))
     raise SkipNode()
def test_EpydocLinker_translate_identifier_xref_intersphinx_relative_id():
    """
    Return the link from inventory using short names, by resolving them based
    on the imports done in the module.
    """
    system = model.System()
    inventory = SphinxInventory(system.msg)
    inventory._links['ext_package.ext_module'] = ('http://tm.tld', 'some.html')
    system.intersphinx = inventory
    target = model.Module(system, 'ignore-name', 'ignore-docstring')
    # Here we set up the target module as it would have this import.
    # from ext_package import ext_module
    ext_package = model.Module(system, 'ext_package', 'ignore-docstring')
    target.contents['ext_module'] = model.Module(system,
                                                 'ext_module',
                                                 'ignore-docstring',
                                                 parent=ext_package)

    sut = epydoc2stan._EpydocLinker(target)

    # This is called for the L{ext_module<Pretty Text>} markup.
    result = sut.translate_identifier_xref('ext_module', 'Pretty Text')

    expected = (
        '<a href="http://tm.tld/some.html"><code>Pretty Text</code></a>')
    assert expected == flatten(result)
 def visit_title_reference(self, node):
     m = _TARGET_RE.match(node.astext())
     if m: text, target = m.groups()
     else: target = text = node.astext()
     xref = self._linker.translate_identifier_xref(target, text)
     self.body.append(flatten(xref))
     raise SkipNode()
Beispiel #4
0
def test_annotation_formatter(annotation: str) -> None:
    """Perform two checks on the annotation formatter:
    - all type names in the annotation are passed to the linker
    - the plain text version of the output matches the input
    """

    expected_lookups = [
        found[1:-1] for found in re.findall('<[^>]*>', annotation)
    ]
    expected_text = annotation.replace('<', '').replace('>', '')

    mod = fromText(f'''
    value: {expected_text}
    ''')
    obj = mod.contents['value']
    parsed = epydoc2stan.get_parsed_type(obj)
    assert parsed is not None
    linker = RecordingAnnotationLinker()
    stan = parsed.to_stan(linker)
    assert linker.requests == expected_lookups
    html = flatten(stan)
    assert html.startswith('<code>')
    assert html.endswith('</code>')
    text = html[6:-7]
    assert text == expected_text
Beispiel #5
0
def test_colorize_codeblock():
    src = '''
def foo():
    """A multi-line docstring.

    The "doc" part doesn't matter for this test,
    but the "string" part does.
    """
    return list({1, 2, 3})

class Foo:
    def __init__(self):
        # Nothing to do.
        pass
'''.lstrip()
    expected = '''
<pre class="py-doctest">
<span class="py-keyword">def</span> <span class="py-defname">foo</span>():
    <span class="py-string">"""A multi-line docstring.</span>

<span class="py-string">    The "doc" part doesn't matter for this test,</span>
<span class="py-string">    but the "string" part does.</span>
<span class="py-string">    """</span>
    <span class="py-keyword">return</span> <span class="py-builtin">list</span>({1, 2, 3})

<span class="py-keyword">class</span> <span class="py-defname">Foo</span>:
    <span class="py-keyword">def</span> <span class="py-defname">__init__</span>(self):
        <span class="py-comment"># Nothing to do.</span>
        <span class="py-keyword">pass</span>
</pre>
'''.strip()
    assert flatten(colorize_codeblock(src)) == expected
def test_EpydocLinker_translate_identifier_xref_intersphinx_link_not_found():
    """
    A message is sent to stdout when no link could be found for the reference,
    while returning the reference name without an A link tag.
    The message contains the full name under which the reference was resolved.
    """
    system = model.System()
    target = model.Module(system, 'ignore-name', 'ignore-docstring')
    # Here we set up the target module as it would have this import.
    # from ext_package import ext_module
    ext_package = model.Module(system, 'ext_package', 'ignore-docstring')
    target.contents['ext_module'] = model.Module(system,
                                                 'ext_module',
                                                 'ignore-docstring',
                                                 parent=ext_package)
    stdout = StringIO()
    sut = epydoc2stan._EpydocLinker(target)

    try:
        # FIXME: https://github.com/twisted/pydoctor/issues/112
        # We no have this ugly hack to capture stdout.
        previousStdout = sys.stdout
        sys.stdout = stdout
        # This is called for the L{ext_module} markup.
        result = sut.translate_identifier_xref(fullID='ext_module',
                                               prettyID='ext_module')
    finally:
        sys.stdout = previousStdout

    assert '<code>ext_module</code>' == flatten(result)

    expected = ("ignore-name:0 invalid ref to 'ext_module' "
                "resolved as 'ext_package.ext_module'\n")

    assert expected == stdout.getvalue()
def docstring2html(obj: model.Documentable) -> str:
    stan = epydoc2stan.format_docstring(obj)
    assert stan.tagName == 'div', stan
    # We strip off break lines for the sake of simplicity.
    return flatten(stan).replace('><', '>\n<').replace('<wbr></wbr>',
                                                       '').replace(
                                                           '<wbr>\n</wbr>', '')
Beispiel #8
0
def rst2html(
    docstring: str, linker: DocstringLinker = NotFoundLinker()) -> str:
    """
    Render a docstring to HTML.
    """
    errors: List[ParseError] = []
    parsed = parse_docstring(docstring, errors)
    assert not errors
    return flatten(parsed.to_stan(linker))
Beispiel #9
0
 def visit_title_reference(self, node: Node) -> None:
     m = _TARGET_RE.match(node.astext())
     if m:
         label, target = m.groups()
     else:
         label = target = node.astext()
     # TODO: 'node.line' is None for some reason.
     #       https://github.com/twisted/pydoctor/issues/237
     lineno = 0
     self.body.append(flatten(self._linker.link_xref(target, label, lineno)))
     raise SkipNode()
def test_module_docformat(capsys: CapSys) -> None:
    """
    Test if Module.docformat effectively override System.options.docformat
    """

    system = model.System()
    system.options.docformat = 'plaintext'

    mod = fromText('''
    """
    Link to pydoctor: U{pydoctor <https://github.com/twisted/pydoctor>}.
    """
    __docformat__ = "epytext"
    ''',
                   modname='test_epy',
                   system=system)

    epytext_output = epydoc2stan.format_docstring(mod)

    captured = capsys.readouterr().out
    assert not captured

    mod = fromText('''
    """
    Link to pydoctor: `pydoctor <https://github.com/twisted/pydoctor>`_.
    """
    __docformat__ = "restructuredtext en"
    ''',
                   modname='test_rst',
                   system=system)

    restructuredtext_output = epydoc2stan.format_docstring(mod)

    captured = capsys.readouterr().out
    assert not captured

    assert 'href="https://github.com/twisted/pydoctor"' in flatten(
        epytext_output)

    assert 'href="https://github.com/twisted/pydoctor"' in flatten(
        restructuredtext_output)
Beispiel #11
0
 def visit_title_reference(self, node):
     m = _TARGET_RE.match(node.astext())
     if m: text, target = m.groups()
     else: target = text = node.astext()
     label = tags.code(text)
     try:
         url = self._linker.resolve_identifier_xref(target)
     except LookupError:
         xref = label
     else:
         xref = tags.a(label, href=url)
     self.body.append(flatten(xref))
     raise SkipNode()
Beispiel #12
0
def test_colorize_doctest_no_output():
    src = '''
Test expecting no output:

    >>> None
'''.lstrip()
    expected = '''
<pre class="py-doctest">
Test expecting no output:

<span class="py-prompt">    &gt;&gt;&gt; </span><span class="py-builtin">None</span>
</pre>
'''.strip()
    assert flatten(colorize_doctest(src)) == expected
Beispiel #13
0
 def visit_title_reference(self, node: Node) -> None:
     m = _TARGET_RE.match(node.astext())
     if m: text, target = m.groups()
     else: target = text = node.astext()
     label = tags.code(text)
     # TODO: 'node.line' is None for some reason.
     #       https://github.com/twisted/pydoctor/issues/237
     lineno = 0
     try:
         url = self._linker.resolve_identifier_xref(target, lineno)
     except LookupError:
         xref = label
     else:
         xref = tags.a(label, href=url)
     self.body.append(flatten(xref))
     raise SkipNode()
Beispiel #14
0
def test_colorize_doctest_exception():
    src = '''
Test division by zero:

    >>> 1/0
    Traceback (most recent call last):
    ZeroDivisionError: integer division or modulo by zero
'''.lstrip()
    expected = '''
<pre class="py-doctest">
Test division by zero:

<span class="py-prompt">    &gt;&gt;&gt; </span>1/0
<span class="py-except">    Traceback (most recent call last):</span>
<span class="py-except">    ZeroDivisionError: integer division or modulo by zero</span>
</pre>
'''.strip()
    assert flatten(colorize_doctest(src)) == expected
Beispiel #15
0
def test_colorize_doctest_more_string():
    src = '''
Test multi-line string:

    >>> """A
    ... B
    ... C"""
    'A\\nB\\nC'
'''.lstrip()
    expected = '''
<pre class="py-doctest">
Test multi-line string:

<span class="py-prompt">    &gt;&gt;&gt; </span><span class="py-string">"""A</span>
<span class="py-more">    ... </span><span class="py-string">B</span>
<span class="py-more">    ... </span><span class="py-string">C"""</span>
<span class="py-output">    'A\\nB\\nC'</span>
</pre>
'''.strip()
    assert flatten(colorize_doctest(src)) == expected
Beispiel #16
0
def test_EpydocLinker_translate_identifier_xref_intersphinx_absolute_id():
    """
    Returns the link from Sphinx inventory based on a cross reference
    ID specified in absolute dotted path and with a custom pretty text for the
    URL.
    """
    system = model.System()
    inventory = SphinxInventory(system.msg)
    inventory._links['base.module.other'] = ('http://tm.tld', 'some.html')
    system.intersphinx = inventory
    target = model.Module(system, 'ignore-name', 'ignore-docstring')
    sut = epydoc2stan._EpydocLinker(target)

    result = sut.translate_identifier_xref('base.module.other',
                                           'base.module.pretty')

    expected = (
        '<a href="http://tm.tld/some.html"><code>base.module.pretty</code></a>'
    )
    assert expected == flatten(result)
Beispiel #17
0
def test_colorize_doctest_more_input():
    src = '''
Test multi-line expression:

    >>> [chr(i + 65)
    ...  for i in range(26)
    ...  if i % 2 == 0]
    ['A', 'C', 'E', 'G', 'I', 'K', 'M', 'O', 'Q', 'S', 'U', 'W', 'Y']
'''.lstrip()
    expected = '''
<pre class="py-doctest">
Test multi-line expression:

<span class="py-prompt">    &gt;&gt;&gt; </span>[<span class="py-builtin">chr</span>(i + 65)
<span class="py-more">    ... </span> <span class="py-keyword">for</span> i <span class="py-keyword">in</span> <span class="py-builtin">range</span>(26)
<span class="py-more">    ... </span> <span class="py-keyword">if</span> i % 2 == 0]
<span class="py-output">    ['A', 'C', 'E', 'G', 'I', 'K', 'M', 'O', 'Q', 'S', 'U', 'W', 'Y']</span>
</pre>
'''.strip()
    assert flatten(colorize_doctest(src)) == expected
Beispiel #18
0
def test_property_decorator(systemcls: Type[model.System]) -> None:
    """A function decorated with '@property' is documented as an attribute."""
    mod = fromText('''
    class C:
        @property
        def prop(self) -> str:
            """For sale."""
            return 'seaside'
        @property
        def oldschool(self):
            """
            @return: For rent.
            @rtype: string
            @see: U{https://example.com/}
            """
            return 'downtown'
    ''',
                   modname='test',
                   systemcls=systemcls)
    C = mod.contents['C']

    prop = C.contents['prop']
    assert isinstance(prop, model.Attribute)
    assert prop.kind == 'Property'
    assert prop.docstring == """For sale."""
    assert type2str(prop.annotation) == 'str'

    oldschool = C.contents['oldschool']
    assert isinstance(oldschool, model.Attribute)
    assert oldschool.kind == 'Property'
    assert isinstance(oldschool.parsed_docstring, ParsedEpytextDocstring)
    assert unwrap(oldschool.parsed_docstring) == """For rent."""
    assert flatten(format_summary(oldschool)) == '<span>For rent.</span>'
    assert isinstance(oldschool.parsed_type, ParsedEpytextDocstring)
    assert str(unwrap(oldschool.parsed_type)) == 'string'
    fields = oldschool.parsed_docstring.fields
    assert len(fields) == 1
    assert fields[0].tag() == 'see'
Beispiel #19
0
def summary2html(obj: model.Documentable) -> str:
    stan = epydoc2stan.format_summary(obj)
    assert stan.tagName == 'span', stan
    return flatten(stan.children)
Beispiel #20
0
def rst2html(s: str) -> str:
    errors: List[ParseError] = []
    parsed = parse_docstring(s, errors)
    assert not errors
    return flatten(parsed.to_stan(None))
def epytext2html(s):
    errors = []
    parsed = parse_docstring(s, errors)
    assert not errors
    return flatten(parsed.to_stan(None))
Beispiel #22
0
def to_html(
    parsed_docstring: ParsedDocstring,
    linker: DocstringLinker = NotFoundLinker()
) -> str:
    return flatten(parsed_docstring.to_stan(linker))
Beispiel #23
0
def epytext2html(s: str, linker: DocstringLinker = NotFoundLinker()) -> str:
    errs: List[ParseError] = []
    v = flatten(epytext.parse_docstring(s, errs).to_stan(linker))
    if errs:
        raise errs[0]
    return (v or '').rstrip()
Beispiel #24
0
def docstring2html(docstring: model.Documentable) -> str:
    stan = epydoc2stan.format_docstring(docstring)
    return flatten(stan).replace('><', '>\n<')
def epytext2html(s: str, linker: DocstringLinker = NotFoundLinker()) -> str:
    errors: List[ParseError] = []
    parsed = parse_docstring(s, errors)
    assert not errors
    return flatten(parsed.to_stan(linker))
Beispiel #26
0
def docstring2html(obj: model.Documentable) -> str:
    stan = epydoc2stan.format_docstring(obj)
    assert stan.tagName == 'div', stan
    return flatten(stan.children).replace('><', '>\n<')
Beispiel #27
0
def epytext2html(s):
    errs = []
    v = flatten(epytext.parse_docstring(s, errs).to_stan(None))
    if errs:
        raise errs[0]
    return (v or '').rstrip()
Beispiel #28
0
 def get_summary(func):
     stan = epydoc2stan.doc2stan(mod.contents[func], summary=True)
     assert stan.tagName == 'span', stan
     return flatten(stan.children)
Beispiel #29
0
def to_html(parsed_docstring):
    return flatten(parsed_docstring.to_stan(None))
Beispiel #30
0
 def get_summary(func: str) -> str:
     stan = epydoc2stan.format_summary(mod.contents[func])
     assert stan.tagName == 'span', stan
     return flatten(stan.children)