A Guide to Popular Python Static Analysis Tools
Python, known for its readability and versatility, has become a programming language of choice for many developers. As projects grow in complexity, ensuring code quality and security becomes paramount, and this is where Python static analysis tools emerge as unsung heroes.
Static code analysis involves the examination of an application's source code without its actual execution, revealing potential errors, security vulnerabilities, dependencies, bugs, and other issues embedded within the codebase.
Static code analysis tools are pivotal in scrutinizing code without executing it, identifying potential issues, and enforcing coding standards.
Whether you're a seasoned Python developer looking to enhance your codebase or a newcomer eager to adopt best practices from the outset, static analysis tools can be your best friend.
Here are a few excellent Python static analysis tools to check out.
mypy
mypy is a Python static type checker. It aims to enforce more disciplined coding practices by checking and inferring variable types, helping catch potential bugs early in development.
It also integrates with most popular integrated development environments (IDEs) to provide real-time feedback. Mypy also supports gradual typing, allowing developers to adopt it incrementally.
Gradual typing is an approach that allows a programming language to support both static typing and dynamic typing within the same codebase. It provides a smooth transition between the two typing systems, allowing developers to choose when and where to use static typing.
Static typing refers to a feature where variable types are explicitly declared and checked at compile time before the program is run. In statically typed languages, the data types of variables are determined and enforced during the compilation phase rather than at runtime, which is where variable types are checked and resolved when using dynamically typed languages.
Python is traditionally a dynamically typed language, meaning you don't need to declare a variable's data type explicitly. The variable type is determined at runtime based on the value it holds.
In recent versions of Python, however, there has been a move towards incorporating static typing through tools like "Type Hints." Type Hints allow developers to add type information to their code using annotations voluntarily. Static analysis tools like MyPy can use these hints to catch potential type-related errors before the code is run.
# Type Hints in Python 3.5+
def add_numbers(a: int, b: int) -> int:
return a + b
result = add_numbers(5, 10)
print(result) # Output: 15
MyPy enables you to write statically typed code while verifying the correctness of your types.
Pylint
Pylint is a widely used static code analysis tool that checks for coding standards and other coding errors, offering suggestions for improvement. It provides a comprehensive analysis covering various coding rules and potential issues.
Pylint is also easily configurable and extensible, allowing developers to tailor checks to their preferences. It can also be very helpful when refactoring code, enabling you to detect unused and duplicated code easily.
************* Module example
W: 2, 0: Unused add_numbers imported from example (unused-import)
C: 6, 0: Duplicate code for 'add_numbers' at line 6 (duplicate-code)
R: 12, 4: Too many statements (14/10) (too-many-statements)
You’re also able to write your own plugins for Pylint to add more personalized features.
Pyflakes
Pyflakes is a lightweight static analysis tool focused on identifying errors in Python code.
It’s fast and efficient, providing quick feedback during development. It’s also simple to use and suitable for integration into various workflows.
Pyflakes doesn’t focus on style. Instead, it focuses on logical code issues, errors in a program that do not cause syntax errors but result in incorrect or unintended behavior due to flawed logic or reasoning in the code.
If you also want style checks, you should check out flake8, which combines Pyflakes with style checking against the PEP 8 Python style guide.
The creators of Pyflakes claim that it rarely emits false positives and that it’s faster than Pylint.
pycodestyle
Formerly known as pep8, pycodestyle focuses on enforcing the style guide outlined in PEP 8. It’s straightforward and effective for maintaining code style consistency and easy to integrate.
If you want to check your code against the style conventions of PEP 8, this is the official linter for that purpose. You can get pycodestyle to show the source code for each error with the relevant text from PEP 8, which would look something like this:
example.py:3:12: E703 statement ends with a semicolon
example.py:3:12: E225 missing whitespace around operator
example.py:3:17: E703 statement ends with a semicolon
The above output indicates that there are issues with the code:
- E703: PEP 8 does not recommend using semicolons to terminate statements in Python. A newline typically terminates statements. The error suggests that the statement ends with a semicolon.
- E225: PEP 8 recommends adding whitespace around binary operators to improve readability. The error suggests that there is missing whitespace around the + operator.
Bandit
Bandit is a security-focused static analysis tool that detects security vulnerabilities like hard-coded passwords, shell injections, SQL injections, and invalid pickle serialization/deserialization.
It integrates well into continuous integration/continuous delivery (CI/CD) pipelines to perform ongoing security checks as you code.
The only real shortcoming of Bandit is that it’s limited to security-related issues and may not catch broader coding issues. Like most other code security tools, Bandit may sometimes produce false positives.
PMD CPD
PMD’s Copy/Paste Detector (CPD) helps developers locate duplicate code. It works with Python and many other popular programming languages, including Java, C/C++, C#, Go, Ruby, Swift, and more.
Why is it essential to be able to locate duplicate blocks of code? If identical code blocks serve the same purpose, any effort to restructure them, even in a simple manner, leads to repetitive manual grunt work. Locating every instance of duplicate code that requires refactoring is another tedious task when performed manually.
A tool like PMD CPD can help you find the duplicates and take them out of your code so that you can avoid refactoring altogether.
Radon and McCabe
Both Radon and McCabe help developers analyze and measure code complexity. Radon calculates cyclomatic complexity and the maintainability index of your code.
Cyclomatic Complexity measures program complexity by counting the number of independent paths through its source code. A higher cyclomatic complexity indicates greater code complexity and may suggest a need for simplification or refactoring.
The maintainability index quantifies how maintainable and understandable a program's source code is, considering factors such as cyclomatic complexity, code size, and duplication. The higher your maintainability index score, the more maintainable your code appears to be.
McCabe also measures the cyclomatic complexity of your functions. It's a good option if you want a no-frills tool focused on that one metric and nothing else.
Prospector
Prospector is a tool that combines various Python analysis tools to provide a holistic view of code quality. It’s highly customizable and allows you to tailor which tools are included in your analysis.
It’s also easily integrated into tools like Jenkins, CircleCI, GitHub, and GitLab.
Prospector runs several of the tools we’ve already discussed and some additional ones. The default options include:
- Pylint
- pycodestyle
- Pyflakes
- Pyflakes
- Pydocstyle
- McCabe
Some option extras you can add to Prospector include:
- Mypy
- Bandit
- Pyroma, a tool that ensures best practices of the Python packaging ecosystem and warns you if you’re missing any package metadata that could improve package quality.
- Vulture, which finds unused classes, functions, and variables
- Frosted, a fork of pyflakes created to extend pyflakes development at a time when development slowed for the tool.
Prospect is a bit resource-intensive since so many tools are packaged together, especially when reviewing larger codebases.
Run Multiple Tools Simultaneously with a Static Analysis Platform
A code quality platform like Codacy gives you access to many popular Python static analysis tools under one roof. With Codacy, every time you run static analysis on your code, it’s being reviewed by Bandit, Prospector, Pylint, PMD CPD, and Radon.
Codacy even integrates with popular security scanner Trivy, which runs secrets and insecure dependencies detection. Check out our list of supported languages and tools to get a full rundown of Codacy’s integrations and features.
Sign up for a free trial today to see how easy it is to perform static code analysis with Codacy, no matter your preferred programming language.