summaryrefslogtreecommitdiff
path: root/sandbox/rstdiff/studies/diff.py
blob: 7f35aae65cc840f7beb3cf9fe782271fa382d909 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# Studies for using difflib on structures

from difflib import SequenceMatcher

from pprint import pprint

import sys

from treediff import TreeMatcher, HashableNodeImpl

__docformat__ = 'reStructuredText'

aI = ( 1, 2, 3, 5, 6, 7, )
bI = ( 2, 3, 4, 8, 6 )

sm = SequenceMatcher(None, aI, bI)

# print(sm.find_longest_match(0, len(aI), 0, len(bI)))
# print(sm.get_matching_blocks())
# print(list(sm.get_grouped_opcodes(0))) # Useful for context diffs
# print(sm.get_opcodes()) # The way to go

class TreeNode(object):
    """An example tree node to play with."""

    tag = None
    children = ( )

    def __init__(self, tag, children=( )):
        self.tag = tag
        self.children = children

class HashableTreeNodeImpl(HashableNodeImpl):
    """A `HashableNodeImpl` for `TreeNode`."""

    def __init__(self):
        super(self.__class__, self).__init__(TreeNode)

    def rootHash(self, node):
        return hash(node.tag)

    def childHash(self, node):
        return hash(node)

    def rootEq(self, node, other):
        return type(node) == type(other) and node.tag == other.tag

    def childEq(self, node, other):
        return node == other

    def getChildren(self, node):
        return node.children

hashableNodeImpl = HashableTreeNodeImpl()

aT = ( TreeNode('first'),
       TreeNode('second', (
            TreeNode('second.first'),
            TreeNode('second.second'),
            )),
       TreeNode('third', (
            TreeNode(2),
            )),
       TreeNode('fourth'),
       )

bT = ( TreeNode('first'),
       TreeNode('second', (
            TreeNode('second.first', (
                    TreeNode('second.first.first'),
                    )),
            TreeNode('second.second1'),
            TreeNode('second.second'),
            )),
       TreeNode('second1', (
            TreeNode(2),
            )),
       TreeNode('third', (
            TreeNode(2),
            )),
       TreeNode('fourth1'),
       )

sm = SequenceMatcher(None, aT, bT)
top = sm.get_opcodes()
pprint(top)
print('---')

# Use a pseudo root with different root nodes.
pprint(TreeMatcher(hashableNodeImpl,
                   TreeNode('a', aT), TreeNode('b', bT)).get_opcodes(),
       sys.stdout, 2, 40, None)

# Use a pseudo root with equal root nodes.
pprint(TreeMatcher(hashableNodeImpl,
                   TreeNode(None, aT), TreeNode(None, bT)).get_opcodes(),
       sys.stdout, 2, 40, None)

# To generate a diff tree:
#
# * ``equal`` opcodes need a copy
#
# * ``insert`` and ``delete`` opcodes must be processed as such
#
# * ``replace`` opcodes need to be analyzed recursively to find a
#   minimal set of changes