From 4250dac79f1b4049349477d1704e70025bcf78d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1n=20Jockusch?= Date: Tue, 28 Apr 2026 13:27:26 +0200 Subject: [PATCH 1/2] Add caching to guarded_import to boost performance Using "import" in Python Scripts triggers the execution of guarded_import each time. This performs a security test and then the import itself. The import is fast because the Python interpreter caches this. The security test is costly, and always yields the same result. This patch inserts a cache to skip this test on repeated executions, speeding up the Python Scripts. --- src/AccessControl/ZopeGuards.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/AccessControl/ZopeGuards.py b/src/AccessControl/ZopeGuards.py index 380391c..afe00d2 100644 --- a/src/AccessControl/ZopeGuards.py +++ b/src/AccessControl/ZopeGuards.py @@ -416,6 +416,12 @@ def guarded_zip(*seqs): import_default_level = 0 +# Cache of (mname, fromlist) pairs whose security check has already passed. +# Module security in Zope is configured globally, so the result is the same +# for every request/user — skipping the repeated validate() calls saves +# significant CPU on instances where Scripts run many imports per request. +_guarded_import_cache = set() + def guarded_import(mname, globals=None, locals=None, fromlist=None, level=import_default_level): @@ -430,6 +436,10 @@ def guarded_import(mname, globals=None, locals=None, fromlist=None, raise Unauthorized("Using import with a level specification isn't " "supported by AccessControl: %s" % mname) + cache_key = (mname, tuple(fromlist)) + if cache_key in _guarded_import_cache: + return __import__(mname, globals, locals, fromlist) + mnameparts = mname.split('.') validate = getSecurityManager().validate module = load_module(None, None, mnameparts, validate, globals, locals) @@ -443,6 +453,7 @@ def guarded_import(mname, globals=None, locals=None, fromlist=None, if not validate(module, module, name, v): raise Unauthorized else: + _guarded_import_cache.add(cache_key) return __import__(mname, globals, locals, fromlist) From 6fb943be37b392c9aef1fe3cbba7418fbda165e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1n=20Jockusch?= Date: Tue, 28 Apr 2026 13:38:52 +0200 Subject: [PATCH 2/2] Add changelog --- CHANGES.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index a5f54b3..ba13fc9 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -7,6 +7,8 @@ For changes before version 3.0, see ``HISTORY.rst``. 7.4 (unreleased) ---------------- +- Add caching for ``guarded_import`` in Python Scripts. This can speed up the + execution of Scripts considerably if they use many ``import`` statements. 7.3 (2025-11-16) ----------------