mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-18 04:18:10 +00:00
feat: custom Pylint plugin
for now, it catches the following incorrect function: async def show_foo() -> Awaitable[None]: return show_something_else("foo") because to correctly show the result, the caller would have to "await (await show_foo())" (this should either be "async def show_foo() -> None", or "def show_foo() -> Awaitable[None]")
This commit is contained in:
parent
3d356b25ab
commit
f0d6539d3d
29
poetry.lock
generated
29
poetry.lock
generated
@ -1,4 +1,4 @@
|
|||||||
# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand.
|
# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand.
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "astroid"
|
name = "astroid"
|
||||||
@ -1550,7 +1550,7 @@ testing = ["flaky (>=3.4.0)", "freezegun (>=0.3.11)", "pathlib2 (>=2.3.3)", "psu
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "trezor"
|
name = "trezor"
|
||||||
version = "0.13.8"
|
version = "0.13.9"
|
||||||
description = "Python library for communicating with Trezor Hardware Wallet"
|
description = "Python library for communicating with Trezor Hardware Wallet"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.6"
|
python-versions = ">=3.6"
|
||||||
@ -1568,17 +1568,34 @@ requests = ">=2.4.0"
|
|||||||
typing_extensions = ">=3.10"
|
typing_extensions = ">=3.10"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
ethereum = ["rlp (>=1.1.0)", "web3 (>=4.8)"]
|
ethereum = ["rlp (>=1.1.0)", "web3 (>=5)"]
|
||||||
extra = ["Pillow"]
|
extra = ["Pillow"]
|
||||||
full = ["Pillow", "PyQt5", "hidapi (>=0.7.99.post20)", "rlp (>=1.1.0)", "stellar-sdk (>=4.0.0,<6.0.0)", "web3 (>=4.8)"]
|
full = ["Pillow", "PyQt5", "hidapi (>=0.7.99.post20)", "rlp (>=1.1.0)", "stellar-sdk (>=6)", "web3 (>=5)"]
|
||||||
hidapi = ["hidapi (>=0.7.99.post20)"]
|
hidapi = ["hidapi (>=0.7.99.post20)"]
|
||||||
qt-widgets = ["PyQt5"]
|
qt-widgets = ["PyQt5"]
|
||||||
stellar = ["stellar-sdk (>=4.0.0,<6.0.0)"]
|
stellar = ["stellar-sdk (>=6)"]
|
||||||
|
|
||||||
[package.source]
|
[package.source]
|
||||||
type = "directory"
|
type = "directory"
|
||||||
url = "python"
|
url = "python"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "trezor-pylint-plugin"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = ""
|
||||||
|
optional = false
|
||||||
|
python-versions = "^3.8"
|
||||||
|
files = []
|
||||||
|
develop = true
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
astroid = "*"
|
||||||
|
pylint = "*"
|
||||||
|
|
||||||
|
[package.source]
|
||||||
|
type = "directory"
|
||||||
|
url = "tools/trezor-pylint-plugin"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typing-extensions"
|
name = "typing-extensions"
|
||||||
version = "4.0.1"
|
version = "4.0.1"
|
||||||
@ -1744,4 +1761,4 @@ testing = ["func-timeout", "jaraco.itertools", "pytest (>=6)", "pytest-black (>=
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = "^3.8"
|
python-versions = "^3.8"
|
||||||
content-hash = "b8063d1d5d0a67a71bbcba204e0e542fbab5ea2bbe7b05c41f77b8e0fa736f0e"
|
content-hash = "72019b6396c9c15ee87968b735b954908a9e9e89d0c828b1e115293a0efb9f05"
|
||||||
|
@ -74,6 +74,7 @@ vulture = "^2.6"
|
|||||||
# tools
|
# tools
|
||||||
binsize = "^0.1.3"
|
binsize = "^0.1.3"
|
||||||
toiftool = {path = "./python/tools/toiftool", develop = true, python = ">=3.8"}
|
toiftool = {path = "./python/tools/toiftool", develop = true, python = ">=3.8"}
|
||||||
|
trezor-pylint-plugin = {path = "./tools/trezor-pylint-plugin", develop = true}
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
scan-build = "*"
|
scan-build = "*"
|
||||||
|
2
tools/trezor-pylint-plugin/.gitignore
vendored
Normal file
2
tools/trezor-pylint-plugin/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
*.egg-info
|
||||||
|
/build
|
23
tools/trezor-pylint-plugin/README.md
Normal file
23
tools/trezor-pylint-plugin/README.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Custom Pylint rule checker
|
||||||
|
|
||||||
|
For now, it catches the following problem (`async-awaitable-return`):
|
||||||
|
|
||||||
|
```python
|
||||||
|
async def show_foo() -> Awaitable[None]:
|
||||||
|
return show_something("foo")
|
||||||
|
```
|
||||||
|
|
||||||
|
This is almost certainly a mistake -- the caller would need to say `await (await
|
||||||
|
show_foo())` to actually show the foo.
|
||||||
|
|
||||||
|
The function should be one of:
|
||||||
|
|
||||||
|
```python
|
||||||
|
async def show_foo() -> None:
|
||||||
|
return await show_something("foo")
|
||||||
|
|
||||||
|
# ... or ...
|
||||||
|
|
||||||
|
def show_foo() -> Awaitable[None]:
|
||||||
|
return show_something("foo")
|
||||||
|
```
|
15
tools/trezor-pylint-plugin/pyproject.toml
Normal file
15
tools/trezor-pylint-plugin/pyproject.toml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
[tool.poetry]
|
||||||
|
name = "trezor-pylint-plugin"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = ""
|
||||||
|
authors = ["matejcik <ja@matejcik.cz>"]
|
||||||
|
readme = "README.md"
|
||||||
|
|
||||||
|
[tool.poetry.dependencies]
|
||||||
|
python = "^3.8"
|
||||||
|
pylint = "*"
|
||||||
|
astroid = "*"
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["poetry-core"]
|
||||||
|
build-backend = "poetry.core.masonry.api"
|
29
tools/trezor-pylint-plugin/trezor_pylint_plugin.py
Normal file
29
tools/trezor-pylint-plugin/trezor_pylint_plugin.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
from astroid import AsyncFunctionDef
|
||||||
|
from pylint.checkers import BaseChecker
|
||||||
|
from pylint.checkers.utils import check_messages
|
||||||
|
from pylint.interfaces import IAstroidChecker
|
||||||
|
|
||||||
|
|
||||||
|
class AsyncAwaitableChecker(BaseChecker):
|
||||||
|
__implements__ = IAstroidChecker
|
||||||
|
|
||||||
|
name = "async-awaitable-checker"
|
||||||
|
priority = -1
|
||||||
|
msgs = {
|
||||||
|
"W9999": (
|
||||||
|
'Async function "%s" is likely not meant to return an Awaitable.',
|
||||||
|
"async-awaitable-return",
|
||||||
|
"Used when an async function returns an Awaitable instead of the result.",
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
@check_messages("async-awaitable-return")
|
||||||
|
def visit_asyncfunctiondef(self, node: AsyncFunctionDef):
|
||||||
|
# Check if the return type is explicitly an Awaitable
|
||||||
|
if node.returns and "Awaitable" in node.returns.as_string():
|
||||||
|
self.add_message("async-awaitable-return", node=node, args=(node.name,))
|
||||||
|
|
||||||
|
|
||||||
|
def register(linter):
|
||||||
|
"""Required method to auto register this checker."""
|
||||||
|
linter.register_checker(AsyncAwaitableChecker(linter))
|
Loading…
Reference in New Issue
Block a user