From 4d9f0f70fc0d6a324189ded0202b4173454e350f Mon Sep 17 00:00:00 2001 From: linesight Date: Mon, 29 Jun 2026 08:44:56 -0700 Subject: [PATCH] Expose root_cache_path setting and set it in unit tests (fixes #685) CEF 121+ logs a warning when CefSettings.root_cache_path is unset: 'Please customize CefSettings.root_cache_path for your application. Use of the default value may lead to unintended process singleton behavior.' This appeared when running the unit tests. cefpython never exposed root_cache_path, so it could not be set (SetApplicationSettings raised 'Invalid appSettings key'). Add it: - cef_types.pxd: declare root_cache_path in the CefSettings struct. - settings.pyx: handle the root_cache_path application setting. - unittests: set root_cache_path to a fixed dir under the system temp (_common.ROOT_CACHE_PATH) in main_test and osr_test, silencing the warning during the test run. - api/ApplicationSettings.md: document the new setting. --- api/ApplicationSettings.md | 22 ++++++++++++++++++++++ src/extern/cef/cef_types.pxd | 1 + src/settings.pyx | 4 ++++ unittests/_common.py | 10 ++++++++++ unittests/main_test.py | 1 + unittests/osr_test.py | 3 ++- 6 files changed, 40 insertions(+), 1 deletion(-) diff --git a/api/ApplicationSettings.md b/api/ApplicationSettings.md index d0732776..19e2d401 100644 --- a/api/ApplicationSettings.md +++ b/api/ApplicationSettings.md @@ -32,6 +32,7 @@ Table of contents: * [product_version](#product_version) * [remote_debugging_port](#remote_debugging_port) * [resources_dir_path](#resources_dir_path) + * [root_cache_path](#root_cache_path) * [single_process](#single_process) * [string_encoding](#string_encoding) * [uncaught_exception_stack_size](#uncaught_exception_stack_size) @@ -376,6 +377,27 @@ the module directory on Windows/Linux or the app bundle Resources directory on Mac OS X. Also configurable using the --resources-dir-path switch. +### root_cache_path + +(string) +The root directory for installation-specific data and the parent directory +for profile-specific data. All `cache_path` values must have this parent +directory in common. If this value is empty and `cache_path` is non-empty +then it will default to the `cache_path` value. Any non-empty value must be +an absolute path. + +If both `root_cache_path` and `cache_path` are empty then a default +platform-specific directory will be used ("~/.config/cef_user_data" on +Linux, "~/Library/Application Support/CEF/User Data" on Mac, and +"AppData\Local\CEF\User Data" on Windows). Use of the default directory is +not recommended in production applications: recent CEF/Chromium versions use +a process singleton lock based on the `root_cache_path` value to guard +against multiple application instances writing to the same directory, and +relying on the default value may lead to unintended process singleton +behavior (CEF logs a warning in this case). You should customize +`root_cache_path` for your application. + + ### single_process (bool) diff --git a/src/extern/cef/cef_types.pxd b/src/extern/cef/cef_types.pxd index e25f601d..2d22d7c2 100644 --- a/src/extern/cef/cef_types.pxd +++ b/src/extern/cef/cef_types.pxd @@ -27,6 +27,7 @@ cdef extern from "include/internal/cef_types.h": cef_string_t browser_subprocess_path int command_line_args_disabled cef_string_t cache_path + cef_string_t root_cache_path int enable_net_security_expiration int persist_session_cookies cef_string_t user_agent diff --git a/src/settings.pyx b/src/settings.pyx index 52000945..75275f63 100644 --- a/src/settings.pyx +++ b/src/settings.pyx @@ -50,6 +50,10 @@ cdef void SetApplicationSettings( cefString = new CefString(&cefAppSettings.cache_path) PyToCefStringPointer(appSettings[key], cefString) del cefString + elif key == "root_cache_path": + cefString = new CefString(&cefAppSettings.root_cache_path) + PyToCefStringPointer(appSettings[key], cefString) + del cefString elif key == "persist_session_cookies": cefAppSettings.persist_session_cookies = int(appSettings[key]) elif key == "user_agent": diff --git a/unittests/_common.py b/unittests/_common.py index 59c1f9ec..fd06eafc 100644 --- a/unittests/_common.py +++ b/unittests/_common.py @@ -8,6 +8,7 @@ import os import platform import sys +import tempfile import time # Platforms @@ -18,6 +19,15 @@ LINUX = SYSTEM if SYSTEM == "LINUX" else False MAC = SYSTEM if SYSTEM == "MAC" else False +# Issue #685: set ApplicationSettings.root_cache_path so that CEF does not +# log a warning about using the default user-data directory which "may lead +# to unintended process singleton behavior". A fixed directory in the +# system temp folder is reused across runs (the tests run a single instance +# at a time, so there is no singleton conflict). +ROOT_CACHE_PATH = os.path.join(tempfile.gettempdir(), "cefpython_tests") +if not os.path.isdir(ROOT_CACHE_PATH): + os.makedirs(ROOT_CACHE_PATH) + # To show the window for an extended period of time increase this number. MESSAGE_LOOP_RANGE = 200 # each iteration is 0.01 sec diff --git a/unittests/main_test.py b/unittests/main_test.py index 525818f3..726f58cb 100644 --- a/unittests/main_test.py +++ b/unittests/main_test.py @@ -130,6 +130,7 @@ def test_main(self): "debug": False, "log_severity": cef.LOGSEVERITY_ERROR, "log_file": "", + "root_cache_path": ROOT_CACHE_PATH, } if not LINUX: # On Linux you get a lot of "X error received" messages diff --git a/unittests/osr_test.py b/unittests/osr_test.py index a3c20989..13546388 100644 --- a/unittests/osr_test.py +++ b/unittests/osr_test.py @@ -79,7 +79,8 @@ def test_osr(self): "debug": False, "log_severity": cef.LOGSEVERITY_ERROR, "log_file": "", - "windowless_rendering_enabled": True + "windowless_rendering_enabled": True, + "root_cache_path": ROOT_CACHE_PATH, } if not LINUX: # On Linux you get a lot of "X error received" messages