Патч для ловли присваивания к перзистент атрибутам
by
Anatoly Zaretsky
—
last modified
2007-10-02 01:46
Мой опыт позволяет предложить некое сомнительное приспособление для охоты на такие баги; прилагаемый файл ZODB.Connection.py.diff является патчем к lib/python/ZODB/Connection.py, с помощью которого можно отслеживать, где происходят изменения persistent-объектов. Патч основан на внесении трассировки в код регистрации объекта в менеджере транзакции при первом его измении
Size 1.6 kB - File type text/plainFile contents
--- ZODB/Connection.py 2007-01-14 17:04:10 +0300
+++ ZODB/Connection.py 2007-09-27 19:04:33 +0400
@@ -866,6 +866,20 @@
obj must be an object loaded from this Connection.
"""
assert obj._p_jar is self
+ #!!!
+ try:
+ from zope.exceptions.exceptionformatter import format_exception
+ trace = format_exception('', '', FrameToTraceback(sys._getframe(1)), with_filenames=True)[:-1]
+ trace.reverse()
+ self._log.info('transaction register %s.%s %s\n%s',
+ obj.__class__.__module__, obj.__class__.__name__,
+ oid_repr(obj._p_oid),
+ (trace[-1] + ''.join(trace[7:-1])).strip())
+ del trace
+ del format_exception
+ except:
+ self._log.warning('register: exception while trying to blame persistent assingment')
+ #!!!
if obj._p_oid is None:
# The actual complaint here is that an object without
# an oid is being registered. I can't think of any way to
@@ -1183,3 +1197,20 @@
# a copy of the index here. An alternative would be to ensure that
# all callers pass copies. As is, our callers do not make copies.
self.index = index.copy()
+
+#!!!
+class FrameToTraceback(object):
+ def __init__(self, f):
+ self.tb_frame = f
+
+ @property
+ def tb_lineno(self):
+ return self.tb_frame.f_lineno
+
+ @property
+ def tb_next(self):
+ next = self.tb_frame.f_back
+ if next is None:
+ return None
+ return FrameToTraceback(next)
+#!!!
Click here to get the file