From 6e055c0a1bb2fa13e4b6aaa7c9e1a66bfd92892b Mon Sep 17 00:00:00 2001 From: Adithya Balaji Date: Sat, 13 Jun 2020 02:57:06 -0400 Subject: [PATCH 1/2] Add dead simple toml parsing. --- setup.cfg | 3 ++ src/flake8/options/config.py | 76 +++++++++++++++++++++++++++++++++--- 2 files changed, 74 insertions(+), 5 deletions(-) diff --git a/setup.cfg b/setup.cfg index a78b67c..51dd10d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -52,6 +52,9 @@ install_requires= python_requires = >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* +[options.extras_require] +toml = toml >= 0.10.1, < 0.11 + [options.packages.find] where = src diff --git a/src/flake8/options/config.py b/src/flake8/options/config.py index eaa2b4e..f2b244a 100644 --- a/src/flake8/options/config.py +++ b/src/flake8/options/config.py @@ -3,7 +3,7 @@ import collections import configparser import logging import os.path -from typing import List, Optional, Tuple +from typing import List, Optional, Tuple, Any from flake8 import utils @@ -12,6 +12,64 @@ LOG = logging.getLogger(__name__) __all__ = ("ConfigFileFinder", "MergedConfigParser") +def handle_option_data(data): + # type: (Any) -> str + if isinstance(data, list): + return '\n' + '\n'.join([str(item) + ',' for item in data])[:-1] + else: + return str(data) + + +def handle_toml_data(config, section, data): + # type: (configparse.RawConfgParser, Any, Any) -> None + if isinstance(data, dict): + for option_or_section, nested_data in data.items(): + if isinstance(nested_data, dict): + new_section = ":".join([section, option_or_section]) + handle_toml_data(config, new_section, nested_data) + else: + # print(f"[{section}] {option_or_section}={nested_data}") + if not config.has_section(section): + config.add_section(section) + config.set( + section, option_or_section, handle_option_data(nested_data) + ) + else: + LOG.debug( + 'Encountered un-ini like data when parsing toml file: %s', + data + ) + + +def toml_shim(config, toml_file): + # type: (configparse.RawConfgParser, str) -> List[str] + """Reads a toml version of flake8's configuration file. + + This method only supports flake8 nested configs of max depth 2. + + """ + try: + import toml + from toml.decoder import TomlDecodeError + except ImportError: + LOG.info( + 'Found %s but could not parse since toml is not installed', + toml_file + ) + return [''] + + try: + toml_data = toml.load(toml_file) + except (ValueError, TomlDecodeError): + return [''] + + for section, data in toml_data.items(): + if isinstance(section, str): + handle_toml_data(config, section, data) + + return [toml_file] + + class ConfigFileFinder(object): """Encapsulate the logic for finding and reading config files.""" @@ -30,7 +88,7 @@ class ConfigFileFinder(object): :param list extra_config_files: Extra configuration files specified by the user to read. :param str config_file: - Configuration file override to only read configuraiton from. + Configuration file override to only read configuration from. :param bool ignore_config_files: Determine whether to ignore configuration files or not. """ @@ -50,7 +108,9 @@ class ConfigFileFinder(object): self.user_config_file = self._user_config_file(program_name) # List of filenames to find in the local/project directory - self.project_filenames = ("setup.cfg", "tox.ini", "." + program_name) + self.project_filenames = ( + "setup.cfg", "tox.ini", "pyproject.toml", "." + program_name + ) self.local_directory = os.path.abspath(os.curdir) @@ -72,11 +132,17 @@ class ConfigFileFinder(object): def _read_config(*files): # type: (*str) -> Tuple[configparser.RawConfigParser, List[str]] config = configparser.RawConfigParser() - found_files = [] + LOG.debug( + "List of filenames found: %s", + files + ) for filename in files: try: - found_files.extend(config.read(filename)) + if 'toml' in filename: + found_files.extend(toml_shim(config, filename)) + else: + found_files.extend(config.read(filename)) except UnicodeDecodeError: LOG.exception( "There was an error decoding a config file." From 8452b77c153608369487ce7bfd01e2ab42a7274e Mon Sep 17 00:00:00 2001 From: Adithya Balaji Date: Sat, 13 Jun 2020 03:05:47 -0400 Subject: [PATCH 2/2] Fix mypy issues. --- src/flake8/options/config.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/flake8/options/config.py b/src/flake8/options/config.py index f2b244a..98c56d3 100644 --- a/src/flake8/options/config.py +++ b/src/flake8/options/config.py @@ -21,7 +21,7 @@ def handle_option_data(data): def handle_toml_data(config, section, data): - # type: (configparse.RawConfgParser, Any, Any) -> None + # type: (configparser.RawConfigParser, Any, Any) -> None if isinstance(data, dict): for option_or_section, nested_data in data.items(): if isinstance(nested_data, dict): @@ -42,7 +42,7 @@ def handle_toml_data(config, section, data): def toml_shim(config, toml_file): - # type: (configparse.RawConfgParser, str) -> List[str] + # type: (configparser.RawConfigParser, str) -> List[str] """Reads a toml version of flake8's configuration file. This method only supports flake8 nested configs of max depth 2.