From 917049816759be44b79aa48436bb1480366a4f7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hakan=20=C3=87elik?= Date: Wed, 7 Oct 2020 22:11:53 +0300 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9E=20Fix:=20Initial=20imports=20from?= =?UTF-8?q?=20sys.modules=20#127=20(#136)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/CHANGELOG.md | 1 + tests/test_refactor.py | 12 ++++++++++++ unimport/constants.py | 17 +++++++++++++++++ unimport/scan.py | 8 +++++++- 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 3629782e..526db59a 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file. ## [Unreleased] - ././2020 +- [🐞 Fix: Initial imports from sys.modules by @hakancelik96](https://github.com/hakancelik96/unimport/pull/136) - [🐞 Fix: import and name matcher by @hakancelik96](https://github.com/hakancelik96/unimport/pull/133) - [🐞 Fix: type comment by @hakancelik96](https://github.com/hakancelik96/unimport/pull/130) - [💪 Support type variable by @hakancelik96](https://github.com/hakancelik96/unimport/pull/128) diff --git a/tests/test_refactor.py b/tests/test_refactor.py index 9f51c055..e18dcf4f 100644 --- a/tests/test_refactor.py +++ b/tests/test_refactor.py @@ -242,6 +242,18 @@ def test_get_star_imp_none(self): self.session.refactor(action), ) + def test_initial_imports(self): + from unimport.constants import INITIAL_IMPORTS + + actions = [ + (f"import {imp_name}\n{imp_name.split('.')[0]}\n") + for imp_name in INITIAL_IMPORTS + ] + self.assertListEqual( + actions, + [self.session.refactor(action) for action in actions], + ) + class TestDuplicateUnusedRefactor(RefactorTestCase): def test_full_unused(self): diff --git a/unimport/constants.py b/unimport/constants.py index f3e90230..150065a6 100644 --- a/unimport/constants.py +++ b/unimport/constants.py @@ -56,3 +56,20 @@ SUBSCRIPT_TYPE_VARIABLE.extend(["Literal", "OrderedDict"]) elif PY37_PLUS: SUBSCRIPT_TYPE_VARIABLE.append("Literal") + +INITIAL_IMPORTS = frozenset( + # https://docs.python.org/3/library/sys.html#sys.modules + # The first thing Python will do is look up the name of import in sys.modules. + # Initial modules are below. + { + "encodings.utf_8", + "encodings.aliases", + "encodings.latin_1", + "importlib._bootstrap", + "importlib.abc", + "importlib.machinery", + "importlib._bootstrap_external", + "importlib.util", + "os.path", + } +) diff --git a/unimport/scan.py b/unimport/scan.py index 5af91c70..b6cc78a2 100644 --- a/unimport/scan.py +++ b/unimport/scan.py @@ -17,7 +17,11 @@ ) from unimport import color -from unimport.constants import PY38_PLUS, SUBSCRIPT_TYPE_VARIABLE +from unimport.constants import ( + INITIAL_IMPORTS, + PY38_PLUS, + SUBSCRIPT_TYPE_VARIABLE, +) from unimport.relate import first_occurrence, get_parents, relate from unimport.statement import Import, ImportFrom, Name from unimport.utils import get_dir, get_source, is_std @@ -103,6 +107,8 @@ def visit_Import(self, node: ast.Import) -> None: return for column, alias in enumerate(node.names): name = alias.asname or alias.name + if name in INITIAL_IMPORTS: + name = name.split(".")[0] self.imports.append( Import( lineno=node.lineno,