/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/bzr/inventory.py

  • Committer: Breezy landing bot
  • Author(s): Jelmer Vernooij
  • Date: 2020-02-14 03:16:54 UTC
  • mfrom: (7479.2.3 no-more-python2)
  • Revision ID: breezy.the.bot@gmail.com-20200214031654-bp1xtv2jr9nmhto3
Drop python2 support.

Merged from https://code.launchpad.net/~jelmer/brz/no-more-python2/+merge/378694

Show diffs side-by-side

added added

removed removed

Lines of Context:
50
50
    osutils,
51
51
    trace,
52
52
    )
53
 
from ..sixish import (
54
 
    bytesintern,
55
 
    text_type,
56
 
    viewitems,
57
 
    viewvalues,
58
 
    )
59
53
from ..static_tuple import StaticTuple
60
54
 
61
55
 
 
56
class InvalidEntryName(errors.InternalBzrError):
 
57
 
 
58
    _fmt = "Invalid entry name: %(name)s"
 
59
 
 
60
    def __init__(self, name):
 
61
        errors.BzrError.__init__(self)
 
62
        self.name = name
 
63
 
 
64
 
62
65
class InventoryEntry(object):
63
66
    """Description of a versioned file.
64
67
 
91
94
 
92
95
    >>> i = Inventory()
93
96
    >>> i.path2id('')
94
 
    'TREE_ROOT'
 
97
    b'TREE_ROOT'
95
98
    >>> i.add(InventoryDirectory(b'123', 'src', ROOT_ID))
96
 
    InventoryDirectory('123', 'src', parent_id='TREE_ROOT', revision=None)
97
 
    >>> i.add(InventoryFile(b'2323', 'hello.c', parent_id='123'))
98
 
    InventoryFile('2323', 'hello.c', parent_id='123', sha1=None, len=None, revision=None)
 
99
    InventoryDirectory(b'123', 'src', parent_id=b'TREE_ROOT', revision=None)
 
100
    >>> i.add(InventoryFile(b'2323', 'hello.c', parent_id=b'123'))
 
101
    InventoryFile(b'2323', 'hello.c', parent_id=b'123', sha1=None, len=None, revision=None)
99
102
    >>> shouldbe = {0: '', 1: 'src', 2: 'src/hello.c'}
100
103
    >>> for ix, j in enumerate(i.iter_entries()):
101
 
    ...   print (j[0] == shouldbe[ix], j[1])
 
104
    ...   print(j[0] == shouldbe[ix], j[1])
102
105
    ...
103
 
    (True, InventoryDirectory('TREE_ROOT', u'', parent_id=None, revision=None))
104
 
    (True, InventoryDirectory('123', 'src', parent_id='TREE_ROOT', revision=None))
105
 
    (True, InventoryFile('2323', 'hello.c', parent_id='123', sha1=None, len=None, revision=None))
106
 
    >>> i.add(InventoryFile('2324', 'bye.c', '123'))
107
 
    InventoryFile('2324', 'bye.c', parent_id='123', sha1=None, len=None, revision=None)
108
 
    >>> i.add(InventoryDirectory('2325', 'wibble', '123'))
109
 
    InventoryDirectory('2325', 'wibble', parent_id='123', revision=None)
 
106
    True InventoryDirectory(b'TREE_ROOT', '', parent_id=None, revision=None)
 
107
    True InventoryDirectory(b'123', 'src', parent_id=b'TREE_ROOT', revision=None)
 
108
    True InventoryFile(b'2323', 'hello.c', parent_id=b'123', sha1=None, len=None, revision=None)
 
109
    >>> i.add(InventoryFile(b'2324', 'bye.c', b'123'))
 
110
    InventoryFile(b'2324', 'bye.c', parent_id=b'123', sha1=None, len=None, revision=None)
 
111
    >>> i.add(InventoryDirectory(b'2325', 'wibble', b'123'))
 
112
    InventoryDirectory(b'2325', 'wibble', parent_id=b'123', revision=None)
110
113
    >>> i.path2id('src/wibble')
111
 
    '2325'
112
 
    >>> i.add(InventoryFile('2326', 'wibble.c', '2325'))
113
 
    InventoryFile('2326', 'wibble.c', parent_id='2325', sha1=None, len=None, revision=None)
114
 
    >>> i.get_entry('2326')
115
 
    InventoryFile('2326', 'wibble.c', parent_id='2325', sha1=None, len=None, revision=None)
 
114
    b'2325'
 
115
    >>> i.add(InventoryFile(b'2326', 'wibble.c', b'2325'))
 
116
    InventoryFile(b'2326', 'wibble.c', parent_id=b'2325', sha1=None, len=None, revision=None)
 
117
    >>> i.get_entry(b'2326')
 
118
    InventoryFile(b'2326', 'wibble.c', parent_id=b'2325', sha1=None, len=None, revision=None)
116
119
    >>> for path, entry in i.iter_entries():
117
 
    ...     print path
 
120
    ...     print(path)
118
121
    ...
119
122
    <BLANKLINE>
120
123
    src
218
221
        >>> e.name
219
222
        'hello.c'
220
223
        >>> e.file_id
221
 
        '123'
 
224
        b'123'
222
225
        >>> e = InventoryFile(b'123', 'src/hello.c', ROOT_ID)
223
226
        Traceback (most recent call last):
224
 
        InvalidEntryName: Invalid entry name: src/hello.c
 
227
        breezy.bzr.inventory.InvalidEntryName: Invalid entry name: src/hello.c
225
228
        """
226
229
        if u'/' in name:
227
 
            raise errors.InvalidEntryName(name=name)
 
230
            raise InvalidEntryName(name=name)
228
231
        if not isinstance(file_id, bytes):
229
232
            raise TypeError(file_id)
230
233
        self.file_id = file_id
417
420
        self.children = {}
418
421
 
419
422
    def sorted_children(self):
420
 
        return sorted(viewitems(self.children))
 
423
        return sorted(self.children.items())
421
424
 
422
425
    def kind_character(self):
423
426
        """See InventoryEntry.kind_character."""
666
669
 
667
670
        >>> i = Inventory()
668
671
        >>> e = i.add(InventoryDirectory(b'src-id', 'src', ROOT_ID))
669
 
        >>> e = i.add(InventoryFile(b'foo-id', 'foo.c', parent_id='src-id'))
670
 
        >>> print i.id2path(b'foo-id')
 
672
        >>> e = i.add(InventoryFile(b'foo-id', 'foo.c', parent_id=b'src-id'))
 
673
        >>> print(i.id2path(b'foo-id'))
671
674
        src/foo.c
672
675
 
673
676
        :raises NoSuchId: If file_id is not present in the inventory.
694
697
 
695
698
        # unrolling the recursive called changed the time from
696
699
        # 440ms/663ms (inline/total) to 116ms/116ms
697
 
        children = sorted(viewitems(from_dir.children))
 
700
        children = sorted(from_dir.children.items())
698
701
        if not recursive:
699
 
            for name, ie in children:
700
 
                yield name, ie
 
702
            yield from children
701
703
            return
702
704
        children = deque(children)
703
705
        stack = [(u'', children)]
719
721
                    continue
720
722
 
721
723
                # But do this child first
722
 
                new_children = sorted(viewitems(ie.children))
 
724
                new_children = sorted(ie.children.items())
723
725
                new_children = deque(new_children)
724
726
                stack.append((path, new_children))
725
727
                # Break out of inner loop, so that we start outer loop with child
804
806
            cur_relpath, cur_dir = stack.pop()
805
807
 
806
808
            child_dirs = []
807
 
            for child_name, child_ie in sorted(viewitems(cur_dir.children)):
 
809
            for child_name, child_ie in sorted(cur_dir.children.items()):
808
810
 
809
811
                child_relpath = cur_relpath + child_name
810
812
 
848
850
        accum = []
849
851
 
850
852
        def descend(dir_ie, dir_path):
851
 
            kids = sorted(viewitems(dir_ie.children))
 
853
            kids = sorted(dir_ie.children.items())
852
854
            for name, ie in kids:
853
855
                child_path = osutils.pathjoin(dir_path, name)
854
856
                accum.append((child_path, ie))
866
868
            or as list of elements.
