Commits

Yuya Nishihara  committed f160742

thgrepo: fix burst of changectx wrapper class caused by double wrapping

Since hg 049d6b5a4a59, repo[changeid] accepts context object as changeid, and
returns the same object in that case. Because changectx object created by
thgrepo is already wrapped by thgchangectx, wrapping it again creates new
thgchangectx class, increasing the number of the class cache table.

Once class cache is flushed, "ctx1 == ctx2" may fail and result in random
crash, for example::

Traceback (most recent call last):
File "tortoisehg/hgqt/revdetails.py", line 341, in _onFileSelected
self.fileview.display(model.fileData(index))
File "tortoisehg/hgqt/fileview.py", line 447, in display
self._displayLoaded(fd)
File "tortoisehg/hgqt/fileview.py", line 458, in _displayLoaded
self._updateDisplay(fd)
File "tortoisehg/hgqt/fileview.py", line 471, in _updateDisplay
self._updateFileDataActions()
File "tortoisehg/hgqt/fileview.py", line 390, in _updateFileDataActions
a.setChecked(fd.baseRev() == pctx.rev())
File "tortoisehg/hgqt/filedata.py", line 118, in baseRev
return self._pctx.rev()
AttributeError: 'NoneType' object has no attribute 'rev'

  • Participants
  • Parent commits 3016f16
  • Branches stable

Comments (0)

Files changed (1)

File tortoisehg/hgqt/thgrepo.py

                     os.path.isabs(changeid) and os.path.isfile(changeid):
                 return genPatchContext(repo, changeid)
 
+            # If changeid is a basectx, repo[changeid] returns the same object.
+            # We assumes changectx is already wrapped in that case; otherwise,
+            # changectx would be double wrapped by thgchangectx.
             changectx = super(thgrepository, self).__getitem__(changeid)
+            if changectx is changeid:
+                return changectx
             changectx.__class__ = _extendchangectx(changectx)
             return changectx
 
     except KeyError:
         pass
 
+    assert parentcls not in _changectxclscache.values(), 'double thgchangectx'
+
     # in case each changectx instance is wrapped by some extension, there's
     # limit on cache size. it may be possible to use weakref.WeakKeyDictionary
     # on Python 2.5 or later.