Ejemplo n.º 1
0
    def _lint_lines(errors: List[Tuple[str, int, int,
                                       str]], fragment: ChangelogFragment,
                    section: str, lines: Any) -> None:
        """
        Lint lines of a changelog fragment.
        """
        if isinstance(lines, list):
            for line in lines:
                if not isinstance(line, str):
                    errors.append((fragment.path, 0, 0,
                                   'section "%s" list items must be type str '
                                   'not %s' % (section, type(line).__name__)))
                    continue

                results = rstcheck.check(
                    line,
                    filename=fragment.path,
                    report_level=docutils.utils.Reporter.WARNING_LEVEL)
                errors += [(fragment.path, 0, 0, result[1])
                           for result in results]
        elif isinstance(lines, str):
            results = rstcheck.check(
                lines,
                filename=fragment.path,
                report_level=docutils.utils.Reporter.WARNING_LEVEL)
            errors += [(fragment.path, 0, 0, result[1]) for result in results]
Ejemplo n.º 2
0
    def lint(self, fragment):
        """Lint a ChangelogFragment.
        :type fragment: ChangelogFragment
        :rtype: list[(str, int, int, str)]
        """
        errors = []

        for section, lines in fragment.content.items():
            if section == self.config.prelude_name:
                if not isinstance(lines, string_types):
                    errors.append((fragment.path, 0, 0, 'section "%s" must be type str not %s' % (section, type(lines).__name__)))
            else:
                # doesn't account for prelude but only the RM should be adding those
                if not isinstance(lines, list):
                    errors.append((fragment.path, 0, 0, 'section "%s" must be type list not %s' % (section, type(lines).__name__)))

                if section not in self.config.sections:
                    errors.append((fragment.path, 0, 0, 'invalid section: %s' % section))

            if isinstance(lines, list):
                for line in lines:
                    if not isinstance(line, string_types):
                        errors.append((fragment.path, 0, 0, 'section "%s" list items must be type str not %s' % (section, type(line).__name__)))
                        continue

                    results = rstcheck.check(line, filename=fragment.path, report_level=docutils.utils.Reporter.WARNING_LEVEL)
                    errors += [(fragment.path, 0, 0, result[1]) for result in results]
            elif isinstance(lines, string_types):
                results = rstcheck.check(lines, filename=fragment.path, report_level=docutils.utils.Reporter.WARNING_LEVEL)
                errors += [(fragment.path, 0, 0, result[1]) for result in results]

        return errors
Ejemplo n.º 3
0
    def lint(self, fragment):
        """Lint a ChangelogFragment.
        :type fragment: ChangelogFragment
        :rtype: list[(str, int, int, str)]
        """
        errors = []

        for section, lines in fragment.content.items():
            if section not in self.config.sections:
                errors.append(
                    (fragment.path, 0, 0, 'invalid section: %s' % section))

            if isinstance(lines, list):
                for line in lines:
                    results = rstcheck.check(
                        line,
                        filename=fragment.path,
                        report_level=docutils.utils.Reporter.WARNING_LEVEL)
                    errors += [(fragment.path, 0, 0, result[1])
                               for result in results]
            else:
                results = rstcheck.check(
                    lines,
                    filename=fragment.path,
                    report_level=docutils.utils.Reporter.WARNING_LEVEL)
                errors += [(fragment.path, 0, 0, result[1])
                           for result in results]

        return errors
Ejemplo n.º 4
0
def test_rst(rst_file):
    with open(rst_file) as input_file:
        contents = input_file.read()

    all_errors = []
    errors = rstcheck.check(contents,
                            report_level=2,
                            ignore={"languages": ["python", "bash"]})
    for line_number, error in errors:
        # report only warnings and higher, ignore Python and Bash pseudocode examples
        if "Title underline too short" in error:
            # These are caused by unicode en dashes and can be ignored
            continue

        # Ignore to text roles provided via Sphinx extensions erroneously marked as unrecognized
        m = re.search('Unknown interpreted text role "([^"]+)"', error)
        if m and m.group(1) in ["program", "paramref"]:
            continue

        m = re.search('Unknown directive type "([^"]+)"', error)
        if m and m.group(1) in ["automodule"]:
            continue

        all_errors.append((line_number, error))

    assert len(all_errors) == 0
Ejemplo n.º 5
0
def test_readme_rst():
    import rstcheck
    with open('README.rst') as f:
        readme = f.read()
    errors = list(rstcheck.check(readme))

    assert errors == []
