Skip to main content

flake8 for code in rst files and docstrings

Project description

flake8-rst module

PyPI conda-forge Build Status

Allows run flake8 on code snippets in docstrings or RST files.

Idea

idea proposed by Mike Bayer on https://github.com/zzzeek/sqlalchemy/pull/362

That said, if there was some alternate form of "doctest" that could simply test a code example both for Python syntax, pep8 compliance (which would be AWESOME) as well as symbol consistency, that would be helpful. The tool could be configured with common imports and symbols significant to SQLAlchemy examples and be helpful as a basic sanity check for code examples. As it is, when writing new documentation I have to organize and run the code in a separate .py file to make sure it does the right thing. So this is a problem, just my experience with doctest in writing the tutorials has shown me what it's good at and where it's likely getting in the way.

Realization inspired by https://github.com/asottile/blacken-docs

Usage

You can install tool from pip pip install flake8-rst.

Tool search sourcecode, code-block and ipython blocks, crop and run flake8 on it:

.. sourcecode:: python

    class Example(Base):
        pass

or

.. code-block:: python

    class Example(Base):
        pass

Supporting all flake8 arguments and flags except jobs (temporary), with additional one:

flake8-rst --bootstrap "import test"

flake8-rst bootstraps code snippets with this code, useful for fix import errors. Load configuration from [flake8-rst] ini sections, like flake8.

Advanced Usage

In order to use custom roles of flake8-rst in documentation with Sphinx, extend sphinx with flake8_rst.sphinxext.custom_roles in conf.py. The roles have no effect on the generated documentation.

extensions = [...,
              'flake8_rst.sphinxext.custom_roles'
              ]
role example
:flake8-group: Blocks with same group are combined to one. :flake8-group: Group1
Blocks with group None are checked individual. :flake8-group: None
:flake8-set-ignore: Overwrites ignore list for current block. :flake8-set-ignore: F821, E999
:flake8-add-ignore: Adds arguments to ignore list for current block. :flake8-add-ignore: E999
:flake8-set-select: Overwrites select list for current block. :flake8-set-select: E, F
:flake8-add-select: Adds arguments to select list for current block. :flake8-add-select: C404
:flake8-bootstrap: Overwrites --bootstrap for current block :flake8-bootstrap: import os; import sys

Keep in mind:

  • The default group is None for sourcecode and code-block directives and ipython for ipython directive.
    • So if not otherwise specified, code within ipython blocks is combined before passing to flake8.
    • Adding :flake8-group: None to a ipython block makes it beeing checked individual.
    • Adding :flake8-group: ipython to a code-block block integrates the code to the ipython blocks for the check.
  • Roles added to blocks within the same group (except group None) have no effect unless they appear in the first block.
  • provided bootstrap-code will get split by ; into individual lines.

Disconnected blocks don't know previous defined names:

.. code-block:: python

    class Example(Base):
        pass

.. code-block:: python

    import datetime

    obj = Example(datetime.datetime.now())            # F821 undefined name 'Example'

Once blocks are connected, different issues are found:

.. code-block:: python
    :flake8-group: ExampleGroup

    class Example(Base):
        pass

.. code-block:: python
    :flake8-group: ExampleGroup

    import datetime                                   # E402 module level import not at top of file

    obj = Example(datetime.datetime.now())

If appropriate, issues can be ignored for a specific group:

.. code-block:: python
    :flake8-group: ExampleGroup1
    :flake8-set-ignore: E402

    class Example(Base):
        pass

.. code-block:: python
    :flake8-group: ExampleGroup1

    import datetime

    obj = Example(datetime.datetime.now())



.. code-block:: python
    :flake8-group: ExampleGroup2

    class Example(Base):
        pass

.. code-block:: python
    :flake8-group: ExampleGroup2
    :flake8-set-ignore: E402                          # no effect, because it's not defined in first 
                                                      # block of ExampleGroup2 

    import datetime                                   # E402 module level import not at top of file

    obj = Example(datetime.datetime.now())

Example

d.kataev:flake8-rst§ flake8-rst --filename="*.py *.rst" tests/data/* --bootstrap="from sqlalchemy import Table, Column, Sequence, Integer, ForeignKey, String, DateTime"
tests/data/test.py:14:42: F821 undefined name 'metadata'
tests/data/test.py:15:13: E128 continuation line under-indented for visual indent
tests/data/test.py:16:28: F821 undefined name 'JSONB'
tests/data/test.py:19:14: F821 undefined name 'engine'
tests/data/test.py:22:21: E251 unexpected spaces around keyword / parameter equals
tests/data/test.py:22:23: E251 unexpected spaces around keyword / parameter equals
tests/data/test.rst:27:48: F821 undefined name 'metadata'
tests/data/test.rst:41:22: F821 undefined name 'meta'
tests/data/test.rst:56:52: F821 undefined name 'meta'
tests/data/test.rst:57:32: F821 undefined name 'meta'
tests/data/test.rst:69:20: F821 undefined name 'Base'
tests/data/test.rst:72:56: F821 undefined name 'Base'

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flake8-rst-0.5.0.tar.gz (25.7 kB view hashes)

Uploaded Source

Built Distribution

flake8_rst-0.5.0-py3-none-any.whl (11.5 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page