diff options
author | Colin Watson <cjwatson@debian.org> | 2021-05-14 01:56:41 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2021-05-14 01:56:41 +0100 |
commit | 7db889e77fc2c51e6e2977366041bea0c8ae1eaa (patch) | |
tree | 70604c9c0fc18be0be89dbb6928a05bae7b49207 | |
parent | 5450d23ab2598e3553e9d4020b4488101c3ecc3e (diff) | |
download | zope-tal-7db889e77fc2c51e6e2977366041bea0c8ae1eaa.tar.gz |
Avoid traceback reference cycle in TALInterpreter.do_onError_tal
In Python 3, exceptions have a ``__traceback__`` attribute containing
their associated traceback. Storing an exception in a local variable of
a frame present in that traceback thus creates a reference cycle. Avoid
this by explicitly deleting the exception value when we're finished with
it.
-rw-r--r-- | CHANGES.rst | 2 | ||||
-rw-r--r-- | src/zope/tal/talinterpreter.py | 13 |
2 files changed, 10 insertions, 5 deletions
diff --git a/CHANGES.rst b/CHANGES.rst index db87896..89411df 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,7 @@ 4.5 (unreleased) ================ -- Nothing changed yet. +- Avoid traceback reference cycle in ``TALInterpreter.do_onError_tal``. 4.4 (2018-10-05) diff --git a/src/zope/tal/talinterpreter.py b/src/zope/tal/talinterpreter.py index 82154db..ce2837e 100644 --- a/src/zope/tal/talinterpreter.py +++ b/src/zope/tal/talinterpreter.py @@ -987,10 +987,15 @@ class TALInterpreter(object): # handled. except: exc = sys.exc_info()[1] - self.restoreState(state) - engine = self.engine - engine.beginScope() - error = engine.createErrorInfo(exc, self.position) + try: + self.restoreState(state) + engine = self.engine + engine.beginScope() + error = engine.createErrorInfo(exc, self.position) + finally: + # Avoid traceback reference cycle due to the __traceback__ + # attribute on Python 3. + del exc engine.setLocal('error', error) try: self.interpret(handler) |