867
869
        :return: tuple with ie, resolved elements and elements left to resolve
868
870
        """
869
 
        if isinstance(relpath, (str, text_type)):
 
871
        if isinstance(relpath, str):
870
872
            names = osutils.splitpath(relpath)
871
873
        else:
872
874
            names = relpath
903
905
 
904
906
        Returns None IFF the path is not found.
905
907
        """
906
 
        if isinstance(relpath, (str, text_type)):
 
908
        if isinstance(relpath, str):
907
909
            names = osutils.splitpath(relpath)
908
910
        else:
909
911
            names = relpath
1000
1002
 
1001
1003
    >>> inv = Inventory()
1002
1004
    >>> inv.add(InventoryFile(b'123-123', 'hello.c', ROOT_ID))
1003
 
    InventoryFile('123-123', 'hello.c', parent_id='TREE_ROOT', sha1=None, len=None, revision=None)
 
1005
    InventoryFile(b'123-123', 'hello.c', parent_id=b'TREE_ROOT', sha1=None, len=None, revision=None)
1004
1006
    >>> inv.get_entry(b'123-123').name
1005
1007
    'hello.c'
1006
1008
 
1007
1009
    Id's may be looked up from paths:
1008
1010
 
1009
1011
    >>> inv.path2id('hello.c')
1010
 
    '123-123'
 
1012
    b'123-123'
1011
1013
    >>> inv.has_id(b'123-123')
1012
1014
    True
1013
1015
 
1014
1016
    There are iterators over the contents:
1015
1017
 
1016
1018
    >>> [entry[0] for entry in inv.iter_entries()]
1017
 
    ['', u'hello.c']
 
1019
    ['', 'hello.c']
1018
1020
    """
1019
1021
 
1020
1022
    def __init__(self, root_id=ROOT_ID, revision_id=None):
1185
1187
        """
1186
1188
        if self.root is None:
1187
1189
            return ()
1188
 
        return iter(viewvalues(self._byid))
 
1190
        return self._byid.values()
1189
1191
 
1190
1192
    def __len__(self):
1191
1193
        """Returns number of entries."""
1196
1198
 
1197
1199
        >>> inv = Inventory()
1198
1200
        >>> inv.add(InventoryFile(b'123123', 'hello.c', ROOT_ID))
1199
 
        InventoryFile('123123', 'hello.c', parent_id='TREE_ROOT', sha1=None, len=None, revision=None)
 
1201
        InventoryFile(b'123123', 'hello.c', parent_id=b'TREE_ROOT', sha1=None, len=None, revision=None)
1200
1202
        >>> inv.get_entry(b'123123').name
1201
1203
        'hello.c'
1202
1204
        """
1223
1225
        self._byid[entry.file_id] = entry
1224
1226
        children = getattr(entry, 'children', {})
1225
1227
        if children is not None:
1226
 
            for child in viewvalues(children):
 
1228
            for child in children.values():
1227
1229
                self._add_child(child)
1228
1230
        return entry
1229
1231
 
1279
1281
 
1280
1282
        >>> inv = Inventory()
1281
1283
        >>> inv.add(InventoryFile(b'123', 'foo.c', ROOT_ID))
1282
 
        InventoryFile('123', 'foo.c', parent_id='TREE_ROOT', sha1=None, len=None, revision=None)
 
1284
        InventoryFile(b'123', 'foo.c', parent_id=b'TREE_ROOT', sha1=None, len=None, revision=None)
1283
1285
        >>> inv.has_id(b'123')
1284
1286
        True
1285
1287
        >>> inv.delete(b'123')
1299
1301
        >>> i1 == i2
1300
1302
        True
1301
1303
        >>> i1.add(InventoryFile(b'123', 'foo', ROOT_ID))
1302
 
        InventoryFile('123', 'foo', parent_id='TREE_ROOT', sha1=None, len=None, revision=None)
 
1304
        InventoryFile(b'123', 'foo', parent_id=b'TREE_ROOT', sha1=None, len=None, revision=None)
1303
1305
        >>> i1 == i2
1304
1306
        False
1305
1307
        >>> i2.add(InventoryFile(b'123', 'foo', ROOT_ID))
1306
 
        InventoryFile('123', 'foo', parent_id='TREE_ROOT', sha1=None, len=None, revision=None)
 
1308
        InventoryFile(b'123', 'foo', parent_id=b'TREE_ROOT', sha1=None, len=None, revision=None)
1307
1309
        >>> i1 == i2
1308
1310
        True
1309
1311
        """
