From dceaae23490a5cb2c305246305e6b3a51c29d3a5 Mon Sep 17 00:00:00 2001 From: Marius Gedminas Date: Wed, 8 Jan 2014 16:01:15 +0200 Subject: Allow public access to CheckerPublic.__module__ Story time: when you pickle an object (call it obj) with a custom __reduce__ method that returns a string, the pickle module assumes this is a global and wants to know which module it came from. It obviously tries obj.__module__ first, but if that raises AttributeError, it has this insane fallback loop where it iterates over sys.modules.items() and for each module (excepting only __main__) checks if getattr(module, obj.__name__, None) is obj. Before my change if you tried >>> from zope.security.checker import CheckerPublic >>> CheckerPublic.__module__ you'd get ForbiddenAttribute: ('__module__', Global(CheckerPublic,zope.security.checker)) Until now it was just a silly inefficiency. But then six 1.5.0 was released with an interesting change: https://bitbucket.org/gutworth/six/commits/fc2decf405ea6bcd3226bb1b77069d2a2279e0b7 Now six puts these six.MovedModule() wrappers into sys.modules. When you try to access their attributes, the wrappers try to import random modules, including those that may not exist in your Python (_winreg on Linux? _tkinter also is often split off into a separate OS package). Boom: running zope.security's tests now fails in random ways: https://bitbucket.org/gutworth/six/issue/54/dependency-on-optional-tkinter-gdbm So let's make sure pickle doesn't need to iterate through sys.modules.items() and avoid the issue, m'kay? --- src/zope/security/checker.py | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/zope/security/checker.py b/src/zope/security/checker.py index 8f3cfb4..e3b914d 100644 --- a/src/zope/security/checker.py +++ b/src/zope/security/checker.py @@ -304,6 +304,7 @@ CP_HACK_XXX = CheckerPublic d={} CheckerPublic = Proxy(CheckerPublic, Checker(d)) # XXX uses CheckerPy d['__reduce__'] = CheckerPublic +d['__module__'] = CheckerPublic del d # TODO: It's a bit scary above that we can pickle a proxy if access is -- cgit v1.2.1