Skip to content

The first attempt to hande the format property during logging.Formatter initilization removes the . dictionary from the config #110875

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
he-dev opened this issue Oct 14, 2023 · 0 comments
Assignees
Labels
stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@he-dev
Copy link

he-dev commented Oct 14, 2023

Bug report

Bug description:

When the library tries to initialize a formatter and comes across the old format property, it falls back to an error handler, but before it does that, it pops the . dicationary from the config making it impossible to process it later during the second call to self.configure_custom(config)

https://github.com/python/cpython/blob/main/Lib/logging/config.py#L480

This is whrere configure_custom calls props = config.pop('.', None), but it does that before result = c(**kwargs) which throws an exception when it finds the format property.

    def configure_custom(self, config):
        """Configure an object with a user-supplied factory."""
        c = config.pop('()')
        if not callable(c):
            c = self.resolve(c)
        props = config.pop('.', None) # <-- '.' gets removed on first try and is gone on the second attempt
        # Check for valid identifiers
        kwargs = {k: config[k] for k in config if valid_ident(k)}
        result = c(**kwargs) # <-- throws an error when `format` property is used
        # props = config.pop('.', None) # <-- this is where it probably needs to get called so that '.' remains in 'config'
        if props:
            for name, value in props.items():
                setattr(result, name, value)
        return result

Then then initialization continues here inside the except that calls configure_custom for the second time, but this time without the . in the config so it's skipped.

https://github.com/python/cpython/blob/main/Lib/logging/config.py#L670

    def configure_formatter(self, config):
        """Configure a formatter from a dictionary."""
        if '()' in config:
            factory = config['()'] # for use in exception handler
            try:
                result = self.configure_custom(config)
            except TypeError as te:
                if "'format'" not in str(te):
                    raise
                #Name of parameter changed from fmt to format.
                #Retry with old name.
                #This is so that code can be used with older Python versions
                #(e.g. by Django)
                config['fmt'] = config.pop('format')
                config['()'] = factory
                result = self.configure_custom(config)

I guess the function configure_custom should call props = config.pop('.', None) after result = c(**kwargs) so that the . remains in the config for the second call in case an exception is thrown during the first try.

Example

This config won't initialize the custom_property of MyFormatter:

            "custom_formatter": {
                "()": MyFormatter,
                "style": "{",
                "datefmt": "%Y-%m-%d %H:%M:%S",
                "format": "<custom-format>", # <-- when removed or changed to `fmt` then the '.' works
                ".": {
                    "custom_property": "value"
                }
            }

The formatter is implemented like this:

class MyFormatter(logging.Formatter):
    custom_property: str = "."

    def format(self, record: logging.LogRecord) -> str:
        # ...
        return super().format(record)

CPython versions tested on:

3.10

Operating systems tested on:

Windows

Linked PRs

@he-dev he-dev added the type-bug An unexpected behavior, bug, or error label Oct 14, 2023
@he-dev he-dev changed the title Handling format property during formatter initilization removes . from config on the first attempt The first attempt to hande the format property during logging.Formatter initilization removes the . dictionary from the config Oct 14, 2023
@AlexWaygood AlexWaygood added the stdlib Python modules in the Lib dir label Oct 15, 2023
vsajip added a commit to vsajip/cpython that referenced this issue Oct 16, 2023
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Nov 9, 2023
…tion c… (pythonGH-110943)

(cherry picked from commit a5f29c9)

Co-authored-by: Vinay Sajip <[email protected]>
vsajip added a commit to vsajip/cpython that referenced this issue Nov 9, 2023
vsajip added a commit to vsajip/cpython that referenced this issue Nov 9, 2023
…nfiguration c… (pythonGH-110943).

(cherry picked from commit a5f29c9)

Co-authored-by: Vinay Sajip <[email protected]>
vsajip added a commit that referenced this issue Nov 9, 2023
vsajip added a commit that referenced this issue Nov 9, 2023
@vsajip vsajip closed this as completed Nov 9, 2023
aisk pushed a commit to aisk/cpython that referenced this issue Feb 11, 2024
Glyphack pushed a commit to Glyphack/cpython that referenced this issue Sep 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
Projects
Development

No branches or pull requests

3 participants