summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Stapleton Cordasco <graffatcolmingov@gmail.com>2021-10-10 19:21:35 -0500
committerGitHub <noreply@github.com>2021-10-10 19:21:35 -0500
commit283f0c81241673221d9628beb11e2d7356826f00 (patch)
tree14c10b9f867c0f955a2722bee6e24b71690ae27d
parent0b1c790443a9777c5d945f963e22571698fadf8c (diff)
parent807904aebc20814ac595b0004ab526fffb5ef681 (diff)
downloadflake8-283f0c81241673221d9628beb11e2d7356826f00.tar.gz
Merge pull request #1404 from PyCQA/drop-xdg-config
Drop support for Home and XDG config files
-rw-r--r--docs/source/internal/option_handling.rst31
-rw-r--r--docs/source/release-notes/4.0.0.rst16
-rw-r--r--docs/source/release-notes/index.rst6
-rw-r--r--src/flake8/options/aggregator.py2
-rw-r--r--src/flake8/options/config.py64
-rw-r--r--tests/unit/test_config_parser.py (renamed from tests/unit/test_merged_config_parser.py)87
6 files changed, 49 insertions, 157 deletions
diff --git a/docs/source/internal/option_handling.rst b/docs/source/internal/option_handling.rst
index 21d6362..00c688f 100644
--- a/docs/source/internal/option_handling.rst
+++ b/docs/source/internal/option_handling.rst
@@ -129,13 +129,8 @@ In |Flake8| 2, configuration file discovery and management was handled by
pep8. In pep8's 1.6 release series, it drastically broke how discovery and
merging worked (as a result of trying to improve it). To avoid a dependency
breaking |Flake8| again in the future, we have created our own discovery and
-management.
-As part of managing this ourselves, we decided to change management/discovery
-for 3.0.0. We have done the following:
-
-- User files (files stored in a user's home directory or in the XDG directory
- inside their home directory) are the first files read. For example, if the
- user has a ``~/.flake8`` file, we will read that first.
+management in 3.0.0. In 4.0.0 we have once again changed how this works and we
+removed support for user-level config files.
- Project files (files stored in the current directory) are read next and
merged on top of the user file. In other words, configuration in project
@@ -157,7 +152,7 @@ To facilitate the configuration file management, we've taken a different
approach to discovery and management of files than pep8. In pep8 1.5, 1.6, and
1.7 configuration discovery and management was centralized in `66 lines of
very terse python`_ which was confusing and not very explicit. The terseness
-of this function (|Flake8|'s authors believe) caused the confusion and
+of this function (|Flake8| 3.0.0's authors believe) caused the confusion and
problems with pep8's 1.6 series. As such, |Flake8| has separated out
discovery, management, and merging into a module to make reasoning about each
of these pieces easier and more explicit (as well as easier to test).
@@ -176,23 +171,19 @@ to parse those configuration files.
.. note:: ``local_config_files`` also filters out non-existent files.
Configuration file merging and managemnt is controlled by the
-:class:`~flake8.options.config.MergedConfigParser`. This requires the instance
+:class:`~flake8.options.config.ConfigParser`. This requires the instance
of :class:`~flake8.options.manager.OptionManager` that the program is using,
the list of appended config files, and the list of extra arguments. This
object is currently the sole user of the
:class:`~flake8.options.config.ConfigFileFinder` object. It appropriately
initializes the object and uses it in each of
-- :meth:`~flake8.options.config.MergedConfigParser.parse_cli_config`
-- :meth:`~flake8.options.config.MergedConfigParser.parse_local_config`
-- :meth:`~flake8.options.config.MergedConfigParser.parse_user_config`
+- :meth:`~flake8.options.config.ConfigParser.parse_cli_config`
+- :meth:`~flake8.options.config.ConfigParser.parse_local_config`
-Finally,
-:meth:`~flake8.options.config.MergedConfigParser.merge_user_and_local_config`
-takes the user and local configuration files that are parsed by
-:meth:`~flake8.options.config.MergedConfigParser.parse_local_config` and
-:meth:`~flake8.options.config.MergedConfigParser.parse_user_config`. The
-main usage of the ``MergedConfigParser`` is in
+Finally, :meth:`~flake8.options.config.ConfigParser.parse` returns the
+appropriate configuration dictionary for this execution of |Flake8|. The
+main usage of the ``ConfigParser`` is in
:func:`~flake8.options.aggregator.aggregate_options`.
Aggregating Configuration File and Command Line Arguments
@@ -201,7 +192,7 @@ Aggregating Configuration File and Command Line Arguments
:func:`~flake8.options.aggregator.aggregate_options` accepts an instance of
:class:`~flake8.options.manager.OptionManager` and does the work to parse the
command-line arguments passed by the user necessary for creating an instance
-of :class:`~flake8.options.config.MergedConfigParser`.
+of :class:`~flake8.options.config.ConfigParser`.
After parsing the configuration file, we determine the default ignore list. We
use the defaults from the OptionManager and update those with the parsed
@@ -229,6 +220,6 @@ API Documentation
:members:
:special-members:
-.. autoclass:: flake8.options.config.MergedConfigParser
+.. autoclass:: flake8.options.config.ConfigParser
:members:
:special-members:
diff --git a/docs/source/release-notes/4.0.0.rst b/docs/source/release-notes/4.0.0.rst
new file mode 100644
index 0000000..e997d09
--- /dev/null
+++ b/docs/source/release-notes/4.0.0.rst
@@ -0,0 +1,16 @@
+4.0.0 -- 202x-mm-dd
+-------------------
+
+You can view the `4.0.0 milestone`_ on GitHub for more details.
+
+Backwards Incompatible Changes
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- Due to constant confusion by users, user-level |Flake8| configuration files
+ are no longer supported. Files will not be searched for in the user's home
+ directory (e.g., ``~/.flake8``) nor in the XDG config directory (e.g.,
+ ``~/.config/flake8``).
+
+.. all links
+.. _4.0.0 milestone:
+ https://github.com/PyCQA/flake8/milestone/39
diff --git a/docs/source/release-notes/index.rst b/docs/source/release-notes/index.rst
index dd20253..3617ff4 100644
--- a/docs/source/release-notes/index.rst
+++ b/docs/source/release-notes/index.rst
@@ -5,6 +5,12 @@
All of the release notes that have been recorded for Flake8 are organized here
with the newest releases first.
+4.x Release Series
+==================
+
+.. toctree::
+ 4.0.0
+
3.x Release Series
==================
diff --git a/src/flake8/options/aggregator.py b/src/flake8/options/aggregator.py
index 40848a2..73a0f36 100644
--- a/src/flake8/options/aggregator.py
+++ b/src/flake8/options/aggregator.py
@@ -38,7 +38,7 @@ def aggregate_options(
default_values, _ = manager.parse_args([])
# Make our new configuration file mergerator
- config_parser = config.MergedConfigParser(
+ config_parser = config.ConfigParser(
option_manager=manager, config_finder=config_finder
)
diff --git a/src/flake8/options/config.py b/src/flake8/options/config.py
index e920e58..fc3b205 100644
--- a/src/flake8/options/config.py
+++ b/src/flake8/options/config.py
@@ -11,7 +11,7 @@ from flake8 import utils
LOG = logging.getLogger(__name__)
-__all__ = ("ConfigFileFinder", "MergedConfigParser")
+__all__ = ("ConfigFileFinder", "ConfigParser")
class ConfigFileFinder:
@@ -48,7 +48,6 @@ class ConfigFileFinder:
# User configuration file.
self.program_name = program_name
- 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", f".{program_name}")
@@ -56,19 +55,6 @@ class ConfigFileFinder:
self.local_directory = os.path.abspath(os.curdir)
@staticmethod
- def _user_config_file(program_name: str) -> str:
- if utils.is_windows():
- home_dir = os.path.expanduser("~")
- config_file_basename = f".{program_name}"
- else:
- home_dir = os.environ.get(
- "XDG_CONFIG_HOME", os.path.expanduser("~/.config")
- )
- config_file_basename = program_name
-
- return os.path.join(home_dir, config_file_basename)
-
- @staticmethod
def _read_config(
*files: str,
) -> Tuple[configparser.RawConfigParser, List[str]]:
@@ -146,15 +132,8 @@ class ConfigFileFinder:
"""Parse all local config files into one config object."""
return self.local_configs_with_files()[0]
- def user_config(self):
- """Parse the user config file into a config object."""
- config, found_files = self._read_config(self.user_config_file)
- if found_files:
- LOG.debug("Found user configuration files: %s", found_files)
- return config
-
-class MergedConfigParser:
+class ConfigParser:
"""Encapsulate merging different types of configuration files.
This parses out the options registered that were specified in the
@@ -167,7 +146,7 @@ class MergedConfigParser:
GETBOOL_ACTIONS = {"store_true", "store_false"}
def __init__(self, option_manager, config_finder):
- """Initialize the MergedConfigParser instance.
+ """Initialize the ConfigParser instance.
:param flake8.options.manager.OptionManager option_manager:
Initialized OptionManager.
@@ -239,19 +218,6 @@ class MergedConfigParser:
LOG.debug("Parsing local configuration files.")
return self._parse_config(config)
- def parse_user_config(self):
- """Parse and return the user configuration files."""
- config = self.config_finder.user_config()
- if not self.is_configured_by(config):
- LOG.debug(
- "User configuration files have no %s section",
- self.program_name,
- )
- return {}
-
- LOG.debug("Parsing user configuration files.")
- return self._parse_config(config)
-
def parse_cli_config(self, config_path):
"""Parse and return the file specified by --config."""
config = self.config_finder.cli_config(config_path)
@@ -265,28 +231,8 @@ class MergedConfigParser:
LOG.debug("Parsing CLI configuration files.")
return self._parse_config(config, os.path.dirname(config_path))
- def merge_user_and_local_config(self):
- """Merge the parsed user and local configuration files.
-
- :returns:
- Dictionary of the parsed and merged configuration options.
- :rtype:
- dict
- """
- user_config = self.parse_user_config()
- config = self.parse_local_config()
-
- for option, value in user_config.items():
- config.setdefault(option, value)
-
- return config
-
def parse(self):
- """Parse and return the local and user config files.
-
- First this copies over the parsed local configuration and then
- iterates over the options in the user configuration and sets them if
- they were not set by the local configuration file.
+ """Parse and return the local config files.
:returns:
Dictionary of parsed configuration options
@@ -309,7 +255,7 @@ class MergedConfigParser:
)
return self.parse_cli_config(self.config_finder.config_file)
- return self.merge_user_and_local_config()
+ return self.parse_local_config()
def get_local_plugins(config_finder):
diff --git a/tests/unit/test_merged_config_parser.py b/tests/unit/test_config_parser.py
index b19291c..0baa108 100644
--- a/tests/unit/test_merged_config_parser.py
+++ b/tests/unit/test_config_parser.py
@@ -1,4 +1,4 @@
-"""Unit tests for flake8.options.config.MergedConfigParser."""
+"""Unit tests for flake8.options.config.ConfigParser."""
import os
from unittest import mock
@@ -32,7 +32,7 @@ def test_parse_cli_config(optmanager, config_finder):
"--ignore", parse_from_config=True, comma_separated_list=True
)
optmanager.add_option("--quiet", parse_from_config=True, action="count")
- parser = config.MergedConfigParser(optmanager, config_finder)
+ parser = config.ConfigParser(optmanager, config_finder)
config_file = "tests/fixtures/config_files/cli-specified.ini"
parsed_config = parser.parse_cli_config(config_file)
@@ -61,41 +61,11 @@ def test_is_configured_by(
):
"""Verify the behaviour of the is_configured_by method."""
parsed_config, _ = config.ConfigFileFinder._read_config(filename)
- parser = config.MergedConfigParser(optmanager, config_finder)
+ parser = config.ConfigParser(optmanager, config_finder)
assert parser.is_configured_by(parsed_config) is is_configured_by
-def test_parse_user_config(optmanager, config_finder):
- """Verify parsing of user config files."""
- optmanager.add_option(
- "--exclude",
- parse_from_config=True,
- comma_separated_list=True,
- normalize_paths=True,
- )
- optmanager.add_option(
- "--ignore", parse_from_config=True, comma_separated_list=True
- )
- optmanager.add_option("--quiet", parse_from_config=True, action="count")
- parser = config.MergedConfigParser(optmanager, config_finder)
-
- config_finder.user_config_file = (
- "tests/fixtures/config_files/" "cli-specified.ini"
- )
- parsed_config = parser.parse_user_config()
-
- assert parsed_config == {
- "ignore": ["E123", "W234", "E111"],
- "exclude": [
- os.path.abspath("foo/"),
- os.path.abspath("bar/"),
- os.path.abspath("bogus/"),
- ],
- "quiet": 1,
- }
-
-
def test_parse_local_config(optmanager, config_finder):
"""Verify parsing of local config files."""
optmanager.add_option(
@@ -108,7 +78,7 @@ def test_parse_local_config(optmanager, config_finder):
"--ignore", parse_from_config=True, comma_separated_list=True
)
optmanager.add_option("--quiet", parse_from_config=True, action="count")
- parser = config.MergedConfigParser(optmanager, config_finder)
+ parser = config.ConfigParser(optmanager, config_finder)
with mock.patch.object(config_finder, "local_config_files") as localcfs:
localcfs.return_value = [
@@ -127,47 +97,14 @@ def test_parse_local_config(optmanager, config_finder):
}
-def test_merge_user_and_local_config(optmanager, config_finder):
- """Verify merging of parsed user and local config files."""
- optmanager.add_option(
- "--exclude",
- parse_from_config=True,
- comma_separated_list=True,
- normalize_paths=True,
- )
- optmanager.add_option(
- "--ignore", parse_from_config=True, comma_separated_list=True
- )
- optmanager.add_option(
- "--select", parse_from_config=True, comma_separated_list=True
- )
- parser = config.MergedConfigParser(optmanager, config_finder)
-
- with mock.patch.object(config_finder, "local_config_files") as localcfs:
- localcfs.return_value = [
- "tests/fixtures/config_files/local-config.ini"
- ]
- config_finder.user_config_file = (
- "tests/fixtures/config_files/" "user-config.ini"
- )
- parsed_config = parser.merge_user_and_local_config()
-
- assert parsed_config == {
- "exclude": [os.path.abspath("docs/")],
- "ignore": ["D203"],
- "select": ["E", "W", "F"],
- }
-
-
def test_parse_isolates_config(optmanager):
"""Verify behaviour of the parse method with isolated=True."""
config_finder = mock.MagicMock()
config_finder.ignore_config_files = True
- parser = config.MergedConfigParser(optmanager, config_finder)
+ parser = config.ConfigParser(optmanager, config_finder)
assert parser.parse() == {}
assert config_finder.local_configs.called is False
- assert config_finder.user_config.called is False
def test_parse_uses_cli_config(optmanager):
@@ -176,7 +113,7 @@ def test_parse_uses_cli_config(optmanager):
config_finder = mock.MagicMock()
config_finder.config_file = config_file_value
config_finder.ignore_config_files = False
- parser = config.MergedConfigParser(optmanager, config_finder)
+ parser = config.ConfigParser(optmanager, config_finder)
parser.parse()
config_finder.cli_config.assert_called_once_with(config_file_value)
@@ -206,13 +143,11 @@ def test_parsed_configs_are_equivalent(
optmanager.add_option(
"--ignore", parse_from_config=True, comma_separated_list=True
)
- parser = config.MergedConfigParser(optmanager, config_finder)
+ parser = config.ConfigParser(optmanager, config_finder)
with mock.patch.object(config_finder, "local_config_files") as localcfs:
localcfs.return_value = [config_fixture_path]
- with mock.patch.object(config_finder, "user_config_file") as usercf:
- usercf.return_value = ""
- parsed_config = parser.merge_user_and_local_config()
+ parsed_config = parser.parse()
assert parsed_config["ignore"] == ["E123", "W234", "E111"]
assert parsed_config["exclude"] == [
@@ -243,13 +178,11 @@ def test_parsed_hyphenated_and_underscored_names(
parse_from_config=True,
comma_separated_list=True,
)
- parser = config.MergedConfigParser(optmanager, config_finder)
+ parser = config.ConfigParser(optmanager, config_finder)
with mock.patch.object(config_finder, "local_config_files") as localcfs:
localcfs.return_value = [config_file]
- with mock.patch.object(config_finder, "user_config_file") as usercf:
- usercf.return_value = ""
- parsed_config = parser.merge_user_and_local_config()
+ parsed_config = parser.parse()
assert parsed_config["max_line_length"] == 110
assert parsed_config["enable_extensions"] == ["H101", "H235"]