mirror of
https://github.com/facebook/sapling.git
synced 2024-10-07 07:17:55 +03:00
lazymanifest: make __iter__ generate filenames, not 3-tuples
The _lazymanifest type(s) behave very much like a sorted dict with filenames as keys and (nodeid, flags) as values. It therefore seems surprising that its __iter__ generates 3-tuples of (path, nodeid, flags). Let's make it match dict's behavior of generating the keys instead, and add a new iterentries method for the 3-tuples. With this change, the "x" in "if x in lm" and "for x in lm" now have the same type (a filename string).
This commit is contained in:
parent
e77f997074
commit
ce0723ee16
@ -234,7 +234,7 @@ static line *lmiter_nextline(lmIter *self)
|
||||
return self->m->lines + self->pos;
|
||||
}
|
||||
|
||||
static PyObject *lmiter_iternext(PyObject *o)
|
||||
static PyObject *lmiter_iterentriesnext(PyObject *o)
|
||||
{
|
||||
size_t pl;
|
||||
line *l;
|
||||
@ -261,10 +261,10 @@ static PyObject *lmiter_iternext(PyObject *o)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyTypeObject lazymanifestIterator = {
|
||||
static PyTypeObject lazymanifestEntriesIterator = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, /*ob_size */
|
||||
"parsers.lazymanifest.iterator", /*tp_name */
|
||||
"parsers.lazymanifest.entriesiterator", /*tp_name */
|
||||
sizeof(lmIter), /*tp_basicsize */
|
||||
0, /*tp_itemsize */
|
||||
lmiter_dealloc, /*tp_dealloc */
|
||||
@ -285,13 +285,13 @@ static PyTypeObject lazymanifestIterator = {
|
||||
/* tp_flags: Py_TPFLAGS_HAVE_ITER tells python to
|
||||
use tp_iter and tp_iternext fields. */
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,
|
||||
"Iterator for a lazymanifest.", /* tp_doc */
|
||||
"Iterator for 3-tuples in a lazymanifest.", /* tp_doc */
|
||||
0, /* tp_traverse */
|
||||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
PyObject_SelfIter, /* tp_iter: __iter__() method */
|
||||
lmiter_iternext, /* tp_iternext: next() method */
|
||||
lmiter_iterentriesnext, /* tp_iternext: next() method */
|
||||
};
|
||||
|
||||
static PyObject *lmiter_iterkeysnext(PyObject *o)
|
||||
@ -340,7 +340,7 @@ static PyTypeObject lazymanifestKeysIterator = {
|
||||
|
||||
static lazymanifest *lazymanifest_copy(lazymanifest *self);
|
||||
|
||||
static PyObject *lazymanifest_getiter(lazymanifest *self)
|
||||
static PyObject *lazymanifest_getentriesiter(lazymanifest *self)
|
||||
{
|
||||
lmIter *i = NULL;
|
||||
lazymanifest *t = lazymanifest_copy(self);
|
||||
@ -348,7 +348,7 @@ static PyObject *lazymanifest_getiter(lazymanifest *self)
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
i = PyObject_New(lmIter, &lazymanifestIterator);
|
||||
i = PyObject_New(lmIter, &lazymanifestEntriesIterator);
|
||||
if (i) {
|
||||
i->m = t;
|
||||
i->pos = -1;
|
||||
@ -860,6 +860,8 @@ static PyObject *lazymanifest_diff(lazymanifest *self, PyObject *args)
|
||||
static PyMethodDef lazymanifest_methods[] = {
|
||||
{"iterkeys", (PyCFunction)lazymanifest_getkeysiter, METH_NOARGS,
|
||||
"Iterate over file names in this lazymanifest."},
|
||||
{"iterentries", (PyCFunction)lazymanifest_getentriesiter, METH_NOARGS,
|
||||
"Iterate over (path, nodeid, flags) typles in this lazymanifest."},
|
||||
{"copy", (PyCFunction)lazymanifest_copy, METH_NOARGS,
|
||||
"Make a copy of this lazymanifest."},
|
||||
{"filtercopy", (PyCFunction)lazymanifest_filtercopy, METH_O,
|
||||
@ -898,7 +900,7 @@ static PyTypeObject lazymanifestType = {
|
||||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
(getiterfunc)lazymanifest_getiter, /* tp_iter */
|
||||
(getiterfunc)lazymanifest_getkeysiter, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
lazymanifest_methods, /* tp_methods */
|
||||
0, /* tp_members */
|
||||
|
@ -44,11 +44,14 @@ class _lazymanifest(dict):
|
||||
dict.__setitem__(self, k, (node, flag))
|
||||
|
||||
def __iter__(self):
|
||||
return ((f, e[0], e[1]) for f, e in sorted(self.iteritems()))
|
||||
return iter(sorted(dict.keys(self)))
|
||||
|
||||
def iterkeys(self):
|
||||
return iter(sorted(dict.keys(self)))
|
||||
|
||||
def iterentries(self):
|
||||
return ((f, e[0], e[1]) for f, e in sorted(self.iteritems()))
|
||||
|
||||
def copy(self):
|
||||
c = _lazymanifest('')
|
||||
c.update(self)
|
||||
@ -76,14 +79,14 @@ class _lazymanifest(dict):
|
||||
|
||||
def filtercopy(self, filterfn):
|
||||
c = _lazymanifest('')
|
||||
for f, n, fl in self:
|
||||
for f, n, fl in self.iterentries():
|
||||
if filterfn(f):
|
||||
c[f] = n, fl
|
||||
return c
|
||||
|
||||
def text(self):
|
||||
"""Get the full data of this manifest as a bytestring."""
|
||||
fl = sorted(self)
|
||||
fl = sorted(self.iterentries())
|
||||
|
||||
_hex = revlog.hex
|
||||
# if this is changed to support newlines in filenames,
|
||||
@ -119,7 +122,7 @@ class manifestdict(object):
|
||||
del self._lm[key]
|
||||
|
||||
def __iter__(self):
|
||||
return self._lm.iterkeys()
|
||||
return self._lm.__iter__()
|
||||
|
||||
def iterkeys(self):
|
||||
return self._lm.iterkeys()
|
||||
@ -140,8 +143,8 @@ class manifestdict(object):
|
||||
|
||||
def filesnotin(self, m2):
|
||||
'''Set of files in this manifest that are not in the other'''
|
||||
files = set(self.iterkeys())
|
||||
files.difference_update(m2.iterkeys())
|
||||
files = set(self)
|
||||
files.difference_update(m2)
|
||||
return files
|
||||
|
||||
def matches(self, match):
|
||||
@ -196,7 +199,7 @@ class manifestdict(object):
|
||||
return c
|
||||
|
||||
def iteritems(self):
|
||||
return (x[:2] for x in self._lm)
|
||||
return (x[:2] for x in self._lm.iterentries())
|
||||
|
||||
def text(self):
|
||||
return self._lm.text()
|
||||
|
@ -40,7 +40,7 @@ class testmanifest(unittest.TestCase):
|
||||
def testEmptyManifest(self):
|
||||
m = manifestmod._lazymanifest('')
|
||||
self.assertEqual(0, len(m))
|
||||
self.assertEqual([], list(m))
|
||||
self.assertEqual([], list(m.iterentries()))
|
||||
|
||||
def testManifest(self):
|
||||
m = manifestmod._lazymanifest(A_SHORT_MANIFEST)
|
||||
@ -49,7 +49,7 @@ class testmanifest(unittest.TestCase):
|
||||
('foo', binascii.unhexlify(HASH_1), ''),
|
||||
]
|
||||
self.assertEqual(len(want), len(m))
|
||||
self.assertEqual(want, list(m))
|
||||
self.assertEqual(want, list(m.iterentries()))
|
||||
self.assertEqual((binascii.unhexlify(HASH_1), ''), m['foo'])
|
||||
self.assertRaises(KeyError, lambda : m['wat'])
|
||||
self.assertEqual((binascii.unhexlify(HASH_2), 'l'),
|
||||
@ -88,7 +88,7 @@ class testmanifest(unittest.TestCase):
|
||||
self.assertEqual((h2, ''), m['beta'])
|
||||
self.assertRaises(KeyError, lambda : m['foo'])
|
||||
w = [('alpha', h1, ''), ('bar/baz/qux.py', h2, 'l'), ('beta', h2, '')]
|
||||
self.assertEqual(w, list(m))
|
||||
self.assertEqual(w, list(m.iterentries()))
|
||||
|
||||
def testSetGetNodeSuffix(self):
|
||||
clean = manifestmod._lazymanifest(A_SHORT_MANIFEST)
|
||||
@ -100,7 +100,7 @@ class testmanifest(unittest.TestCase):
|
||||
self.assertEqual(want, m['foo'])
|
||||
self.assertEqual([('bar/baz/qux.py', binascii.unhexlify(HASH_2), 'l'),
|
||||
('foo', binascii.unhexlify(HASH_1) + 'a', '')],
|
||||
list(m))
|
||||
list(m.iterentries()))
|
||||
# Sometimes it even tries a 22-byte fake hash, but we can
|
||||
# return 21 and it'll work out
|
||||
m['foo'] = want[0] + '+', f
|
||||
@ -114,7 +114,7 @@ class testmanifest(unittest.TestCase):
|
||||
self.assertEqual(want, m2['foo'])
|
||||
# suffix with iteration
|
||||
self.assertEqual([('bar/baz/qux.py', binascii.unhexlify(HASH_2), 'l'),
|
||||
('foo', want[0], '')], list(m))
|
||||
('foo', want[0], '')], list(m.iterentries()))
|
||||
# shows up in diff
|
||||
self.assertEqual({'foo': (want, (h, ''))}, m.diff(clean))
|
||||
self.assertEqual({'foo': ((h, ''), want)}, clean.diff(m))
|
||||
|
Loading…
Reference in New Issue
Block a user