D1527: context: add an abstract base class for filectx
phillco (Phil Cohen)
phabricator at mercurial-scm.org
Thu Dec 7 16:22:29 EST 2017
phillco updated this revision to Diff 4175.
REPOSITORY
rHG Mercurial
CHANGES SINCE LAST UPDATE
https://phab.mercurial-scm.org/D1527?vs=3903&id=4175
REVISION DETAIL
https://phab.mercurial-scm.org/D1527
AFFECTED FILES
mercurial/context.py
mercurial/filemerge.py
CHANGE DETAILS
diff --git a/mercurial/filemerge.py b/mercurial/filemerge.py
--- a/mercurial/filemerge.py
+++ b/mercurial/filemerge.py
@@ -104,6 +104,18 @@
def isabsent(self):
return True
+ def isexec(self):
+ return False
+
+ def islink(self):
+ return False
+
+ def setflags(self, l, x):
+ raise error.ProgrammingError("absentfilectx is immutable")
+
+ def write(self, data, flags):
+ raise error.ProgrammingError("absentfilectx is immutable")
+
def _findtool(ui, tool):
if tool in internals:
return tool
diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -7,6 +7,7 @@
from __future__ import absolute_import
+import abc
import errno
import filecmp
import os
@@ -717,7 +718,36 @@
def matches(self, match):
return self.walk(match)
-class basefilectx(object):
+class abstractfilectx(object):
+ """Defines the mininum required methods for filectxs"""
+ __metaclass__ = abc.ABCMeta
+
+ @abc.abstractmethod
+ def data(self): pass
+ @abc.abstractmethod
+ def cmp(self, other): pass
+ @abc.abstractmethod
+ def changectx(self): pass
+ @abc.abstractmethod
+ def flags(self): pass
+ @abc.abstractmethod
+ def path(self): pass
+ @abc.abstractmethod
+ def size(self): pass
+ @abc.abstractmethod
+ def isbinary(self): pass
+ @abc.abstractmethod
+ def islink(self): pass
+ @abc.abstractmethod
+ def isexec(self): pass
+ @abc.abstractmethod
+ def isabsent(self): pass
+ @abc.abstractmethod
+ def write(self, data, flags): pass
+ @abc.abstractmethod
+ def setflags(self, l, x): pass
+
+class basefilectx(abstractfilectx):
"""A filecontext object represents the common logic for its children:
filectx: read-only access to a filerevision that is already present
in the repo,
@@ -1307,6 +1337,12 @@
return [filectx(self._repo, self._path, fileid=x,
filelog=self._filelog) for x in c]
+ def setflags(self, l, x):
+ raise error.ProgrammingError("filectx is immutable")
+
+ def write(self, data, flags):
+ raise error.ProgrammingError("filectx is immutable")
+
class committablectx(basectx):
"""A committablectx object provides common functionality for a context that
wants the ability to commit, e.g. workingctx or memctx."""
@@ -2387,6 +2423,9 @@
"""wraps repo.wwrite"""
self._data = data
+ def setflags(self, l, x):
+ raise NotImplementedError
+
class overlayfilectx(committablefilectx):
"""Like memfilectx but take an original filectx and optional parameters to
override parts of it. This is useful when fctx.data() is expensive (i.e.
@@ -2556,7 +2595,7 @@
return scmutil.status(modified, added, removed, [], [], [], [])
-class arbitraryfilectx(object):
+class arbitraryfilectx(abstractfilectx):
"""Allows you to use filectx-like functions on a file in an arbitrary
location on disk, possibly not in the working directory.
"""
@@ -2576,12 +2615,36 @@
return not filecmp.cmp(self.path(), self._repo.wjoin(fctx.path()))
return self.data() != fctx.data()
+ def changectx(self):
+ raise error.ProgrammingError("an arbitraryfilectx cannot have a "
+ "changectx")
+
+ def isabsent(self):
+ return False
+
+ # TODO deduplicate these from ``basefilectx``
+ def isbinary(self):
+ try:
+ return util.binary(self.data())
+ except IOError:
+ return False
+ def isexec(self):
+ return 'x' in self.flags()
+ def islink(self):
+ return 'l' in self.flags()
+
+ def size(self):
+ return os.stat(self._path).st_size
+
def path(self):
return self._path
def flags(self):
return ''
+ def setflags(self, l, x):
+ raise NotImplementedError
+
def data(self):
return util.readfile(self._path)
To: phillco, #hg-reviewers, martinvonz
Cc: mercurial-devel
More information about the Mercurial-devel
mailing list