Merge branch 'pyproject' into 'master'

[WIP] Add dead simple toml parsing

See merge request pycqa/flake8!440
This commit is contained in:
Adithya Balaji 2020-06-13 07:05:54 +00:00
commit aaedfc6d69
2 changed files with 74 additions and 5 deletions

View file

@ -52,6 +52,9 @@ install_requires=
python_requires = >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* 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] [options.packages.find]
where = src where = src

View file

@ -3,7 +3,7 @@ import collections
import configparser import configparser
import logging import logging
import os.path import os.path
from typing import List, Optional, Tuple from typing import List, Optional, Tuple, Any
from flake8 import utils from flake8 import utils
@ -12,6 +12,64 @@ LOG = logging.getLogger(__name__)
__all__ = ("ConfigFileFinder", "MergedConfigParser") __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: (configparser.RawConfigParser, 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: (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.
"""
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): class ConfigFileFinder(object):
"""Encapsulate the logic for finding and reading config files.""" """Encapsulate the logic for finding and reading config files."""
@ -30,7 +88,7 @@ class ConfigFileFinder(object):
:param list extra_config_files: :param list extra_config_files:
Extra configuration files specified by the user to read. Extra configuration files specified by the user to read.
:param str config_file: :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: :param bool ignore_config_files:
Determine whether to ignore configuration files or not. 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) self.user_config_file = self._user_config_file(program_name)
# List of filenames to find in the local/project directory # 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) self.local_directory = os.path.abspath(os.curdir)
@ -72,11 +132,17 @@ class ConfigFileFinder(object):
def _read_config(*files): def _read_config(*files):
# type: (*str) -> Tuple[configparser.RawConfigParser, List[str]] # type: (*str) -> Tuple[configparser.RawConfigParser, List[str]]
config = configparser.RawConfigParser() config = configparser.RawConfigParser()
found_files = [] found_files = []
LOG.debug(
"List of filenames found: %s",
files
)
for filename in files: for filename in files:
try: 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: except UnicodeDecodeError:
LOG.exception( LOG.exception(
"There was an error decoding a config file." "There was an error decoding a config file."