Ejemplo n.º 6
0
def test_rst(rst_file):
    with open(rst_file) as input_file:
        contents = input_file.read()

    all_errors = []
    errors = rstcheck.check(
        contents,
        report_level=2,
        ignore={
            'languages': ['python', 'bash']
        }
    )
    for line_number, error in errors:
        # report only warnings and higher, ignore Python and Bash pseudocode examples
        if 'Title underline too short' in error:
            # These are caused by unicode en dashes and can be ignored
            continue

        # Ignore to text roles provided via Sphinx extensions erroneously marked as unrecognized
        m = re.search('Unknown interpreted text role "([^"]+)"', error)
        if m and m.group(1) in ['program', 'paramref']:
            continue

        m = re.search('Unknown directive type "([^"]+)"', error)
        if m and m.group(1) in ['automodule']:
            continue

        all_errors.append((line_number, error))

    assert len(all_errors) == 0
Ejemplo n.º 7
0
    def visit_FunctionDef(self, node: ast.FunctionDef):
        # clean=True removes all leading spaces far more reliably than
        # textwrap.dedent, not to mention expanding tabs to spaces.
        docstring = ast.get_docstring(node, clean=True)
        if docstring:
            original_line_numbers = {}
            for line_no, line in enumerate(docstring.split('\n')):
                original_line_numbers[line.strip()] = line_no

            parsed_docstring = GoogleDocstring(docstring).__str__()
            print(parsed_docstring)

            # TODO: How do I correctly map line numbers back to the original
            # source?
            parsed_line_numbers = {}
            for line_no, line in enumerate(parsed_docstring.split('\n')):
                line_without_directives = re.sub('^:[a-zA-Z0-9_-]+:', '',
                                                 line.strip())

                parsed_line_numbers[line.strip()] = line_no

            # Line number, column offset, RST error
            for local_line_no, rst_error in rstcheck.check(parsed_docstring):
                self.problems.append((node.lineno + local_line_no + 1,
                                      node.col_offset, "NAP001 " + rst_error))

        self.generic_visit(node)
Ejemplo n.º 8
0
    def test_check_rst_report_level(self):
        self.assert_lines_equal([],
                                rstcheck.check("""\
Test
===
""",
                                               report_level=5))
Ejemplo n.º 9
0
    def test_check_rst(self):
        self.assert_lines_equal(
            [2],
            rstcheck.check(
                """\
Test
===
"""))
Ejemplo n.º 10
0
    def test_check_rst(self):
        self.assert_lines_equal(
            [2],
            rstcheck.check(
                """\
Test
===
"""))
Ejemplo n.º 11
0
def test_readme_is_proper_rst():
    parent = pathlib.Path(__file__).parent.resolve().parent
    path_to_readme = parent / "README.rst"

    with path_to_readme.open() as f:
        rst = f.read()

    errors = list(rstcheck.check(rst))
    assert len(errors) == 0, "; ".join(str(e) for e in errors)
Ejemplo n.º 12
0
def _check_docstring(text):
    split_docstring = text.split('\n')
    docstring = '\n'.join(
        [split_docstring[0]] +
        textwrap.dedent('\n'.join(split_docstring[1:])).split('\n'))

    parsed_docstring = GoogleDocstring(docstring, config).__str__()

    return rstcheck.check(docstring)
Ejemplo n.º 13
0
 def action(files):
     results = []
     for file in files:
         with open(file) as fh:
             lines = fh.read()
         result = list(rstcheck.check(lines))
         if result:
             results.append(file, *result)
     return results
Ejemplo n.º 14
0
    def test_check_rst_report_level(self):
        self.assert_lines_equal(
            [],
            rstcheck.check(
                """\
Test
===
""",
                report_level=5))
Ejemplo n.º 15
0
    def test_check_code_block(self):
        self.assert_lines_equal([6],
                                rstcheck.check("""\
Test
====

.. code-block:: python

    print(
"""))
Ejemplo n.º 16
0
    def test_check_doctest(self):
        self.assert_lines_equal([5],
                                rstcheck.check("""\
Testing
=======

>>> x = 1
>>>> x
1
"""))
Ejemplo n.º 17
0
    def test_readme_valid(self):
        import rstcheck

        with open('README.rst') as f:
            rst = f.read()
            errors = list(rstcheck.check(rst))

            for line, error in errors:
                print('{}: {}'.format(line, error))
            self.assertTrue(len(errors) == 0)
Ejemplo n.º 18
0
    def test_check_doctest_do_not_crash_when_indented(self):
        """docutils does not provide line number when indented."""
        list(rstcheck.check(
            """\
Testing
=======

    >>> x = 1
    >>>> x
    1
"""))
Ejemplo n.º 19
0
    def test_check_regex(self):
        self.assert_lines_equal([6],
                                rstcheck.check("""\
Test
====

.. code-block:: regex

    [0-9]++

"""))
Ejemplo n.º 20
0
    def test_check_doctest_do_not_crash_when_indented(self):
        """docutils does not provide line number when indented."""
        list(rstcheck.check(
            """\
Testing
=======

    >>> x = 1
    >>>> x
    1
"""))
Ejemplo n.º 21
0
    def __processCommands(self, commands):
        content = "\n".join(commands)
        results=[]

        with rstcheck.enable_sphinx_if_possible():
            results = list(rstcheck.check(content))


        for result in results:
            logger.debug(f"{result[0]}:{result[1]}")
            print(f"{result[0]}:{result[1]}")
        print(f"{self.endSeq}", flush=True)
