Skip to content

3.12.4 breakslogging.config.DictConfig with logging.handlers.QueueHandler on read-only file systems#120868

@provinzkraut

Description

@provinzkraut

Bug report

Bug description:

When using logging.config.dictConfig to configure a logging.handlers.QueueHandler on a read only file system, it works fine in 3.12.3, but crashes in 3.12.4.

Reproducing

# bug.pyimportlogging.configlogging.config.dictConfig({"version": 1, "handlers":{"queue_listener":{"class": "logging.handlers.QueueHandler", "queue":{"()": "queue.Queue", "maxsize": -1}, }, }, } )
# DockerfileFROM python:3.12.4-slim-bookworm COPY bug.py ./ CMD ["python", "bug.py"]

Run docker run --rm --read-only -it $(docker build -q .)

Process SyncManager-1: Traceback (most recent call last): File "/usr/local/lib/python3.12/multiprocessing/process.py", line 314, in _bootstrap self.run() File "/usr/local/lib/python3.12/multiprocessing/process.py", line 108, in run self._target(*self._args, **self._kwargs) File "/usr/local/lib/python3.12/multiprocessing/managers.py", line 591, in _run_server server = cls._Server(registry, address, authkey, serializer) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/multiprocessing/managers.py", line 156, in __init__ self.listener = Listener(address=address, backlog=128) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/multiprocessing/connection.py", line 458, in __init__ address = address or arbitrary_address(family) ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/multiprocessing/connection.py", line 77, in arbitrary_address return tempfile.mktemp(prefix='listener-', dir=util.get_temp_dir()) ^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/multiprocessing/util.py", line 149, in get_temp_dir tempdir = tempfile.mkdtemp(prefix='pymp-') ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/tempfile.py", line 373, in mkdtemp prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/tempfile.py", line 126, in _sanitize_params dir = gettempdir() ^^^^^^^^^^^^ File "/usr/local/lib/python3.12/tempfile.py", line 315, in gettempdir return _os.fsdecode(_gettempdir()) ^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/tempfile.py", line 308, in _gettempdir tempdir = _get_default_tempdir() ^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/tempfile.py", line 223, in _get_default_tempdir raise FileNotFoundError(_errno.ENOENT, FileNotFoundError: [Errno 2] No usable temporary directory found in ['/tmp', '/var/tmp', '/usr/tmp', '/'] Traceback (most recent call last): File "/usr/local/lib/python3.12/logging/config.py", line 581, in configure handler = self.configure_handler(handlers[name]) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/logging/config.py", line 792, in configure_handler proxy_queue = MM().Queue() ^^^^ File "/usr/local/lib/python3.12/multiprocessing/context.py", line 57, in Manager m.start() File "/usr/local/lib/python3.12/multiprocessing/managers.py", line 566, in start self._address = reader.recv() ^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/multiprocessing/connection.py", line 250, in recv buf = self._recv_bytes() ^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/multiprocessing/connection.py", line 430, in _recv_bytes buf = self._recv(4) ^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/multiprocessing/connection.py", line 399, in _recv raise EOFError EOFError The above exception was the direct cause of the following exception: Traceback (most recent call last): File "//bug.py", line 3, in <module> logging.config.dictConfig( File "/usr/local/lib/python3.12/logging/config.py", line 920, in dictConfig dictConfigClass(config).configure() File "/usr/local/lib/python3.12/logging/config.py", line 588, in configure raise ValueError('Unable to configure handler ' ValueError: Unable to configure handler 'queue_listener' 

From my understanding, this is related to #119819 et al. and the change that caused this was introduced in #120030: It introduces creating ephemeral instances of multiprocessing.Manager which, on init, tries to acquire a temporary directory.

proxy_queue=MM().Queue()

CPython versions tested on:

3.12

Operating systems tested on:

Linux

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-bugAn unexpected behavior, bug, or error

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions