See: codacy_hack.py for examples.
Codacy runs PyLint so we already have a linter in place.
The ideal linter in a dynamic language should flag issues that the compiler would flag in a compiled language.
The linter should raise an alert if there is a syntax error or if an import is missing just like a compiler would. It should warn you that basestring, cmp(), long, reload(), unicode, xrange() are not builtins in Python 3.
Codacy does none of these things that a compiler would. It merely says that async def func(): is not valid Python. (Argh!?!) It seems to be tuned to Python 2 and is therefor more legacy than the PyLint that it is based on. In the hands of a strong practitioner, PyLint can catch many of the issues mentioned above but it requires configuration and usually a lot of # pylint: disable=xyz directives in your code.
I prefer flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics to catch the syntax errors and undefined names that Codacy does not.
Add flake8 tests to find Python syntax errors and undefined names.
E901,E999,F821,F822,F823 are the "showstopper" flake8 issues that can halt the runtime with a SyntaxError, NameError, etc. Most other flake8 issues are merely "style violations" -- useful for readability but they do not effect runtime safety.
- F821: undefined name
name
- F822: undefined name
name
in__all__
- F823: local variable name referenced before assignment
- E901: SyntaxError or IndentationError
- E999: SyntaxError -- failed to compile a file into an Abstract Syntax Tree