Ejemplo n.º 22
0
    def test_check(self):
        self.assert_lines_equal(
            [6],
            rstcheck.check(
                """\
Test
====

.. code-block:: python

    print(
"""))
Ejemplo n.º 23
0
    def test_check_doctest(self):
        self.assert_lines_equal(
            [5],
            rstcheck.check(
                """\
Testing
=======

>>> x = 1
>>>> x
1
"""))
Ejemplo n.º 24
0
def lint_optional_conditions(
        content: str, path: str,
        collection_name: str) -> t.List[t.Tuple[int, int, str]]:
    '''Check a extra docs RST file's content for whether it satisfied the required conditions.

    Return a list of errors.
    '''
    results = rstcheck.check(
        content,
        filename=path,
        report_level=docutils.utils.Reporter.WARNING_LEVEL)
    return [(result[0], 0, result[1]) for result in results]
Ejemplo n.º 25
0
    def test_check_regex_with_bad_ignore(self):
        self.assert_lines_equal([6, 8],
                                rstcheck.check("""\
Test
====

.. code-block:: regex

    [0-9]++

.. rstcheck: ignore-language regex,python,rst
"""))
Ejemplo n.º 26
0
    def test_check_doctest_in_code_block(self):
        self.assert_lines_equal([7],
                                rstcheck.check("""\
Testing
=======

.. code-block:: doctest

    >>> x = 1
    >>>> x
    1
"""))
Ejemplo n.º 27
0
    def test_check_json(self):
        self.assert_lines_equal([7],
                                rstcheck.check("""\
Test
====

.. code-block:: json

    {
        'abc': 123
    }
"""))
Ejemplo n.º 28
0
    def test_check_regex_with_unmatched_ignores_only(self):
        self.assert_lines_equal([6],
                                rstcheck.check("""\
Test
====

.. code-block:: regex

    [0-9]++

.. rstcheck: ignore-language=cpp,python,rst
"""))
Ejemplo n.º 29
0
    def test_check_doctest_with_ignore(self):
        self.assert_lines_equal([],
                                rstcheck.check("""\
Testing
=======

>>> x = 1
>>>> x
1

.. rstcheck: ignore-language=doctest
"""))
Ejemplo n.º 30
0
    def test_check_with_extra_blank_lines_before(self):
        self.assert_lines_equal([8],
                                rstcheck.check("""\
Test
====

.. code-block:: python



    print(
"""))
Ejemplo n.º 31
0
    def test_check_doctest_in_python_code_block(self):
        """I'm not sure if this is correct, but I've seen people do it."""
        self.assert_lines_equal([7],
                                rstcheck.check("""\
Testing
=======

.. code-block:: python

    >>> x = 1
    >>>> x
    1
"""))
Ejemplo n.º 32
0
    def test_check_xml(self):
        self.assert_lines_equal([8],
                                rstcheck.check("""\
Test
====

.. code-block:: xml

    <?xml version="1.0" encoding="UTF-8"?>
    <root>
       </abc>123<abc>
    </root>
"""))
Ejemplo n.º 33
0
    def visit_ClassDef(self, node: ast.ClassDef):
        # clean=True removes all leading spaces far more reliably than
        # textwrap.dedent, not to mention expanding tabs to spaces.
        docstring = ast.get_docstring(node, clean=True)
        if docstring:
            parsed_docstring = GoogleDocstring(docstring).__str__()

            # Line number, column offset, RST error
            for local_line_no, rst_error in rstcheck.check(parsed_docstring):
                self.problems.append((node.lineno + local_line_no + 1,
                                      node.col_offset, "NAP001 " + rst_error))

        self.generic_visit(node)
