This project is no longer actively maintained.
Contents
TidyPy is a tool that encapsulates a number of other static analysis tools and makes it easy to configure, execute, and review their results.
*.py source files. In addition to executing a
number of different tools on your code, it can also check your YAML, JSON,
PO, POT, and RST files.pyproject.toml file defined by PEP 518. All
options for all the tools TidyPy uses are declared in one place, rather than
requiring that you configure each tool in a different way.# noqa comment in your Python source to easily
ignore issues reported by any tool.When TidyPy is installed (pip install tidypy), the tidypy command
should become available in your environment:
$ tidypy --help
Usage: tidypy [OPTIONS] COMMAND [ARGS]...
A tool that executes several static analysis tools upon a Python project
and aggregates the results.
Options:
--version Show the version and exit.
--help Show this message and exit.
Commands:
check Executes the tools upon the project files.
default-config Outputs a default configuration that can be used to
bootstrap your own configuration file.
extensions Outputs a listing of all available TidyPy extensions.
install-vcs Installs TidyPy as a pre-commit hook into the specified
VCS.
list-codes Outputs a listing of all known issue codes that tools
may report.
purge-config-cache Deletes the cache of configurations retrieved from
outside the primary configuration.
remove-vcs Removes the TidyPy pre-commit hook from the specified
VCS.
To have TidyPy analyze your project, use the check subcommand:
$ tidypy check --help
Usage: tidypy check [OPTIONS] [PATH]
Executes the tools upon the project files.
Accepts one argument, which is the path to the base of the Python project.
If not specified, defaults to the current working directory.
Options:
-x, --exclude REGEX Specifies a regular expression matched
against paths that you want to exclude from
the examination. Can be specified multiple
times. Overrides the expressions specified
in the configuration file.
-t, --tool [bandit|dlint|eradicate|jsonlint|manifest|mccabe|polint|pycodestyle|pydiatra|pydocstyle|pyflakes|pylint|pyroma|rstlint|secrets|vulture|yamllint]
Specifies the name of a tool to use during
the examination. Can be specified multiple
times. Overrides the configuration file.
-r, --report [console,csv,custom,json,null,pycodestyle,pylint,pylint-parseable,toml,yaml][:filename]
Specifies the name of a report to execute
after the examination. Can specify an
optional output file name using the form -r
report:filename. If filename is unset, the
report will be written on stdout. Can be
specified multiple times. Overrides the
configuration file.
-c, --config FILENAME Specifies the path to the TidyPy
configuration file to use instead of the
configuration found in the project's
pyproject.toml.
--workers NUM_WORKERS The number of workers to use to concurrently
execute the tools. Overrides the
configuration file.
--disable-merge Disable the merging of issues from various
tools when TidyPy considers them equivalent.
Overrides the configuration file.
--disable-progress Disable the display of the progress bar.
--disable-noqa Disable the ability to ignore issues using
the "# noqa" comment in Python files.
--disable-config-cache Disable the use of the cache when retrieving
configurations referenced by the "extends"
option.
--help Show this message and exit.
If you need to generate a skeleton configuration file with the default options,
use the default-config subcommand:
$ tidypy default-config --help
Usage: tidypy default-config [OPTIONS]
Outputs a default configuration that can be used to bootstrap your own
configuration file.
Options:
--pyproject Output the config so that it can be used in a pyproject.toml
file.
--help Show this message and exit.
If you'd like to see a list of the possible issue codes that could be returned,
use the list-codes subcommand:
$ tidypy list-codes --help
Usage: tidypy list-codes [OPTIONS]
Outputs a listing of all known issue codes that tools may report.
Options:
-t, --tool [bandit|dlint|eradicate|jsonlint|manifest|mccabe|polint|pycodestyle|pydiatra|pydocstyle|pyflakes|pylint|pyroma|rstlint|secrets|vulture|yamllint]
Specifies the name of a tool whose codes
should be output. If not specified, defaults
to all tools.
-f, --format [toml|json|yaml|csv]
Specifies the format in which the tools
should be output. If not specified, defaults
to TOML.
--help Show this message and exit.
If you want to install or remove TidyPy as a pre-commit hook in your project's
VCS, use the install-vcs/remove-vcs subcommands:
$ tidypy install-vcs --help
Usage: tidypy install-vcs [OPTIONS] VCS [PATH]
Installs TidyPy as a pre-commit hook into the specified VCS.
Accepts two arguments:
VCS: The version control system to install the hook into. Choose from:
git, hg
PATH: The path to the base of the repository to install the hook into.
If not specified, defaults to the current working directory.
Options:
--strict Whether or not the hook should prevent the commit if TidyPy finds
issues.
--help Show this message and exit.
$ tidypy remove-vcs --help
Usage: tidypy remove-vcs [OPTIONS] VCS [PATH]
Removes the TidyPy pre-commit hook from the specified VCS.
Accepts two arguments:
VCS: The version control system to remove the hook from. Choose from:
git, hg
PATH: The path to the base of the repository to remove the hook from. If
not specified, defaults to the current working directory.
Options:
--help Show this message and exit.
If you'd like to enable bash completion for TidyPy, run the following in your shell (or put it in your bash startup scripts):
$ eval "$(_TIDYPY_COMPLETE=source tidypy)"
If you don't want to install TidyPy locally on your system or in your virtualenv, you can use the published Docker image:
$ docker run --rm --tty --volume=`pwd`:/project tidypy/tidypy
The command above will run tidypy check on the contents of the current
directory. If you want to run it on a different directory, then change the
`pwd` to whatever path you need (the goal being to mount your project
directory to the container's /project volume).
Running TidyPy in this manner has a few limitiations, mostly around the fact that since TidyPy is running in its own, isolated Python environment, tools like pylint won't be able to introspect the packages your project installed locally, so it may report false positives around "import-error", "no-name-in-module", "no-member", etc.
If you want to run a command other than check, just pass that along when
you invoke docker:
$ docker run --rm --tty --volume=`pwd`:/project tidypy/tidypy tidypy list-codes
TODO
In addition to ignoring entire files, tools, or specific issue types from tools via your configuration file, you can also use comments in your Python source files to ignore issues on specific lines. Some tools have their own built-in support and notation for doing this:
# pylint# nosec# noqa# noqa# pragma: whitelist
secretTidyPy goes beyond these tool-specific flags to implement # noqa on a
global scale for Python source files. It will ignore issues for lines that have
the # noqa comment, regardless of what tools raise the issues. If you only
want to ignore a particular type of issue on a line, you can use syntax like
the following:
# noqa: CODE1,CODE2
Or, if a particular code is used in multiple tools, you can specify the exact tool in the comment:
# noqa: pycodestyle:CODE1,pylint:CODE2
Or, if you want to ignore any issue a specific tool raises on a line, you can specify the tool:
# noqa: @pycodestyle,@pylint
You can, of course, mix and match all three notations in a single comment if you need to:
# noqa: CODE1,pylint:CODE2,@pycodestyle
You can disable TidyPy's NOQA behavior by specifying the --disable-noqa
option on the command line, or by setting the noqa option to false in
your configuration file. A caveat, though: currently pycodestyle and pydocstyle
do not respect this option and will always honor any # noqa comments they
find.
Out of the box, TidyPy includes support for a number of tools:
TidyPy includes a number of different methods to present and/or export the results of the analysis of a project. Out of the box, it provides the following:
filename, line, character,
tool, code, message.TidyPy includes a handful of plugins/integrations that hook it into other tools.
--tidypy on the command line when you run
pytest, or include it as part of the addopts property in your pytest
config.--with-tidypy on the command line when you
run nose, or set the with-tidypy property to 1 in your
setup.cfg.tidypy test.
To enable it, you can either specify --extend=tidypy.plugin.pbbt on the
command line when you run PBBT, or set the extend property in your
setup.cfg or pbbt.yaml to tidypy.plugin.pbbt.A simple interface exists for extending TidyPy to include more and different
tools and reporters. To add a tool, create a class that extends tidypy.Tool,
and in your setup.py, declare an entry_point for tidypy.tools that
points to your class:
entry_points={
'tidypy.tools': [
'mycooltool = path.to.model:MyCoolToolClassName',
],
}
To add a reporter, the process is nearly identical, except that you extend
tidypy.Report and declare an entry_point for tidypy.reports.
Yea, that happens. The philosophy I chose to follow with this tool is that I didn't want it to hide anything from me. I wanted its default behavior to execute every tool in its suite using their most obnoxious setting. Then, when I can see the full scope of damage, I can then decide to disable specific tools or issues via a project-level configuration. I figured if someone took the time to implement a check for a particular issue, they must think it has some value. If my tooling hides that from me by default, then I won't be able to gain any benefits from it.
In general, I don't recommend starting to use linters or other sorts of static analyzers when you think you're "done". You should incorporate them into your workflow right at the beginning of a project -- just as you would (or should) your unit tests. That way you find things early and learn from them (or disable them). It's much less daunting a task to deal with when you address them incrementally.
Contributions are most welcome. Particularly if they're bug fixes! To hack on
this code, simply clone it, and then run make setup. This will create a
virtualenv with all the tools you'll need. The Makefile also has a test
target for running the pytest suite, and a lint target for running TidyPy
on itself.
TidyPy is released under the terms of the MIT License.