Skip to content

pytest.ini pythonpath doesn't work with local early-loaded (-p) plugin #11118

Description

@a3f

I am using pytest 7.2.1 on NixOS 23.05 and want to early-load a plugin, so I can do some custom command line parsing using pytest_load_initial_conftests. Here's my setup:

 >conftest.py     echo 'pytest_plugins = [ "my_plugin" ]'
 >my_plugin.py    echo 'print("Plugin loaded")'
 >pytest.ini      echo '[pytest]' 
>>pytest.ini      echo 'pythonpath = .' 

Normal non-early loading of plugin works:

$ pytest -q
no tests ran in 0.00s
Plugin loaded

Early-loading plugin with manual PYTHONPATH override also works:

$ PYTHONPATH="$PYTHONPATH:." pytest -p my_plugin -q
Plugin loaded

no tests ran in 0.00s

But relying on pytest.ini pythonpath for early-loading fails:

$ pytest -p my_plugin
Traceback (most recent call last):
  File "/nix/store/apjpa7zk1p61ri44n1a4mykdyqpbdvw1-python3.10-pytest-7.2.1/lib/python3.10/site-packages/_pytest/config/__init__.py", line 774, in import_plugin
    __import__(importspec)
ModuleNotFoundError: No module named 'my_plugin'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/nix/store/apjpa7zk1p61ri44n1a4mykdyqpbdvw1-python3.10-pytest-7.2.1/bin/.pytest-wrapped", line 9, in <module>
    sys.exit(console_main())
  File "/nix/store/apjpa7zk1p61ri44n1a4mykdyqpbdvw1-python3.10-pytest-7.2.1/lib/python3.10/site-packages/_pytest/config/__init__.py", line 190, in console_main
    code = main()
  File "/nix/store/apjpa7zk1p61ri44n1a4mykdyqpbdvw1-python3.10-pytest-7.2.1/lib/python3.10/site-packages/_pytest/config/__init__.py", line 148, in main
    config = _prepareconfig(args, plugins)
  File "/nix/store/apjpa7zk1p61ri44n1a4mykdyqpbdvw1-python3.10-pytest-7.2.1/lib/python3.10/site-packages/_pytest/config/__init__.py", line 329, in _prepareconfig
    config = pluginmanager.hook.pytest_cmdline_parse(
  File "/nix/store/r5wq2w8xy457h1bwx3fyb8lvlaim3gkx-python3.10-pluggy-1.0.0/lib/python3.10/site-packages/pluggy/_hooks.py", line 265, in __call__
    return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
  File "/nix/store/r5wq2w8xy457h1bwx3fyb8lvlaim3gkx-python3.10-pluggy-1.0.0/lib/python3.10/site-packages/pluggy/_manager.py", line 80, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
  File "/nix/store/r5wq2w8xy457h1bwx3fyb8lvlaim3gkx-python3.10-pluggy-1.0.0/lib/python3.10/site-packages/pluggy/_callers.py", line 55, in _multicall
    gen.send(outcome)
  File "/nix/store/apjpa7zk1p61ri44n1a4mykdyqpbdvw1-python3.10-pytest-7.2.1/lib/python3.10/site-packages/_pytest/helpconfig.py", line 103, in pytest_cmdline_parse
    config: Config = outcome.get_result()
  File "/nix/store/r5wq2w8xy457h1bwx3fyb8lvlaim3gkx-python3.10-pluggy-1.0.0/lib/python3.10/site-packages/pluggy/_result.py", line 60, in get_result
    raise ex[1].with_traceback(ex[2])
  File "/nix/store/r5wq2w8xy457h1bwx3fyb8lvlaim3gkx-python3.10-pluggy-1.0.0/lib/python3.10/site-packages/pluggy/_callers.py", line 39, in _multicall
    res = hook_impl.function(*args)
  File "/nix/store/apjpa7zk1p61ri44n1a4mykdyqpbdvw1-python3.10-pytest-7.2.1/lib/python3.10/site-packages/_pytest/config/__init__.py", line 1058, in pytest_cmdline_parse
    self.parse(args)
  File "/nix/store/apjpa7zk1p61ri44n1a4mykdyqpbdvw1-python3.10-pytest-7.2.1/lib/python3.10/site-packages/_pytest/config/__init__.py", line 1346, in parse
    self._preparse(args, addopts=addopts)
  File "/nix/store/apjpa7zk1p61ri44n1a4mykdyqpbdvw1-python3.10-pytest-7.2.1/lib/python3.10/site-packages/_pytest/config/__init__.py", line 1225, in _preparse
    self.pluginmanager.consider_preparse(args, exclude_only=False)
  File "/nix/store/apjpa7zk1p61ri44n1a4mykdyqpbdvw1-python3.10-pytest-7.2.1/lib/python3.10/site-packages/_pytest/config/__init__.py", line 702, in consider_preparse
    self.consider_pluginarg(parg)
  File "/nix/store/apjpa7zk1p61ri44n1a4mykdyqpbdvw1-python3.10-pytest-7.2.1/lib/python3.10/site-packages/_pytest/config/__init__.py", line 728, in consider_pluginarg
    self.import_plugin(arg, consider_entry_points=True)
  File "/nix/store/apjpa7zk1p61ri44n1a4mykdyqpbdvw1-python3.10-pytest-7.2.1/lib/python3.10/site-packages/_pytest/config/__init__.py", line 776, in import_plugin
    raise ImportError(
  File "/nix/store/apjpa7zk1p61ri44n1a4mykdyqpbdvw1-python3.10-pytest-7.2.1/lib/python3.10/site-packages/_pytest/config/__init__.py", line 774, in import_plugin
    __import__(importspec)
ImportError: Error importing plugin "my_plugin": No module named 'my_plugin'

I haven't seen anything in the docs to indicate that pythonpath is not applicable to -p. If that's intended behavior, it would be nice to amend the docs to reflect that. Also, I am curious if there's another way to get pytest -p my_plugin to just work? I'd like to add -p my_plugin to my pytest.ini eventually, so users just need to type in pytest and not have to worry about paths.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    topic: configrelated to config handling, argument parsing and config filetype: docsdocumentation improvement, missing or needing clarificationtype: questiongeneral question, might be closed after 2 weeks of inactivity

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions