Skip to content

Fix handling of ini configuration in subdirs when specifying :: #2149

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 27, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@
expected warnings and the list of caught warnings is added to the
error message. Thanks `@lesteve`_ for the PR.

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

*

.. _@lesteve: https://github.com/lesteve
.. _@pelme: https://github.com/pelme

.. _#2150: https://github.com/pytest-dev/pytest/issues/2150
.. _#2148: https://github.com/pytest-dev/pytest/issues/2148


3.0.5 (2016-12-05)
Expand Down
47 changes: 31 additions & 16 deletions _pytest/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -1228,25 +1228,20 @@ def getcfg(args, warnfunc=None):
return None, None, None


def get_common_ancestor(args):
# args are what we get after early command line parsing (usually
# strings, but can be py.path.local objects as well)
def get_common_ancestor(paths):
common_ancestor = None
for arg in args:
if str(arg)[0] == "-":
continue
p = py.path.local(arg)
if not p.exists():
for path in paths:
if not path.exists():
continue
if common_ancestor is None:
common_ancestor = p
common_ancestor = path
else:
if p.relto(common_ancestor) or p == common_ancestor:
if path.relto(common_ancestor) or path == common_ancestor:
continue
elif common_ancestor.relto(p):
common_ancestor = p
elif common_ancestor.relto(path):
common_ancestor = path
else:
shared = p.common(common_ancestor)
shared = path.common(common_ancestor)
if shared is not None:
common_ancestor = shared
if common_ancestor is None:
Expand All @@ -1257,9 +1252,29 @@ def get_common_ancestor(args):


def get_dirs_from_args(args):
return [d for d in (py.path.local(x) for x in args
if not str(x).startswith("-"))
if d.exists()]
def is_option(x):
return str(x).startswith('-')

def get_file_part_from_node_id(x):
return str(x).split('::')[0]

def get_dir_from_path(path):
if path.isdir():
return path
return py.path.local(path.dirname)

# These look like paths but may not exist
possible_paths = (
py.path.local(get_file_part_from_node_id(arg))
for arg in args
if not is_option(arg)
)

return [
get_dir_from_path(path)
for path in possible_paths
if path.exists()
]


def determine_setup(inifile, args, warnfunc=None):
Expand Down
23 changes: 23 additions & 0 deletions testing/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,29 @@ def test_toolongargs_issue224(testdir):
result = testdir.runpytest("-m", "hello" * 500)
assert result.ret == EXIT_NOTESTSCOLLECTED

def test_config_in_subdirectory_colon_command_line_issue2148(testdir):
conftest_source = '''
def pytest_addoption(parser):
parser.addini('foo', 'foo')
'''

testdir.makefile('.ini', **{
'pytest': '[pytest]\nfoo = root',
'subdir/pytest': '[pytest]\nfoo = subdir',
})

testdir.makepyfile(**{
'conftest': conftest_source,
'subdir/conftest': conftest_source,
'subdir/test_foo': '''
def test_foo(pytestconfig):
assert pytestconfig.getini('foo') == 'subdir'
'''})

result = testdir.runpytest('subdir/test_foo.py::test_foo')
assert result.ret == 0


def test_notify_exception(testdir, capfd):
config = testdir.parseconfig()
excinfo = pytest.raises(ValueError, "raise ValueError(1)")
Expand Down