diff --git a/CHANGELOG.rst b/CHANGELOG.rst index cfd77cb0c..906aa640e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -203,6 +203,9 @@ time or change existing behaviors in order to make them less surprising/more use removed in pytest-4.0 (`#1684`_). Thanks `@nicoddemus`_ for the PR. +* Passing a command-line string to ``pytest.main()`` is considered deprecated and scheduled + for removal in pytest-4.0. It is recommended to pass a list of arguments instead (`#1723`_). + * Rename ``getfuncargvalue`` to ``getfixturevalue``. ``getfuncargvalue`` is still present but is now considered deprecated. Thanks to `@RedBeardCode`_ and `@tomviner`_ for the PR (`#1626`_). @@ -282,6 +285,7 @@ time or change existing behaviors in order to make them less surprising/more use .. _#1633: https://github.com/pytest-dev/pytest/pull/1633 .. _#1664: https://github.com/pytest-dev/pytest/pull/1664 .. _#1684: https://github.com/pytest-dev/pytest/pull/1684 +.. _#1723: https://github.com/pytest-dev/pytest/pull/1723 .. _@DRMacIver: https://github.com/DRMacIver .. _@RedBeardCode: https://github.com/RedBeardCode diff --git a/_pytest/config.py b/_pytest/config.py index 8cb1e6e01..2309ac317 100644 --- a/_pytest/config.py +++ b/_pytest/config.py @@ -98,6 +98,7 @@ def get_plugin_manager(): return get_config().pluginmanager def _prepareconfig(args=None, plugins=None): + warning = None if args is None: args = sys.argv[1:] elif isinstance(args, py.path.local): @@ -106,6 +107,10 @@ def _prepareconfig(args=None, plugins=None): if not isinstance(args, str): raise ValueError("not a string or argument list: %r" % (args,)) args = shlex.split(args, posix=sys.platform != "win32") + # we want to remove this way of passing arguments to pytest.main() + # in pytest-4.0 + warning = ('passing a string to pytest.main() is deprecated, ' + 'pass a list of arguments instead.') config = get_config() pluginmanager = config.pluginmanager try: @@ -115,6 +120,8 @@ def _prepareconfig(args=None, plugins=None): pluginmanager.consider_pluginarg(plugin) else: pluginmanager.register(plugin) + if warning: + config.warn('C1', warning) return pluginmanager.hook.pytest_cmdline_parse( pluginmanager=pluginmanager, args=args) except BaseException: diff --git a/testing/acceptance_test.py b/testing/acceptance_test.py index d709a6f4d..58887712e 100644 --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -795,3 +795,17 @@ def test_funcarg_prefix_deprecation(testdir): 'Please remove the prefix and use the @pytest.fixture decorator instead.'), '*1 passed*', ]) + + +def test_str_args_deprecated(tmpdir, testdir): + """Deprecate passing strings to pytest.main(). Scheduled for removal in pytest-4.0.""" + warnings = [] + + class Collect: + def pytest_logwarning(self, message): + warnings.append(message) + + ret = pytest.main("%s -x" % tmpdir, plugins=[Collect()]) + testdir.delete_loaded_modules() + assert warnings == ['passing a string to pytest.main() is deprecated, pass a list of arguments instead.'] + assert ret == EXIT_NOTESTSCOLLECTED