Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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)
----------------
Expand Down
11 changes: 11 additions & 0 deletions src/AccessControl/ZopeGuards.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -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)
Expand All @@ -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)


Expand Down
Loading