summaryrefslogtreecommitdiff
path: root/sandbox/rstdiff/studies/diff.py
diff options
context:
space:
mode:
authorsmerten <smerten@929543f6-e4f2-0310-98a6-ba3bd3dd1d04>2010-04-18 10:45:20 +0000
committersmerten <smerten@929543f6-e4f2-0310-98a6-ba3bd3dd1d04>2010-04-18 10:45:20 +0000
commit4133116de6147211270942fb2a377b45562b1f98 (patch)
tree2e3cf3e95e6edcdbbff9f4e94310cf8edaeddb48 /sandbox/rstdiff/studies/diff.py
parentd840e8e318a824ac29eece586ed527a752384603 (diff)
downloaddocutils-4133116de6147211270942fb2a377b45562b1f98.tar.gz
Continued studies.
git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk@6309 929543f6-e4f2-0310-98a6-ba3bd3dd1d04
Diffstat (limited to 'sandbox/rstdiff/studies/diff.py')
-rw-r--r--sandbox/rstdiff/studies/diff.py111
1 files changed, 46 insertions, 65 deletions
diff --git a/sandbox/rstdiff/studies/diff.py b/sandbox/rstdiff/studies/diff.py
index 8dea6c1db..4ff8a2f41 100644
--- a/sandbox/rstdiff/studies/diff.py
+++ b/sandbox/rstdiff/studies/diff.py
@@ -2,7 +2,13 @@
from difflib import SequenceMatcher
-from hashable import HashableImpl
+from hashable import HashableNodeImpl
+
+from pprint import pprint
+
+import sys
+
+__docformat__ = 'reStructuredText'
aI = ( 1, 2, 3, 5, 6, 7, )
bI = ( 2, 3, 4, 8, 6 )
@@ -23,55 +29,27 @@ class TreeNode(object):
self.tag = tag
self.children = children
-class HashableTreeNodeImpl(HashableImpl):
-
- """Consider only the root node (or include the children)."""
- # TODO Needs a push/pop methods
- rootOnly = False
+class HashableTreeNodeImpl(HashableNodeImpl):
def __init__(self):
super(self.__class__, self).__init__(TreeNode)
- def impl__hash__(self, this):
- rootHash = self.rootHash(this)
- if self.rootOnly:
- return rootHash
- else:
- return rootHash + self.childrenHash(this)
-
- def impl__eq__(self, this, other):
- if not self.rootEq(this, other):
- return False
- if self.rootOnly:
- return True
- return self.childrenEq(this, other)
-
- def rootHash(self, this):
- """Return a hash for the root only."""
- return hash(this.tag)
-
- def childrenHash(self, this):
- """Return a hash for the children only."""
- return reduce(lambda x, y: x + y,
- [ hash(child)
- for child in this.children ], 0)
-
- def rootEq(self, this, other):
- """True if the two nodes as roots are equal without considering their
- children. This should be true if one node can be replaced by
- the other and all changes can be represented without changing
- the node itself."""
- return type(this) == type(other) and this.tag == other.tag
-
- def childrenEq(self, this, other):
- """True if the children of the two nodes are equal without considering
- the root features."""
- if len(this.children) != len(other.children):
- return False
- for i in xrange(len(this.children)):
- if not (this.children[i] == other.children[i]):
- return False
- return hashableImpl
+ def rootHash(self, node):
+ return hash(node.tag)
+
+ def childHash(self, node):
+ """Return a hash for the children only. Subclasses should override
+ this."""
+ 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
# To generate a diff tree:
#
@@ -82,10 +60,10 @@ class HashableTreeNodeImpl(HashableImpl):
# * ``replace`` opcodes need to be analyzed recursively to find a
# minimal set of changes
-def resolveDeepReplace(hashableImpl, opcodes, a, b):
+def resolveDeepReplace(hashableNodeImpl, opcodes, a, b):
"""Resolves ``replace`` elements in `opcodes` pertaining to `a` and
`b`. Returns opcodes including nested elements for these cases.
- `hashableImpl` is the `HashableImpl` used to control the hashable
+ `hashableNodeImpl` is the `HashableNodeImpl` used to control the hashable
feature."""
result = [ ]
for i in xrange(len(opcodes)):
@@ -94,8 +72,7 @@ def resolveDeepReplace(hashableImpl, opcodes, a, b):
result.append(opcodes[i])
continue
try:
- savedRootOnly = hashableImpl.rootOnly
- hashableImpl.rootOnly = True
+ hashableNodeImpl.pushRootOnly(True)
sm = SequenceMatcher(None, a[aBeg:aEnd], b[bBeg:bEnd])
rootOpcodes = sm.get_opcodes()
for j in xrange(len(rootOpcodes)):
@@ -109,36 +86,37 @@ def resolveDeepReplace(hashableImpl, opcodes, a, b):
bIdx = bBeg + bSubBeg + k
result.append(('descend',
aIdx, aIdx + 1, bIdx, bIdx + 1,
- resolveRootEqual(hashableImpl,
+ resolveRootEqual(hashableNodeImpl,
a[aIdx], b[bIdx]), ))
finally:
- hashableImpl.rootOnly = savedRootOnly
+ hashableNodeImpl.popRootOnly()
return result
-def resolveRootEqual(hashableImpl, aElem, bElem):
+def resolveRootEqual(hashableNodeImpl, aElem, bElem):
"""Considers children of `aElem` and `bElem` which have equal roots.
- Returns opcodes for the children. `hashableImpl` is the
- `HashableImpl` used to control the hashable feature."""
- a = aElem.children
- b = bElem.children
+ Returns opcodes for the children. `hashableNodeImpl` is the
+ `HashableNodeImpl` used to control the hashable feature."""
+ a = hashableNodeImpl.getChildren(aElem)
+ b = hashableNodeImpl.getChildren(bElem)
try:
- savedRootOnly = hashableImpl.rootOnly
- hashableImpl.rootOnly = False
+ hashableNodeImpl.pushRootOnly(False)
sm = SequenceMatcher(None, a, b)
nestedOpcodes = sm.get_opcodes()
- return resolveDeepReplace(hashableImpl, nestedOpcodes, a, b)
+ return resolveDeepReplace(hashableNodeImpl, nestedOpcodes, a, b)
finally:
- hashableImpl.rootOnly = savedRootOnly
+ hashableNodeImpl.popRootOnly()
-hashableImpl = HashableTreeNodeImpl()
+hashableNodeImpl = HashableTreeNodeImpl()
aT = ( TreeNode('first'),
TreeNode('second', (
TreeNode('second.first'),
+ TreeNode('second.second'),
)),
TreeNode('third', (
TreeNode(2),
)),
+ TreeNode('fourth'),
)
bT = ( TreeNode('first'),
@@ -146,6 +124,7 @@ bT = ( TreeNode('first'),
TreeNode('second.first', (
TreeNode('second.first.first'),
)),
+ TreeNode('second.second1'),
TreeNode('second.second'),
)),
TreeNode('second1', (
@@ -154,12 +133,14 @@ bT = ( TreeNode('first'),
TreeNode('third', (
TreeNode(2),
)),
- TreeNode('fourth'),
+ TreeNode('fourth1'),
)
sm = SequenceMatcher(None, aT, bT)
top = sm.get_opcodes()
-print(top)
+pprint(top)
print('---')
# Use a pseudo root
-print(resolveRootEqual(hashableImpl, TreeNode(None, aT), TreeNode(None, bT)))
+pprint(resolveRootEqual(hashableNodeImpl,
+ TreeNode(None, aT), TreeNode(None, bT)),
+ sys.stdout, 2, 40, None)