Skip to content

Instantly share code, notes, and snippets.

@matangover
Last active March 6, 2023 20:30
Show Gist options
  • Save matangover/5e95be78f95e340aae9c4071f0d2834f to your computer and use it in GitHub Desktop.
Save matangover/5e95be78f95e340aae9c4071f0d2834f to your computer and use it in GitHub Desktop.
Custom pylint checker to verify all Python 3.5+ "async" functions are immediately awaited
"""Checker for non-awaited async function calls."""
import six
import astroid
from pylint.checkers import BaseChecker, utils
from pylint.interfaces import IAstroidChecker
def register(linter):
linter.register_checker(AsyncAwaitChecker(linter))
class AsyncAwaitChecker(BaseChecker):
"""
Checks that every async function (or method) call is awaited.
Example:
async def my_func():
await do_something()
def bad_func():
# Not awaiting the bad_func!
my_func()
The message id is `non-awaited-async`.
"""
__implements__ = IAstroidChecker
name = 'async-await-checker'
MESSAGE_ID = 'non-awaited-async'
msgs = {
'E8000': (
"async function %s() must be awaited",
MESSAGE_ID,
"async functions must be awaited",
),
}
@utils.check_messages(MESSAGE_ID)
def visit_callfunc(self, node):
"""Called for every function call in the source code."""
if not self.linter.is_message_enabled(self.MESSAGE_ID):
return
func_def = utils.safe_infer(node.func)
if isinstance(func_def, astroid.BoundMethod):
func_def = func_def._proxied
if isinstance(func_def, astroid.UnboundMethod):
func_def = func_def._proxied
if isinstance(func_def, astroid.AsyncFunctionDef):
if not isinstance(node.parent, astroid.Await):
self.add_message(self.MESSAGE_ID, args=func_def.name, node=node)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment