Skip to content

Commit 7f6bae9

Browse files
hippo91PCManticore
authored andcommitted
Separate the handling of third party and first party imports
1 parent 019dd8a commit 7f6bae9

File tree

6 files changed

+45
-18
lines changed

6 files changed

+45
-18
lines changed

ChangeLog

+4
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,10 @@ What's New in Pylint 1.8?
146146
deeply nested inside loop.
147147
Close #1661
148148

149+
* Fix no ``wrong-import-order`` message emitted on ordering of first and third party
150+
libraries. With this fix, pylint distinguishes third and first party
151+
modules when checking import order.
152+
Close #1702
149153

150154
What's New in Pylint 1.7.1?
151155
=========================

doc/whatsnew/1.8.rst

+6-2
Original file line numberDiff line numberDiff line change
@@ -351,5 +351,9 @@ Other Changes
351351

352352
* The Python 3 porting checker respects disabled checkers found in the config file.
353353

354-
* Modules, classes, or methods consist of compound statements that exceed the ``docstring-min-length``
355-
are now correctly emitting `missing-docstring`
354+
* Modules, classes, or methods consist of compound statements that exceed the ``docstring-min-length``
355+
are now correctly emitting `missing-docstring`
356+
357+
* Fix no ``wrong-import-order`` message emitted on ordering of first and third party libraries.
358+
With this fix, pylint distinguishes first and third party modules when checking
359+
import order.

pylint/checkers/imports.py

+28-10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# -*- coding: utf-8 -*-
12
# Copyright (c) 2006-2015 LOGILAB S.A. (Paris, FRANCE) <[email protected]>
23
# Copyright (c) 2012-2014 Google, Inc.
34
# Copyright (c) 2014-2016 Claudiu Popa <[email protected]>
@@ -563,10 +564,14 @@ def _check_imports_order(self, _module_node):
563564
564565
Imports must follow this order: standard, 3rd party, local
565566
"""
566-
extern_imports = []
567-
local_imports = []
568567
std_imports = []
569-
extern_not_ignored = []
568+
third_party_imports = []
569+
first_party_imports = []
570+
# need of a list that holds third or first party ordered import
571+
external_imports = []
572+
local_imports = []
573+
third_party_not_ignored = []
574+
first_party_not_ignored = []
570575
local_not_ignored = []
571576
isort_obj = isort.SortImports(
572577
file_contents='', known_third_party=self.config.known_third_party,
@@ -581,29 +586,42 @@ def _check_imports_order(self, _module_node):
581586
ignore_for_import_order = not self.linter.is_message_enabled('wrong-import-order',
582587
node.fromlineno)
583588
import_category = isort_obj.place_module(package)
589+
node_and_package_import = (node, package)
584590
if import_category in ('FUTURE', 'STDLIB'):
585-
std_imports.append((node, package))
586-
wrong_import = extern_not_ignored or local_not_ignored
591+
std_imports.append(node_and_package_import)
592+
wrong_import = (third_party_not_ignored or first_party_not_ignored
593+
or local_not_ignored)
587594
if self._is_fallback_import(node, wrong_import):
588595
continue
589596
if wrong_import and not nested:
590597
self.add_message('wrong-import-order', node=node,
591598
args=('standard import "%s"' % node.as_string(),
592599
'"%s"' % wrong_import[0][0].as_string()))
593-
elif import_category in ('FIRSTPARTY', 'THIRDPARTY'):
594-
extern_imports.append((node, package))
600+
elif import_category == 'THIRDPARTY':
601+
third_party_imports.append(node_and_package_import)
602+
external_imports.append(node_and_package_import)
603+
if not nested and not ignore_for_import_order:
604+
third_party_not_ignored.append(node_and_package_import)
605+
wrong_import = first_party_not_ignored or local_not_ignored
606+
if wrong_import and not nested:
607+
self.add_message('wrong-import-order', node=node,
608+
args=('third party import "%s"' % node.as_string(),
609+
'"%s"' % wrong_import[0][0].as_string()))
610+
elif import_category == 'FIRSTPARTY':
611+
first_party_imports.append(node_and_package_import)
612+
external_imports.append(node_and_package_import)
595613
if not nested and not ignore_for_import_order:
596-
extern_not_ignored.append((node, package))
614+
first_party_not_ignored.append(node_and_package_import)
597615
wrong_import = local_not_ignored
598616
if wrong_import and not nested:
599617
self.add_message('wrong-import-order', node=node,
600-
args=('external import "%s"' % node.as_string(),
618+
args=('first party import "%s"' % node.as_string(),
601619
'"%s"' % wrong_import[0][0].as_string()))
602620
elif import_category == 'LOCALFOLDER':
603621
local_imports.append((node, package))
604622
if not nested and not ignore_for_import_order:
605623
local_not_ignored.append((node, package))
606-
return std_imports, extern_imports, local_imports
624+
return std_imports, external_imports, local_imports
607625

608626
def _get_imported_module(self, importnode, modname):
609627
try:

pylint/test/functional/wrong_import_order.py

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Checks import order rule"""
22
# pylint: disable=unused-import,relative-import,ungrouped-imports,import-error,no-name-in-module,relative-beyond-top-level
3+
from __future__ import absolute_import
34
try:
45
from six.moves import configparser
56
except ImportError:
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
wrong-import-order:11::standard import "import os.path" should be placed before "import six"
2-
wrong-import-order:13::standard import "import sys" should be placed before "import six"
3-
wrong-import-order:14::standard import "import datetime" should be placed before "import six"
4-
wrong-import-order:17::external import "import totally_missing" should be placed before "from .package import Class"
5-
wrong-import-order:19::external import "import astroid" should be placed before "from .package import Class"
1+
wrong-import-order:12::standard import "import os.path" should be placed before "import six"
2+
wrong-import-order:14::standard import "import sys" should be placed before "import six"
3+
wrong-import-order:15::standard import "import datetime" should be placed before "import six"
4+
wrong-import-order:18::first party import "import totally_missing" should be placed before "from .package import Class"
5+
wrong-import-order:20::third party import "import astroid" should be placed before "import unused_import"

pylint/test/functional/wrong_import_order2.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from sys import argv
88

99
# external imports
10-
import lxml
10+
import isort
1111

1212
from six import moves
1313

0 commit comments

Comments
 (0)