https://github.com/best-doctor/mr_proper
Static Python code analyzer, that tries to check if functions in code are pure or not and why.
https://github.com/best-doctor/mr_proper
pure-function python static-analyzer
Last synced: 8 months ago
JSON representation
Static Python code analyzer, that tries to check if functions in code are pure or not and why.
- Host: GitHub
- URL: https://github.com/best-doctor/mr_proper
- Owner: best-doctor
- License: mit
- Created: 2019-10-27T19:04:11.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2023-04-11T09:05:36.000Z (about 3 years ago)
- Last Synced: 2025-07-21T10:51:47.732Z (11 months ago)
- Topics: pure-function, python, static-analyzer
- Language: Python
- Size: 250 KB
- Stars: 19
- Watchers: 2
- Forks: 3
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# mr. Proper
[](https://travis-ci.org/best-doctor/mr_proper)
[](https://badge.fury.io/py/mr-proper)
[](https://codeclimate.com/github/best-doctor/mr_proper/maintainability)
[](https://codeclimate.com/github/best-doctor/mr_proper/test_coverage)
Static Python code analyzer, that tries to check if functions in code are
[pure](https://en.wikipedia.org/wiki/Pure_function) or not and why.

*DISCLAIMER*: this library is very experimental and has a lot of edge cases.
Functions that mr. Proper marks as pure can be not pure, but they are
usually cleaner than other functions.
## Installation
```bash
pip install mr_proper
```
## What mr. Proper check
1. that function has no blacklisted calls (like `print`)
and blacklisted attributes access (like `smth.count`);
1. that function not uses global objects (only local vars and function arguments);
1. that function has al least one return;
1. that function not mutates it's arguments;
1. that function has no local imports;
1. that function has no arguments of forbidden types (like ORM objects);
1. that function not uses `self`, `class` or `super`;
1. that function has calls of only pure functions.
This list is not enough to say that function is pure and some points
are quite controversial, but it's a nice start.
## Example
Console usage:
```python
# test.py
def add_one(n: int) -> int:
return n + 1
def print_amount_of_users(users_qs: QuerySet) -> None:
print(f'Current amount of users is {users_qs.count()}')
```
```bash
$ mr_propper test.py
add_one is pure!
print_amount_of_users is not pure because of:
it uses forbidden argument types (QuerySet)
it calls not pure functions (print)
it has no return
```
Usage inside Python code sample:
```jupyterpython
>>> import ast
>>> from mr_propper.utils import is_function_pure
>>> funcdef = ast.parse('''
def add_one(n: int) -> int:
return n + 1
''').body[0]
>>> is_function_pure(funcdef)
True
>>> is_function_pure(funcdef, with_errors=True)
(True, [])
```
## Parameters
CLI interface:
- `filepath`: path to .py file to check (directories are not supported for now);
- `--recursive`: require inner calls to be pure for function pureness.
## Code prerequisites
1. Python 3.7+;
1. Functions are fully type-annotated;
1. No dynamic calls (like `getattr(sender, 'send_' + message_type)(message)`).
## Contributing
We would love you to contribute to our project. It's simple:
1. Create an issue with bug you found or proposal you have.
Wait for approve from maintainer.
1. Create a pull request. Make sure all checks are green.
1. Fix review comments if any.
1. Be awesome.
Here are useful tips:
- You can run all checks and tests with `make check`.
Please do it before TravisCI does.
- We use [BestDoctor python styleguide](https://github.com/best-doctor/guides/blob/master/guides/en/python_styleguide.md).
- We respect [Django CoC](https://www.djangoproject.com/conduct/).
Make soft, not bullshit.