Issue 36122: Second run of 2to3 continues to modify output (original) (raw)
I did this on Windows 10:
P:>python --version Python 3.7.2
P:>echo print 1, 2 > Test.py
P:>python Test.py File "Test.py", line 1 print 1, 2 ^ SyntaxError: Missing parentheses in call to 'print'. Did you mean print(1, 2)?
P:>2to3 -w Test.py RefactoringTool: Skipping optional fixer: buffer RefactoringTool: Skipping optional fixer: idioms RefactoringTool: Skipping optional fixer: set_literal RefactoringTool: Skipping optional fixer: ws_comma RefactoringTool: Refactored Test.py --- Test.py (original) +++ Test.py (refactored) @@ -1 +1 @@ -print 1, 2 +print(1, 2) RefactoringTool: Files that were modified: RefactoringTool: Test.py
P:>python Test.py 1 2
P:>2to3 -w Test.py RefactoringTool: Skipping optional fixer: buffer RefactoringTool: Skipping optional fixer: idioms RefactoringTool: Skipping optional fixer: set_literal RefactoringTool: Skipping optional fixer: ws_comma RefactoringTool: Refactored Test.py --- Test.py (original) +++ Test.py (refactored) @@ -1 +1 @@ -print(1, 2) +print((1, 2)) RefactoringTool: Files that were modified: RefactoringTool: Test.py
P:>python Test.py (1, 2)
Note how "print 1, 2" first becomes "print(1, 2)" (expected), then becomes "print((1, 2))" in the following run. This changes the output of Test.py
Because what's being printed is a tuple, I think it's not exactly the same as , because in fact this is the correct behavior for 2to3, note that in Python 2:
Python 2.7.15 (default, Jul 21 2018, 11:13:03)
print 1, 2 1 2 print(1, 2) (1, 2)
And in Python 3:
Python 3.7.2 (default, Feb 9 2019, 13🔞43)
print(1, 2) 1 2 print((1, 2)) (1, 2)
I think this bug report is based on an understandable misunderstanding of what 2to3 does - 2to3 is not intended to be idempotent or to generate code the works for both Python 2 and Python 3, it's intended to translate Python 2 code into Python 3, so passing it something that is already Python 3 code you are not guaranteed to get a meaningful output from it.
In this case, it first translates print 1, 2
(Python 2) into print(1, 2)
(Python 3), then when you run it a second time, it translates print(1, 2)
(Python 2) into print((1, 2))
(Python 3) - in both cases it's doing the right thing.
@bers I hope that this has helped to clarify the situation. Thank you for taking the time to report this.