diff options
-rw-r--r-- | isort/settings.py | 64 | ||||
-rwxr-xr-x | setup.py | 1 | ||||
-rw-r--r-- | test_isort.py | 17 | ||||
-rw-r--r-- | tox.ini | 1 |
4 files changed, 59 insertions, 24 deletions
diff --git a/isort/settings.py b/isort/settings.py index 693c29fc..2c86842b 100644 --- a/isort/settings.py +++ b/isort/settings.py @@ -29,7 +29,9 @@ import io import os import posixpath import sys +import warnings from collections import namedtuple +from distutils.util import strtobool from .pie_slice import itemsview, lru_cache, native_str @@ -38,6 +40,11 @@ try: except ImportError: import ConfigParser as configparser +try: + import toml +except ImportError: + toml = False + MAX_CONFIG_SEARCH_DEPTH = 25 # The number of parent directories isort will look for a config file within DEFAULT_SECTIONS = ('FUTURE', 'STDLIB', 'THIRDPARTY', 'FIRSTPARTY', 'LOCALFOLDER') @@ -208,8 +215,11 @@ def _update_with_config_file(file_path, sections, computed_settings): computed_settings[access_key] = list(existing_data.union(_abspaths(cwd, _as_list(value)))) else: computed_settings[access_key] = list(existing_data.union(_as_list(value))) - elif existing_value_type == bool and value.lower().strip() == 'false': - computed_settings[access_key] = False + elif existing_value_type == bool: + # Only some configuration formats support native boolean values. + if not isinstance(value, bool): + value = bool(strtobool(value)) + computed_settings[access_key] = value elif key.startswith('known_'): computed_settings[access_key] = list(_abspaths(cwd, _as_list(value))) elif key == 'force_grid_wrap': @@ -242,26 +252,40 @@ def _get_config_data(file_path, sections): settings = {} with io.open(file_path) as config_file: - if file_path.endswith('.editorconfig'): - line = '\n' - last_position = config_file.tell() - while line: - line = config_file.readline() - if '[' in line: - config_file.seek(last_position) - break - last_position = config_file.tell() - - if sys.version_info >= (3, 2): - config = configparser.ConfigParser() - config.read_file(config_file) + if file_path.endswith('.toml'): + if toml: + config = toml.load(config_file) + for section in sections: + config_section = config + for key in section.split('.'): + config_section = config_section.get(key, {}) + settings.update(config_section) + else: + warnings.warn( + "Found %s but toml package is not installed. To configure" + "isort with %s, install with 'isort[pyproject]'." % (file_path, file_path) + ) else: - config = configparser.SafeConfigParser() - config.readfp(config_file) + if file_path.endswith('.editorconfig'): + line = '\n' + last_position = config_file.tell() + while line: + line = config_file.readline() + if '[' in line: + config_file.seek(last_position) + break + last_position = config_file.tell() + + if sys.version_info >= (3, 2): + config = configparser.ConfigParser() + config.read_file(config_file) + else: + config = configparser.SafeConfigParser() + config.readfp(config_file) - for section in sections: - if config.has_section(section): - settings.update(config.items(section)) + for section in sections: + if config.has_section(section): + settings.update(config.items(section)) return settings @@ -23,6 +23,7 @@ setup(name='isort', packages=['isort'], extras_require={ 'pipfile': ['pipreqs', 'requirementslib'], + 'pyproject': ['toml'], 'requirements': ['pip', 'pipreqs'], }, install_requires=['futures; python_version < "3.2"'], diff --git a/test_isort.py b/test_isort.py index ba124a9d..beeab2e5 100644 --- a/test_isort.py +++ b/test_isort.py @@ -31,6 +31,8 @@ import shutil import sys import tempfile +import pytest + from isort import finders from isort.isort import SortImports from isort.utils import exists_case_sensitive @@ -38,6 +40,11 @@ from isort.main import is_python_file from isort.pie_slice import PY2 from isort.settings import WrapModes +try: + import toml +except ImportError: + toml = None + SHORT_IMPORT = "from third_party import lib1, lib2, lib3, lib4" SINGLE_FROM_IMPORT = "from third_party import lib1" @@ -1822,6 +1829,7 @@ def test_sections_parsed_correct(): shutil.rmtree(tmp_conf_dir, ignore_errors=True) +@pytest.mark.skipif(toml is None, reason="Requires toml package to be installed.") def test_pyproject_conf_file(): """Ensure that modules for custom sections parsed as list from config file and isort result is correct""" tmp_conf_dir = None @@ -1834,10 +1842,11 @@ def test_pyproject_conf_file(): 'license = "MIT"\n' '[tool.isort]\n' 'lines_between_types=1\n' - 'known_common=nose\n' - 'import_heading_common=Common Library\n' - 'import_heading_stdlib=Standard Library\n' - 'sections=FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER,COMMON\n' + 'known_common="nose"\n' + 'import_heading_common="Common Library"\n' + 'import_heading_stdlib="Standard Library"\n' + 'sections="FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER,COMMON"\n' + 'include_trailing_comma = true\n' ) test_input = ( 'import os\n' @@ -10,6 +10,7 @@ deps = pytest extras = pipfile + pyproject requirements commands = py.test test_isort.py {posargs} |