Ejemplo n.º 34
0
    def test_check_with_extra_blank_lines_before(self):
        self.assert_lines_equal(
            [8],
            rstcheck.check(
                """\
Test
====

.. code-block:: python



    print(
"""))
Ejemplo n.º 35
0
    def test_check_json_with_bad_ignore(self):
        self.assert_lines_equal([7, 10],
                                rstcheck.check("""\
Test
====

.. code-block:: json

    {
        'abc': 123
    }

.. rstcheck: ignore-language json,python,rst
"""))
Ejemplo n.º 36
0
    def test_check_doctest_with_ignore(self):
        self.assert_lines_equal(
            [],
            rstcheck.check(
                """\
Testing
=======

>>> x = 1
>>>> x
1

.. rstcheck: ignore-language=doctest
"""))
Ejemplo n.º 37
0
    def test_check_doctest_in_code_block(self):
        self.assert_lines_equal(
            [7],
            rstcheck.check(
                """\
Testing
=======

.. code-block:: doctest

    >>> x = 1
    >>>> x
    1
"""))
Ejemplo n.º 38
0
    def test_check_json(self):
        self.assert_lines_equal(
            [7],
            rstcheck.check(
                """\
Test
====

.. code-block:: json

    {
        'abc': 123
    }
"""))
Ejemplo n.º 39
0
    def test_ignore_sphinx_directives(self):
        self.assert_lines_equal(
            [],
            rstcheck.check(
                """\
.. toctree::
    :maxdepth: 2

    intro
    strings
    datatypes
    numeric
    (many more documents listed here)
"""))
Ejemplo n.º 40
0
 def visit_functiondef(self, node):
     """
     Check if docstring always starts and ends from/by triple double-quotes
     and they are on the new line.
     """
     if hasattr(node, "doc") and node.doc:
         out = list(rstcheck.check(node.doc.strip()))
         if out:
             messages = []
             for errcode, msg in out:
                 messages.append(msg)
             self.add_message("docstring-rst-format",
                              node=node,
                              args=(", ".join(messages), ))
Ejemplo n.º 41
0
    def test_check_json_with_unmatched_ignores_only(self):
        self.assert_lines_equal([7],
                                rstcheck.check("""\
Test
====

.. code-block:: json

    {
        'abc': 123
    }

.. rstcheck: ignore-language=cpp,python,rst
"""))
Ejemplo n.º 42
0
    def test_check_xml_with_bad_ignore(self):
        self.assert_lines_equal([8, 11],
                                rstcheck.check("""\
Test
====

.. code-block:: xml

    <?xml version="1.0" encoding="UTF-8"?>
    <root>
       </abc>123<abc>
    </root>

.. rstcheck: ignore-language xml,python,rst
"""))
Ejemplo n.º 43
0
    def test_check_doctest_in_python_code_block(self):
        """I'm not sure if this is correct, but I've seen people do it."""
        self.assert_lines_equal(
            [7],
            rstcheck.check(
                """\
Testing
=======

.. code-block:: python

    >>> x = 1
    >>>> x
    1
"""))
Ejemplo n.º 44
0
    def test_check_json_with_unmatched_ignores_only(self):
        self.assert_lines_equal(
            [7],
            rstcheck.check(
                """\
Test
====

.. code-block:: json

    {
        'abc': 123
    }

.. rstcheck: ignore-language=cpp,python,rst
"""))
Ejemplo n.º 45
0
    def test_check_json_with_bad_ignore(self):
        self.assert_lines_equal(
            [7, 10],
            rstcheck.check(
                """\
Test
====

.. code-block:: json

    {
        'abc': 123
    }

.. rstcheck: ignore-language json,python,rst
"""))
Ejemplo n.º 46
0
def check_readme(file='README.rst'):
    """
    Checks readme rst file, to ensure it will upload to pypi and be formatted correctly.
    :param file:
    :return:
    """
    # Get the long description from the relevant file
    with open(file, encoding='utf-8') as f:
        readme_content = f.read()

    errors = list(rstcheck.check(readme_content))
    if errors:
        msg = 'There are errors in {}, errors \n {}'.format(file, str(errors[0]))
        raise SystemExit(msg)
    else:
        msg = 'No errors in {}'.format(file)
        print(msg)
Ejemplo n.º 47
0
    def test_ignore_sphinx_directives(self):
        self.assert_lines_equal(
            [],
            rstcheck.check(
                """\
.. toctree::
    :maxdepth: 2

    intro
    strings
    datatypes
    numeric
    (many more documents listed here)

.. highlight:: python
   :linenothreshold: 5

::

   print('Hello')

.. code-block:: ruby
   :linenos:

   puts "Hello!"

.. code-block:: python
   :linenos:
   :emphasize-lines: 3,5

   def some_function():
       interesting = False
       print('This line is highlighted.')
       print('This one is not...')
       print('...but this one is.')

.. literalinclude:: rstcheck.py
   :language: python
   :linenos:

"""))
Ejemplo n.º 48
0
    def test_check_nested_rst(self):
        self.assert_lines_equal(
            [32],
            rstcheck.check(
                """\
Test
====

.. code-block:: rst

    Test
    ====

    .. code-block:: rst


        Test
        ====

        .. code-block:: rst

            Test
            ====

            .. code-block:: rst

                Test
                ====

                .. code-block:: rst

                    Test
                    ====

                    .. code-block:: python

                        print(
"""))