# HG changeset patch # User Pierre-Yves David # Date 1371204702 -7200 # Node ID 84c5b01ebb3eb42334213b7d895eed16c053f127 # Parent 768eb9a6a2dbc43c9750043bbc796ad6429d93e1 [connection] move hook control logic on Connection The _hook_control context manager now operate on connection. We have to keep a specific entry point in Session to ensure Connection object are properly cleaned up when using session to "manage" Connection live cycle. Related to #2503918 diff -r 768eb9a6a2db -r 84c5b01ebb3e server/session.py --- a/server/session.py Fri Jun 14 12:10:45 2013 +0200 +++ b/server/session.py Fri Jun 14 12:11:42 2013 +0200 @@ -114,14 +114,13 @@ # ... do stuff with none but 'integrity' hooks activated This is an internal api, you should rather use - :meth:`~cubicweb.server.session.Session.deny_all_hooks_but` or - :meth:`~cubicweb.server.session.Session.allow_all_hooks_but` session - methods. + :meth:`~cubicweb.server.session.Connection.deny_all_hooks_but` or + :meth:`~cubicweb.server.session.Connection.allow_all_hooks_but` + Transaction methods. """ - def __init__(self, session, mode, *categories): + def __init__(self, cnx, mode, *categories): assert mode in (HOOKS_ALLOW_ALL, HOOKS_DENY_ALL) - self.session = session - self.cnx = session._cnx + self.cnx = cnx self.mode = mode self.categories = categories self.oldmode = None @@ -138,17 +137,32 @@ def __exit__(self, exctype, exc, traceback): self.cnx.ctx_count -= 1 + try: + if self.categories: + if self.mode is HOOKS_DENY_ALL: + self.cnx.disable_hook_categories(*self.categories) + else: + self.cnx.enable_hook_categories(*self.categories) + finally: + self.cnx.hooks_mode = self.oldmode + +class _session_hooks_control(_hooks_control): + """hook control context manager for session + + Necessary To handle some unholy transaction scope logic.""" + + + def __init__(self, session, mode, *categories): + self.session = session + super_init = super(_session_hooks_control, self).__init__ + return super_init(session._cnx, mode, *categories) + + def __exit__(self, exctype, exc, traceback): + super_exit = super(_session_hooks_control, self).__exit__ + ret = super_exit(exctype, exc, traceback) if self.cnx.ctx_count == 0: self.session._clear_thread_storage(self.cnx) - else: - try: - if self.categories: - if self.mode is HOOKS_DENY_ALL: - self.cnx.disable_hook_categories(*self.categories) - else: - self.cnx.enable_hook_categories(*self.categories) - finally: - self.cnx.hooks_mode = self.oldmode + return ret @deprecated('[3.17] use .security_enabled instead') def security_enabled(obj, *args, **kwargs): @@ -553,6 +567,12 @@ # Hooks control ########################################################### + def allow_all_hooks_but(self, *categories): + return _hooks_control(self, HOOKS_ALLOW_ALL, *categories) + + def deny_all_hooks_but(self, *categories): + return _hooks_control(self, HOOKS_DENY_ALL, *categories) + def disable_hook_categories(self, *categories): """disable the given hook categories: @@ -1048,9 +1068,9 @@ # all hooks should be activated during normal execution def allow_all_hooks_but(self, *categories): - return _hooks_control(self, HOOKS_ALLOW_ALL, *categories) + return _session_hooks_control(self, HOOKS_ALLOW_ALL, *categories) def deny_all_hooks_but(self, *categories): - return _hooks_control(self, HOOKS_DENY_ALL, *categories) + return _session_hooks_control(self, HOOKS_DENY_ALL, *categories) hooks_mode = cnx_attr('hooks_mode')