Skip to content

Commit 0bb8a4a

Browse files
committed
Fixed #2148 - parse directory names properly when args contains ::.
This commit also improves readbility in get_dirs_from_args by using self documenting local functions. get_dirs_from_args also now only returns directories that actually exists, and not files to avoid confusion. This commit also removes redundant checks in get_common_ancestor that was already performed in get_dirs_from_args..
1 parent 3164062 commit 0bb8a4a

File tree

3 files changed

+59
-17
lines changed

3 files changed

+59
-17
lines changed

CHANGELOG.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,17 @@
99
expected warnings and the list of caught warnings is added to the
1010
error message. Thanks `@lesteve`_ for the PR.
1111

12-
*
12+
* Specifying tests with colons like ``test_foo.py::test_bar`` for tests in
13+
subdirectories with ini configuration files now uses the correct ini file
14+
(`#2148`_). Thanks `@pelme`_.
1315

1416
*
1517

1618
.. _@lesteve: https://github.com/lesteve
19+
.. _@pelme: https://github.com/pelme
1720

1821
.. _#2150: https://github.com/pytest-dev/pytest/issues/2150
22+
.. _#2148: https://github.com/pytest-dev/pytest/issues/2148
1923

2024

2125
3.0.5 (2016-12-05)

_pytest/config.py

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,25 +1228,20 @@ def getcfg(args, warnfunc=None):
12281228
return None, None, None
12291229

12301230

1231-
def get_common_ancestor(args):
1232-
# args are what we get after early command line parsing (usually
1233-
# strings, but can be py.path.local objects as well)
1231+
def get_common_ancestor(paths):
12341232
common_ancestor = None
1235-
for arg in args:
1236-
if str(arg)[0] == "-":
1237-
continue
1238-
p = py.path.local(arg)
1239-
if not p.exists():
1233+
for path in paths:
1234+
if not path.exists():
12401235
continue
12411236
if common_ancestor is None:
1242-
common_ancestor = p
1237+
common_ancestor = path
12431238
else:
1244-
if p.relto(common_ancestor) or p == common_ancestor:
1239+
if path.relto(common_ancestor) or path == common_ancestor:
12451240
continue
1246-
elif common_ancestor.relto(p):
1247-
common_ancestor = p
1241+
elif common_ancestor.relto(path):
1242+
common_ancestor = path
12481243
else:
1249-
shared = p.common(common_ancestor)
1244+
shared = path.common(common_ancestor)
12501245
if shared is not None:
12511246
common_ancestor = shared
12521247
if common_ancestor is None:
@@ -1257,9 +1252,29 @@ def get_common_ancestor(args):
12571252

12581253

12591254
def get_dirs_from_args(args):
1260-
return [d for d in (py.path.local(x) for x in args
1261-
if not str(x).startswith("-"))
1262-
if d.exists()]
1255+
def is_option(x):
1256+
return str(x).startswith('-')
1257+
1258+
def get_file_part_from_node_id(x):
1259+
return str(x).split('::')[0]
1260+
1261+
def get_dir_from_path(path):
1262+
if path.isdir():
1263+
return path
1264+
return py.path.local(path.dirname)
1265+
1266+
# These look like paths but may not exist
1267+
possible_paths = (
1268+
py.path.local(get_file_part_from_node_id(arg))
1269+
for arg in args
1270+
if not is_option(arg)
1271+
)
1272+
1273+
return [
1274+
get_dir_from_path(path)
1275+
for path in possible_paths
1276+
if path.exists()
1277+
]
12631278

12641279

12651280
def determine_setup(inifile, args, warnfunc=None):

testing/test_config.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,29 @@ def test_toolongargs_issue224(testdir):
527527
result = testdir.runpytest("-m", "hello" * 500)
528528
assert result.ret == EXIT_NOTESTSCOLLECTED
529529

530+
def test_config_in_subdirectory_colon_command_line_issue2148(testdir):
531+
conftest_source = '''
532+
def pytest_addoption(parser):
533+
parser.addini('foo', 'foo')
534+
'''
535+
536+
testdir.makefile('.ini', **{
537+
'pytest': '[pytest]\nfoo = root',
538+
'subdir/pytest': '[pytest]\nfoo = subdir',
539+
})
540+
541+
testdir.makepyfile(**{
542+
'conftest': conftest_source,
543+
'subdir/conftest': conftest_source,
544+
'subdir/test_foo': '''
545+
def test_foo(pytestconfig):
546+
assert pytestconfig.getini('foo') == 'subdir'
547+
'''})
548+
549+
result = testdir.runpytest('subdir/test_foo.py::test_foo')
550+
assert result.ret == 0
551+
552+
530553
def test_notify_exception(testdir, capfd):
531554
config = testdir.parseconfig()
532555
excinfo = pytest.raises(ValueError, "raise ValueError(1)")

0 commit comments

Comments
 (0)