Skip to content

python 3.12->3.13's logging.Handler requres .createLock() et.al., and possibly .lock #125606

@cagney

Description

@cagney

Bug report

Bug description:

This code block was working in 3.12 but barfs in 3.13

class DebugHandler(logging.Handler):

    def __init__(self):
        logging.Handler.__init__(self)
        self.stream_handlers = list()
        self.setLevel(NONE)
        self.setFormatter(_DEBUG_FORMATTER)

    def emit(self, record):
        for stream_handler in self.stream_handlers:
            stream_handler.emit(record)
        if _DEBUG_STREAM:
            _DEBUG_STREAM.emit(record)

    def push(self, stream):
        stream_handler = logging.StreamHandler(stream)
        stream_handler.setFormatter(_DEBUG_FORMATTER)
        self.stream_handlers.append(stream_handler)
        self.setLevel(DEBUG)

    def pop(self):
        stream_handler = self.stream_handlers.pop()
        stream_handler.flush()
        # This doesn't close the file; and probably does nothing.
        stream_handler.close()
        if not self.stream_handlers:
            self.setLevel(NONE)

    def flush(self):
        for stream_handler in self.stream_handlers:
            stream_handler.flush()

because my class doesn't provide:

    def createLock(self):
        pass
    def acquire(self):
        pass
    def release(self):
        pass

is needing to add these function's considered a regression?

This leads to my second problem, I'm not clear on how these should be implemented. With the above code I get:

File "/usr/lib64/python3.13/logging/init.py", line 1664, in _log
self.handle(record)
~~~~~~~~~~~^^^^^^^^
File "/usr/lib64/python3.13/logging/init.py", line 1680, in handle
self.callHandlers(record)
~~~~~~~~~~~~~~~~~^^^^^^^^
File "/usr/lib64/python3.13/logging/init.py", line 1736, in callHandlers
hdlr.handle(record)
~~~~~~~~~~~^^^^^^^^
File "/usr/lib64/python3.13/logging/init.py", line 1025, in handle
with self.lock:
^^^^^^^^^
AttributeError: 'DebugHandler' object has no attribute 'lock'

According to the docs, NullHandler has https://docs.python.org/3/library/logging.handlers.html#nullhandler

createLock()
    This method returns None for the lock, since there is no underlying I/O to which access needs to be serialized.

but when I look at the code I find:

    def createLock(self):
        self.lock = None

I guess I try extending NullHandler()

CPython versions tested on:

3.13

Operating systems tested on:

Linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions