Skip to content

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

Closed
@a3f

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.

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