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?
__module__
attribute are instances of builtin types. However, none of those are callable. I'm not sure if a metaclass can prevent the addition of a__module__
on a class, its instances or its methods (and even if it can I'm not sure if it's safe). I was able to find a sort of fringe case. Method descriptors for builtin types, likerange.count
(which is callable) do not have__module__
. On instances e.g.range(0).count
the__module__
isNone
, except for special methods e.g.range(0).__str__
where it does not exist. – DictaphoneCallable
that would be appropriate to exclude these fringe cases? – InclinationCallable
for that. I'm not even sure if those cases are supposed to behave like that and that's the reason for PyCharm to complain or if there's just no precise answer to the question "what things should or should not have__module__
" in general. In any case, you can always do something like(getattr(fn, '__module__', None) or '(none)')
. – Dictaphonemypy
has no problem with this. – Recessionalmypy
is generally a bit more well behaved than whatever PyCharm is using under the hood. – Inclination