Repository: tox-dev/tox

Issue:
[tox4] Document loaders on config set
I'm trying to port our tox extension to the new tox 4 and I have one problem described in this thread: https://github.com/fedora-python/tox-current-env/pull/42#pullrequestreview-799430800

The problem basically is that it's not possible to call `get_env` in `tox_add_env_config` because it causes an endless recursion. I need to do it so I can overwrite some settings loaded from config with values from the extension.

Discussion:

Patch:
diff --git a/docs/changelog/2183.feature.rst b/docs/changelog/2183.feature.rst
new file mode 100644
index 00000000..9ddfb8cf
--- /dev/null
+++ b/docs/changelog/2183.feature.rst
@@ -0,0 +1,2 @@
+Display a hint for unrecognized argument CLI parse failures to use ``--`` separator to pass arguments to commands
+- by :user:`gaborbernat`.
diff --git a/docs/changelog/2287.doc.rst b/docs/changelog/2287.doc.rst
new file mode 100644
index 00000000..40c2ab68
--- /dev/null
+++ b/docs/changelog/2287.doc.rst
@@ -0,0 +1,1 @@
+Document :meth:`tox.config.sets.ConfigSet.loaders` - by :user:`gaborbernat`.
diff --git a/src/tox/config/cli/parser.py b/src/tox/config/cli/parser.py
index a7a4e548..a49ce18b 100644
--- a/src/tox/config/cli/parser.py
+++ b/src/tox/config/cli/parser.py
@@ -76,6 +76,19 @@ class ArgumentParserWithEnvAndConfig(ArgumentParser):
                 raise TypeError(action)
         return of_type
 
+    def parse_args(  # type: ignore # avoid defining all overloads
+        self,
+        args: Sequence[str] | None = None,
+        namespace: Namespace | None = None,
+    ) -> Namespace:
+        res, argv = self.parse_known_args(args, namespace)
+        if argv:
+            self.error(
+                f'unrecognized arguments: {" ".join(argv)}\n'
+                "hint: if you tried to pass arguments to a command use -- to separate them from tox ones",
+            )
+        return res
+
 
 class HelpFormatter(ArgumentDefaultsHelpFormatter):
     """
diff --git a/src/tox/config/sets.py b/src/tox/config/sets.py
index 46864030..5f0df677 100644
--- a/src/tox/config/sets.py
+++ b/src/tox/config/sets.py
@@ -24,7 +24,7 @@ class ConfigSet(ABC):
         self._section = section
         self._env_name = env_name
         self._conf = conf
-        self.loaders: list[Loader[Any]] = []
+        self.loaders: list[Loader[Any]] = []  #: active configuration loaders, can alter to change configuration values
         self._defined: dict[str, ConfigDefinition[Any]] = {}
         self._keys: dict[str, None] = {}
         self._alias: dict[str, str] = {}


Test patch:
diff --git a/tests/config/cli/test_parser.py b/tests/config/cli/test_parser.py
index 71d515cf..3b965d0d 100644
--- a/tests/config/cli/test_parser.py
+++ b/tests/config/cli/test_parser.py
@@ -7,7 +7,7 @@ import pytest
 from pytest_mock import MockerFixture
 
 from tox.config.cli.parser import Parsed, ToxParser
-from tox.pytest import MonkeyPatch
+from tox.pytest import CaptureFixture, MonkeyPatch
 
 
 def test_parser_const_with_default_none(monkeypatch: MonkeyPatch) -> None:
@@ -81,3 +81,11 @@ def test_parse_known_args_not_set(mocker: MockerFixture) -> None:
     parser = ToxParser.base()
     _, unknown = parser.parse_known_args(None)
     assert unknown == ["--help"]
+
+
+def test_parser_hint(capsys: CaptureFixture) -> None:
+    parser = ToxParser.base()
+    with pytest.raises(SystemExit):
+        parser.parse_args("foo")
+    out, err = capsys.readouterr()
+    assert err.endswith("hint: if you tried to pass arguments to a command use -- to separate them from tox ones\n")