Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

comparing Python code for equivalence

Tags:

python

Is there a reliable, automatic way (such as a command-line utility) to check if two Python files are equivalent modulo whitespace, semicolons, backslash continuations, comments, etc.? In other words, that they are identical to the interpreter?

For example, this:

import sys
sys.stdout.write('foo\n')
sys.stdout.write('bar\n')

should be considered equivalent to this:

import   sys
sys.stdout.\
    write('foo\n'); sys.stdout.\
    write(

    'bar\n') # This is an unnecessary comment
like image 827
Jian Avatar asked Nov 07 '12 21:11

Jian


People also ask

How do you compare equals in Python?

Python comparison operators can be used to compare strings in Python. These operators are: equal to ( == ), not equal to ( != ), greater than ( > ), less than ( < ), less than or equal to ( <= ), and greater than or equal to ( >= ).

Can you compare strings with == in Python?

Using the == (equal to) operator for comparing two strings If you simply require comparing the values of two variables then you may use the '==' operator. If strings are same, it evaluates as True, otherwise False.

Is == A comparison operator in Python?

Python has six comparison operators: less than ( < ), less than or equal to ( <= ), greater than ( > ), greater than or equal to ( >= ), equal to ( == ), and not equal to ( != ).

What is the difference between == and === in Python?

In Python and many other programming languages, a single equal mark is used to assign a value to a variable, whereas two consecutive equal marks is used to check whether 2 expressions give the same value .


3 Answers

Use the ast module.

Example (for Python 2):

import ast

x = r'''import sys
sys.stdout.write('foo\n')
sys.stdout.write('bar\n')'''

y = r'''import   sys
sys.stdout.\
    write('foo\n'); sys.stdout.\
    write(

    'bar\n') # This is an unnecessary comment'''

xd = ast.dump(ast.parse(x))
yd = ast.dump(ast.parse(y))
print xd == yd

You can of course read in the source code from actual files instead of string literals.

Edit:

So that the comments make sense, I'd like to note that I originally proposed using the built-in compile() function. However, @Jian found a simple case that it didn't handle well. Perhaps it could be adapted, as suggested by @DSM, but then the solution becomes a little less tidy. Maybe not unreasonably so, but if the ast parse-and-dump works as well or better, it's the more straightforward way.

like image 60
John Y Avatar answered Oct 07 '22 05:10

John Y


Use python's parser:

In [1]: import parser

In [2]: with open('file1.py', 'r') as f1:
    st1 = parser.suite(f1.read())

In [3]: with open('file2.py', 'r') as f2:
    st2 = parser.suite(f2.read())

In [4]: st1.compile() == st2.compile()
Out[4]: True
like image 38
Andy Hayden Avatar answered Oct 07 '22 06:10

Andy Hayden


Python includes its own parser. Apply it to both files, then check that the result is structurally equivalent.

like image 26
Marcin Avatar answered Oct 07 '22 05:10

Marcin