Repository: nose-devs/nose2

Issue:
v0.15.0 seemed to break my ini config
Here is my ini config file:
```
[flake8]
max-line-length = 120
extend-ignore = E722

[unittest]
plugins = nose2.plugins.layers
          nose2.plugins.junitxml

[junit-xml]
always-on = False
keep_restricted = False
path = nosetests.xml
test_fullname = False

[layer-reporter]
always-on = True
colors = False
```

Running `nose2 -c tox.ini --junit-xml <testNames>` I get:
`nose2: error: Unrecognized arguments: --junit-xml`

Reverting back to v0.14.2 fixes my issue.

Discussion:

Patch:
diff --git a/docs/changelog.rst b/docs/changelog.rst
index 3a842fb..5d0c4b3 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -13,6 +13,13 @@ testsuites.
 Unreleased
 ----------
 
+Fixed
+~~~~~
+
+* Fix a bug with config loading which caused custom ini configs not to load if
+  they were not named with a ``.cfg`` extension. Thanks :user:`grhwalls` for
+  the bug report!
+
 0.15.0 (2024-05-30)
 -------------------
 
diff --git a/nose2/session.py b/nose2/session.py
index bfc3e1d..d6e527e 100644
--- a/nose2/session.py
+++ b/nose2/session.py
@@ -1,8 +1,7 @@
 import argparse
 import logging
 import os
-
-# py2/py3 compatible load of SafeConfigParser/ConfigParser
+import pathlib
 from configparser import ConfigParser
 
 from nose2 import config, events, util
@@ -120,11 +119,12 @@ class Session:
 
         """
         for filename in filenames:
-            if filename.endswith(".cfg"):
-                self.config.read(filename)
-            elif filename.endswith("pyproject.toml"):
-                if not os.path.exists(filename):
-                    continue
+            path = pathlib.Path(filename)
+            if not path.exists():
+                continue
+
+            # handle pyproject.toml case
+            if path.name == "pyproject.toml":
                 toml_config = load_toml(filename)
                 if not isinstance(toml_config.get("tool"), dict):
                     continue
@@ -133,6 +133,10 @@ class Session:
                     continue
                 self.config.read_dict(tool_table["nose2"])
 
+            # else, use the config parser to read config data
+            else:
+                self.config.read(path)
+
     def loadPlugins(self, modules=None, exclude=None):
         """Load plugins.
 


Test patch:
diff --git a/nose2/tests/functional/test_session.py b/nose2/tests/functional/test_session.py
index 9f7061a..27a1eb7 100644
--- a/nose2/tests/functional/test_session.py
+++ b/nose2/tests/functional/test_session.py
@@ -1,4 +1,6 @@
+import pathlib
 import sys
+import tempfile
 import unittest
 
 from nose2 import session
@@ -6,6 +8,25 @@ from nose2._toml import TOML_ENABLED
 from nose2.tests._common import FunctionalTestCase, support_file
 
 
+def test_loading_config_from_ini_file_without_cfg_suffix():
+    """
+    Regression test for https://github.com/nose-devs/nose2/issues/614
+
+    It is possible to have nose2 config embedded in any ini config file, and it might
+    not have a recognizable name.
+    It is not guaranteed that filenames used for config will end in `.cfg`.
+    """
+    sess = session.Session()
+    with tempfile.TemporaryDirectory() as tmpdirname:
+        tmpdir = pathlib.Path(tmpdirname)
+
+        foo_ini = tmpdir / "foo.ini"
+        foo_ini.write_text("""[alpha]\na = 1""")
+
+        sess.loadConfigFiles(str(foo_ini))
+        assert sess.config.has_section("alpha")
+
+
 class SessionFunctionalTests(FunctionalTestCase):
     def setUp(self):
         self.s = session.Session()