dflook / python-minifier

Transform Python source code into its most compact representation
MIT License
558 stars 41 forks source link

Python Minifier doesn't rename variables when eval() is used. #44

Open Niikurasu opened 2 years ago

Niikurasu commented 2 years ago

When I try to shorten this code with all options enabled it only removes the spaces.

equation = input().split("=")[1]
grid = [["."]*10 for i in range(10)]
for y in range(10):
    x = int(eval(equation))
    if 0 <= x <= 9:
        grid[y][x] = "o"

print('\n'.join("".join(j for j in i) for i in grid))

Result: Reduction from 217 to 192

equation=input().split('=')[1]
grid=[['.']*10 for i in range(10)]
for y in range(10):
    x=int(eval(equation))
    if 0<=x<=9:grid[y][x]='o'
print('\n'.join((''.join((j for j in i))for i in grid)))

When the eval() is removed from the code it gets shortened properly (203 to 162)

D=range
E=input().split('=')[1]
A=[['.']*10 for A in D(10)]
for C in D(10):
    B=int()
    if 0<=B<=9:A[C][B]='o'
print('\n'.join((''.join((A for A in B))for B in A)))
Niikurasu commented 2 years ago

Didn't read the documentation. Any possibility of fixing it?

dflook commented 2 years ago

eval() executes a python expression using the local and global variables in it's current scope. We can't rename those without renaming references to them in the expression, which is not generally possible as we don't know what the expression will be.

You could technically do it if the expression was a static string, but you wouldn't need to eval it in that case.

I would try to avoid eval() as much as possible.

dflook commented 2 years ago

I've thought about this some more, and I think there are improvements that could be made.

For usage of eval() (and var(), locals(), globals(), and maybe exec()), they only need to prevent renaming in their own local and global namespace. If a local or global mapping is provided for var() or eval() (and exec()?) then they don't need to prevent renaming at all.

This wouldn't help for your short example, but I expect it would make a difference in most situations.