bpo-39683: 2to3 fix_exitfunc suggests duplicated import of atexit module

2to3 fix for sys.exitfunc adds multiple import when sys.exitfunc
is present multiple times.

This patch adds a check for already existing 'import atexit' and
do not add multiple imports.
This commit is contained in:
Paulo Henrique Silva 2020-02-25 00:06:48 -08:00
parent 356c878fbf
commit 1844260d01
No known key found for this signature in database
GPG Key ID: F7B1BA2C56570F83
3 changed files with 25 additions and 2 deletions

View File

@ -5,7 +5,7 @@ Convert use of sys.exitfunc to use the atexit module.
# Author: Benjamin Peterson
from lib2to3 import pytree, fixer_base
from lib2to3.fixer_util import Name, Attr, Call, Comma, Newline, syms
from lib2to3.fixer_util import Name, Attr, Call, Comma, Newline, syms, does_tree_import
class FixExitfunc(fixer_base.BaseFix):
@ -55,6 +55,10 @@ class FixExitfunc(fixer_base.BaseFix):
"import at the top of your file.")
return
# Do not add import if already present (multiple sys.atexit's)
if does_tree_import(None, "atexit", self.sys_import.parent):
return
# Now add an atexit import after the sys import.
names = self.sys_import.children[1]
if names.type == syms.dotted_as_names:
@ -63,7 +67,6 @@ class FixExitfunc(fixer_base.BaseFix):
else:
containing_stmt = self.sys_import.parent
position = containing_stmt.children.index(self.sys_import)
stmt_container = containing_stmt.parent
new_import = pytree.Node(syms.import_name,
[Name("import"), Name("atexit", " ")]
)

View File

@ -4527,6 +4527,24 @@ class Test_exitfunc(FixerTestCase):
"""
self.check(b, a)
def test_multiple(self):
b = """
import sys
if 42:
sys.exitfunc = my_atexit
else:
sys.exitfunc = my_otheratexit
"""
a = """
import sys
import atexit
if 42:
atexit.register(my_atexit)
else:
atexit.register(my_otheratexit)
"""
self.check(b, a)
def test_names_import(self):
b = """
import sys, crumbs

View File

@ -0,0 +1,2 @@
lib2to3: Fix duplicated atexit import when fixing multiple sys.exitfunc.
Patch by Paulo Henrique Silva.