bpo-34844: logging.Formatter enhancement - Ensure styles and fmt matches in logging.Formatter by BNMetrics · Pull Request #9703 · python/cpython (original) (raw)

if not cname:
    c = logging.Formatter
else:
    c = _resolve(cname)  # this might actually resolve to logging.Formatter

if c is logging.Formatter:
    # we know c will accept the validate parameter
    use_validate = True
    validate = config.get('validate', True)
else:
    # we don't yet know if c will accept a validate parameter.
    use_validate = False
    # Here, we could go to some trouble to determine whether there's a validate
    # or kwargs parameter, as you've done. But we have to take care:  there are
    # a number of things to consider. We currently call c with fmt, dfmt, style
    # arguments. So we expect c to be a class which inherits from
    # logging.Formatter and either doesn't redefine __init__, or does redefine
    # it. In the first case, we'd be safe to set use_validate to True, but in
    # the second, we wouldn't, because we don't know if this a Formatter
    # subclass written after 3.8 was released - when the developer of it would
    # be expected to know about the validate parameter - or whether it was a
    # class designed before 3.8, when they wouldn't be expected to know about
    # it. If it's specified in the config, then they know about it and we can
    # assume it's a post-3.8 design, so we can pass the configured value;
    # otherwise, we have as yet no idea if the redefined __init__ will accept
    # validate. We could dig into its signature to see if we could figure it
    # out, but there's no guarantee it will be *our* validate parameter - even
    # if we can figure out that it's expected to be a bool, we have no idea
    # how a True value would be interpreted. So it's safest not to pass it.

    # In the case that c is a class which doesn't even inherit from Formatter,
    # we have no idea what its __init__ does, though we do know that it has to
    # take (fmt, dfmt, style) parameters, otherwise it wouldn't work now.
    # Thus:

    if issubclass(c, logging.Formatter):
        if '__init__' not in c.__dict__:  # not redefined
            use_validate = True
        elif 'validate' in config:  # user has specified it, so OK to use
            use_validate = True
        # else:
            # if we decided to implement signature checking, we would import
            # inspect here and introspect the signature. Note that you couldn't
            # rely on a parameter literally named 'kwargs' - someone could have
            # used **kw, for example. You'd have to rely on there being a
            # specific parameter p such that p.kind == inspect._VAR_KEYWORD.

if use_validate :
    result = c(fmt, dfmt, style)
else:
    result = c(fmt, dfmt, style, validate)