diff options
Diffstat (limited to 'lib2to3c/__init__.py')
-rw-r--r-- | lib2to3c/__init__.py | 71 |
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) + |