1374
1376
            ie = to_find_delete.pop()
1375
1377
            to_delete.append(ie.file_id)
1376
1378
            if ie.kind == 'directory':
1377
 
                to_find_delete.extend(viewvalues(ie.children))
 
1379
                to_find_delete.extend(ie.children.values())
1378
1380
        for file_id in reversed(to_delete):
1379
1381
            ie = self.get_entry(file_id)
1380
1382
            del self._byid[file_id]
1623
1625
        # to filter out empty names because of non rich-root...
1624
1626
        sections = data.split(b'\n')
1625
1627
        kind, file_id = sections[0].split(b': ')
1626
 
        return (sections[2], bytesintern(file_id), bytesintern(sections[3]))
 
1628
        return (sections[2], file_id, sections[3])
1627
1629
 
1628
1630
    def _bytes_to_entry(self, bytes):
1629
1631
        """Deserialise a serialised entry."""
1651
1653
            result.reference_revision = sections[4]
1652
1654
        else:
1653
1655
            raise ValueError("Not a serialised entry %r" % bytes)
1654
 
        result.file_id = bytesintern(result.file_id)
1655
 
        result.revision = bytesintern(sections[3])
 
1656
        result.file_id = result.file_id
 
1657
        result.revision = sections[3]
1656
1658
        if result.parent_id == b'':
1657
1659
            result.parent_id = None
1658
1660
        self._fileid_to_entry_cache[result.file_id] = result
1796
1798
                continue
1797
1799
            # This loop could potentially be better by using the id_basename
1798
1800
            # map to just get the child file ids.
1799
 
            for child in viewvalues(entry.children):
 
1801
            for child in entry.children.values():
1800
1802
                if child.file_id not in altered:
1801
1803
                    raise errors.InconsistentDelta(self.id2path(child.file_id),
1802
1804
                                                   child.file_id, "Child not deleted or reparented when "
1808
1810
            # re-keying, but its simpler to just output that as a delete+add
1809
1811
            # to spend less time calculating the delta.
1810
1812
            delta_list = []
1811
 
            for key, (old_key, value) in viewitems(parent_id_basename_delta):
 
1813
            for key, (old_key, value) in parent_id_basename_delta.items():
1812
1814
                if value is not None:
1813
1815
                    delta_list.append((old_key, key, value))
1814
1816
                else:
1855
1857
                raise errors.BzrError('Duplicate key in inventory: %r\n%r'
1856
1858
                                      % (key, bytes))
1857
1859
            info[key] = value
1858
 
        revision_id = bytesintern(info[b'revision_id'])
1859
 
        root_id = bytesintern(info[b'root_id'])
1860
 
        search_key_name = bytesintern(info.get(b'search_key_name', b'plain'))
1861
 
        parent_id_basename_to_file_id = bytesintern(info.get(
1862
 
            b'parent_id_basename_to_file_id', None))
 
1860
        revision_id = info[b'revision_id']
 
1861
        root_id = info[b'root_id']
 
1862
        search_key_name = info.get(b'search_key_name', b'plain')
 
1863
        parent_id_basename_to_file_id = info.get(
 
1864
            b'parent_id_basename_to_file_id', None)
1863
1865
        if not parent_id_basename_to_file_id.startswith(b'sha1:'):
1864
1866
            raise ValueError('parent_id_basename_to_file_id should be a sha1'
1865
1867
                             ' key not %r' % (parent_id_basename_to_file_id,))
2174
2176
    def path2id(self, relpath):
2175
2177
        """See CommonInventory.path2id()."""
2176
2178
        # TODO: perhaps support negative hits?
2177
 
        if isinstance(relpath, (str, text_type)):
 
2179
        if isinstance(relpath, str):
2178
2180
            names = osutils.splitpath(relpath)
2179
2181
        else:
2180
2182
            names = relpath