I am making a logging decorator for functions in python:
import logging
from typing import Callable
from functools import wraps
def function_logging(fn: Callable) -> Callable:
fn_logger = logging.getLogger(fn.__module__ + '.' + fn.__name__)
@wraps(fn)
def wrapper(*args, **kwargs):
fn_logger.info("Args: {}".format(args))
fn_logger.info("Kwargs: {}".format(kwargs))
result = fn(*args, **kwargs)
fn_logger.info("Return: {}".format(result))
return result
return wrapper
PyCharm's static analysis is telling me that I cannot expect a Callable
to have the attribute __module__
. So far I haven't encountered cases where this fails. Does anyone know under what circumstances one might encounter a Callable
without the __module__
attribute?
Here's an example:
list.__add__
That's a callable with no __module__
. It's the unbound method for list concatenation.
In general, there's no requirement that callables have a __module__
. It just has to be possible to call them. There's also no requirement that callables have a __name__
, and for most callable types, it doesn't make sense to use functools.wraps
with them.
Your decorator requires an instance of the ordinary Python function type; it cannot accept arbitrary callables. If you're going to give it type hints, you should hint it with that type:
def function_logging(fn: types.FunctionType) -> types.FunctionType:
...