Issue19111
This issue tracker has been migrated to GitHub,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2013-09-28 14:52 by maubp, last changed 2022-04-11 14:57 by admin. This issue is now closed.
Files | ||||
---|---|---|---|---|
File name | Uploaded | Description | Edit | |
2to3_fix_future_builtins.patch | zvyn, 2015-06-24 05:28 | review |
Messages (7) | |||
---|---|---|---|
msg198521 - (view) | Author: Peter (maubp) | Date: 2013-09-28 14:52 | |
The 2to3 script should remove lines like this: from future_builtins import zip after running the zip fixer which respects the meaning of this command (issue 217). It does not, which results in an ImportError when trying to use the converted code under Python 3. Similarly for lines like this after running the map fixer etc: from future_builtins import map Background: Python 2.6 and 2.7 have an iterator-style zip function in future_builtins (and other things): $ python2.6 Python 2.6.8 (unknown, Sep 28 2013, 12:09:28) [GCC 4.6.3] on linux3 Type "help", "copyright", "credits" or "license" for more information. >>> import future_builtins >>> dir(future_builtins) ['__doc__', '__file__', '__name__', '__package__', 'ascii', 'filter', 'hex', 'map', 'oct', 'zip'] >>> quit() $ python2.7 Python 2.7.1 (r271:86832, Dec 26 2010, 19:03:20) [GCC 4.4.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import future_builtins >>> dir(future_builtins) ['__doc__', '__file__', '__name__', '__package__', 'ascii', 'filter', 'hex', 'map', 'oct', 'zip'] >>> quit() The future_builtins module does not exist under Python 3, in particular its zip and map functions do not exist. $ python3.3 Python 3.3.2 (default, Sep 28 2013, 12:00:20) [GCC 4.6.3] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import future_builtins Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: No module named 'future_builtins' -------------------------------------------------- Sample script using zip which works under Python 2.6 and 2.7, $ more zip_2to3_bug.py from future_builtins import zip assert next(zip("abc", [1, 2, 3])) == ("a", 1) print "Done" $ python2.6 zip_2to3_bug.py Done $ python2.7 zip_2to3_bug.py Done Now let's use the 2to3 script (in place): $ 2to3 -w zip_2to3_bug.py RefactoringTool: Skipping implicit fixer: buffer RefactoringTool: Skipping implicit fixer: idioms RefactoringTool: Skipping implicit fixer: set_literal RefactoringTool: Skipping implicit fixer: ws_comma RefactoringTool: Refactored zip_2to3_bug.py --- zip_2to3_bug.py (original) +++ zip_2to3_bug.py (refactored) @@ -1,3 +1,3 @@ from future_builtins import zip assert next(zip("abc", [1, 2, 3])) == ("a", 1) -print "Done" +print("Done") Here's the (broken) output: $ more zip_2to3_bug.py from future_builtins import zip assert next(zip("abc", [1, 2, 3])) == ("a", 1) print("Done") This breaks: $ python3.3 zip_2to3_bug.py Traceback (most recent call last): File "zip_2to3_bug.py", line 1, in <module> from future_builtins import zip ImportError: No module named 'future_builtins' Expected output should respect the fact I am using "from future_builtins import zip" therefore zip as an iterator already (this is working), and then remove the line "from future_builtins import zip": $ more zip_2to3_bug.py assert next(zip("abc", [1, 2, 3])) == ("a", 1) print("Done") -------------------------------------------------- Sample script using zip which works under Python 2.6 and 2.7, $ more map_2to3_bug.py from future_builtins import map x = [-2, -1, 0, 1, 2, 3] y = next(map(abs, x)) assert y == 2 print "Done" $ python2.6 map_2to3_bug.py Done $ python2.7 map_2to3_bug.py Done Now let's use the 2to3 script (in place): $ 2to3 -w map_2to3_bug.py RefactoringTool: Skipping implicit fixer: buffer RefactoringTool: Skipping implicit fixer: idioms RefactoringTool: Skipping implicit fixer: set_literal RefactoringTool: Skipping implicit fixer: ws_comma RefactoringTool: Refactored map_2to3_bug.py --- map_2to3_bug.py (original) +++ map_2to3_bug.py (refactored) @@ -2,4 +2,4 @@ x = [-2, -1, 0, 1, 2, 3] y = next(map(abs, x)) assert y == 2 -print "Done" +print("Done") RefactoringTool: Files that were modified: RefactoringTool: map_2to3_bug.py Here's the (broken) output: $ more map_2to3_bug.py from future_builtins import map x = [-2, -1, 0, 1, 2, 3] y = next(map(abs, x)) assert y == 2 print("Done") This breaks: $ python3.3 map_2to3_bug.py Traceback (most recent call last): File "map_2to3_bug.py", line 1, in <module> from future_builtins import map ImportError: No module named 'future_builtins' Expected output should respect the fact I am using "from future_builtins import map" and therefore treat map according (this is working), and then remove the line "from future_builtins import map": $ more zip_2to3_bug.py x = [-2, -1, 0, 1, 2, 3] y = next(map(abs, x)) assert y == 2 print("Done") |
|||
msg198598 - (view) | Author: Peter (maubp) | Date: 2013-09-29 15:27 | |
Thinking about this, perhaps the bug is that Python 3 doesn't have a future_builtins module? Consider: $ python2.6 Python 2.6.8 (unknown, Sep 28 2013, 12:09:28) [GCC 4.6.3] on linux3 Type "help", "copyright", "credits" or "license" for more information. >>> from __future__ import with_statement >>> from __future__ import print_function >>> from future_builtins import map, zip >>> quit() versus: $ python3.3 Python 3.3.2 (default, Sep 28 2013, 12:00:20) [GCC 4.6.3] on linux Type "help", "copyright", "credits" or "license" for more information. >>> from __future__ import with_statement >>> from __future__ import print_function >>> from future_builtins import map, zip Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: No module named 'future_builtins' >>> quit() The expectation from the __future__ imports is that once a feature is part of Python, the import is a harmless no-op. You could expect the same from future_builtins as well. |
|||
msg227249 - (view) | Author: Kevin Christopher Henry (marfire) | Date: 2014-09-22 03:09 | |
I'm interested in working on this, but it's not clear to me if this has been accepted as a bug. I converted a large project recently and was shocked to find that all 100+ files were broken because of the needless "from future_builtins..." line. Perversely, this most hurts those who made the most effort to make their code forward-compatible with Python 3. One complication is that you can't simply substitute a blank line, since that could produce invalid code if the import is inside a try/except block. (This doesn't affect "from __future__..." since that can only be at the start of a file.) Substituting a "pass" should work fine though. That would be a bit unsightly, but then again so is the blank line at the start of the file produced by removing "from __future__...". More important is to produce code that actually works under Python 3. Another issue is that it's possible to simply "import future_builtins" and then use, for example, "future_builtins.zip(...)". So trying to fix that usage as well would be (I assume) a lot more complicated. Personally it seems fine with me to just fix the "from __future_builtins__..." usage. |
|||
msg245719 - (view) | Author: Milan Oberkirch (zvyn) * | Date: 2015-06-24 05:28 | |
Here is a simple patch that would solve this issue. The new fixer 'future_builtins' removes `from future_builtins import foo` statements if they aren't nested in other constructs (try-except, classes, ...) and replaces them with `pass` otherwise. |
|||
msg245789 - (view) | Author: Josh Rosenberg (josh.r) * | Date: 2015-06-25 01:46 | |
Shouldn't it also disable the relevant fixers for map, filter, zip, etc. as appropriate? Otherwise a whole bunch of calls will be wrapper in list() or the like to mimic a behavior the code never had in Py2 in the first place. |
|||
msg245800 - (view) | Author: Milan Oberkirch (zvyn) * | Date: 2015-06-25 05:28 | |
The other fixers you mentioned are deactivated independently of this patch if an import from future_builtins exists. I gave it the same run_order as in the fix for __future__ imports which prevents 2to3 from deleting the calls before other fixers check for their existence. |
|||
msg245807 - (view) | Author: Josh Rosenberg (josh.r) * | Date: 2015-06-25 10:14 | |
Ah, my mistake. Apologies. |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-11 14:57:51 | admin | set | github: 63310 |
2021-10-20 22:46:00 | iritkatriel | set | status: open -> closed superseder: Close 2to3 issues and list them here resolution: wont fix stage: resolved |
2015-06-25 10:14:59 | josh.r | set | messages: + msg245807 |
2015-06-25 05:28:54 | zvyn | set | messages: + msg245800 |
2015-06-25 01:46:57 | josh.r | set | nosy:
+ josh.r messages: + msg245789 |
2015-06-24 05:28:04 | zvyn | set | files:
+ 2to3_fix_future_builtins.patch versions: + Python 2.7, Python 3.6, - Python 3.5 nosy: + zvyn messages: + msg245719 keywords: + patch |
2014-09-22 03:09:17 | marfire | set | nosy:
+ marfire messages: + msg227249 versions: + Python 3.5, - Python 3.3 |
2013-10-05 00:28:23 | terry.reedy | set | nosy:
+ benjamin.peterson |
2013-09-29 15:27:14 | maubp | set | messages: + msg198598 |
2013-09-28 14:52:33 | maubp | create |