Leitouran
Leitouran

Reputation: 588

Overriding parent methods Programmatically

I need to use a company logger library that requires a Message object as an argument instead of a plain string like vanilla python logging library (the rest works exactly like vanilla logging).

To avoid having to migrate each log individually across all the applications I maintain, I am trying to extend this custom logger class to accept either a Message or a plain string. I was able to do this by overriding explicitly each log level method

from companylogging.logger import CompanyLogger, Message

class CustomLogger(CompanyLogger):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, *kwargs)

    def debug(self, message):

        if isinstance(message, Message):
            super().debug(message)
        else:
            super().debug(Message(message))


    ...

    def critical(self, message):

        if isinstance(message, Message):
            super().critical(message)
        else:
            super().critical(Message(message))    

I would like to do this programmatically for each level, with levels being a list of strings depicting how the logging methods in the parent class are named:

from companylogging.logger import CompanyLogger, Message

class CustomLogger(CompanyLogger):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, *kwargs)

        for level in levels:
            setattr(self, level, self.override_loglevels(level))


    def override_loglevels(self, level):

        def log(message):
            logger = getattr(CompanyLogger, level)
            if isinstance(message, Message):
                logger(message)
            else :
                logger(Message(message))

        return log

This approach didn't work. When used, an error occurs saying I am not providing the message argument:

TypeError: debug() missing 1 required positional argument: 'msg'

But I am passing it...

logger.debug(f"test message")
logger.debug(Message(f"test message"))

Any ideas of what I'm doing wrong? Or maybe an alternative approach to achieve this "programmatic method override"?

Upvotes: 0

Views: 44

Answers (1)

Leitouran
Leitouran

Reputation: 588

Since I'm overriding a method, I needed to pass self as well when overriding

def override_loglevels(self, level):

    def log(message):
        logger = getattr(SantanderLogger, level)
        if isinstance(message, Message):
            logger(self, message)
        else :
            logger(self, Message(message))

Upvotes: 1

Related Questions