summaryrefslogtreecommitdiffstats
path: root/lib2to3c/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib2to3c/__init__.py')
-rw-r--r--lib2to3c/__init__.py71
1 files changed, 71 insertions, 0 deletions
diff --git a/lib2to3c/__init__.py b/lib2to3c/__init__.py
new file mode 100644
index 0000000..8d545ae
--- /dev/null
+++ b/lib2to3c/__init__.py
@@ -0,0 +1,71 @@
+import os
+import tempfile
+from subprocess import Popen, PIPE
+
+class Fix(object):
+ def transform(self, string):
+ raise NotImplementedError
+
+class CoccinelleError(RuntimeError):
+ def __init__(self, p, args, stderr):
+ self.p = p
+ self.args = args
+ self.stderr = stderr
+
+ def __str__(self):
+ return ('Return code: %s (args: %s)\n --- start of captured stderr ---\n%s--- enf of captured stderr ---\n'
+ % (self.p.returncode, repr(self.args), self.stderr))
+
+class CocciFix(Fix):
+ def __init__(self, filename):
+ self.filename = filename
+
+ def get_script_path(self):
+ return os.path.join('lib2to3c', self.filename)
+
+ def transform(self, string):
+ # spatch seems to require the input and output to be actual files,
+ # rather than stdin/stdout.
+
+ (src_hn, src_path) = tempfile.mkstemp(suffix="-%s.in.c" % self.filename)
+ #print (src_hn, src_path)
+ (dst_hn, dst_path) = tempfile.mkstemp(suffix="-%s.out.c" % self.filename)
+ #print (dst_hn, dst_path)
+ os.write(src_hn, string)
+
+ args = ['spatch', '-sp_file', self.get_script_path(), src_path, '-o', dst_path]
+ p = Popen(args, stdout=PIPE, stderr=PIPE)
+ (stdout, stderr) = p.communicate()
+ if p.returncode != 0:
+ raise CoccinelleError(p, args, stderr)
+
+ string = open(dst_path, 'r').read()
+ os.close(src_hn)
+ os.close(dst_hn)
+
+ return string
+
+import unittest
+class NonequalStrings(Exception):
+ def __init__(self, actual_result, exp_result):
+ self.actual_result = actual_result
+ self.exp_result = exp_result
+
+ def __str__(self):
+ from difflib import unified_diff
+ result = '\n'
+ for line in unified_diff(self.exp_result.splitlines(),
+ self.actual_result.splitlines(),
+ fromfile = 'Expected result',
+ tofile = 'Actual result',
+ lineterm=''):
+ result += line + '\n'
+ return result
+
+class FixTest(unittest.TestCase):
+ '''Subclass of TestCase for verifying that a Fix is working as expected'''
+ def assertTransformsTo(self, fixer, src, exp_result):
+ actual_result = fixer.transform(src)
+ if actual_result != exp_result:
+ raise NonequalStrings(actual_result, exp_result)
+