3

For reference, this is the opposite of this question. That question asks how to get pytest to use your local module. I want to avoid pytest using the local module.

I need to test my module's installation procedure. We should all be testing our modules' installation procedures. Therefore, I want my test suite to pretend like it's any other python module trying to import my module, which I have installed (whether or not it's up to date with my latest edits and/or an editable install is my business).

My project layout looks like this:

.
├── my_package
│   ├── __init__.py
│   └── my_module.py
├── setup.py
├── pyproject.toml
└── tests
    ├── conftest.py
    ├── __init__.py
    └── test_my_package.py

If I

pip install .
cd tests
python -c "import my_package"

it all works. However, if I

pip install .
pytest

it does not. This is because pytest automatically adds the calling directory to the PYTHONPATH, making it impossible to test that pip install has worked. I want it to not do that.

I need to do this because I am using setuptools-scm (which has different behaviour in editable and non-editable installs) and setuptools.find_packages, which makes it easy to ignore subpackages. However, to reiterate, my issue is with pytest's discovery, not with the use of these two utilities.

Chris L. Barnes
  • 475
  • 4
  • 13

2 Answers2

2

See docs for pytest import mechanisms and sys.path/PYTHONPATH, which describe three import modes, which control this behavior. For instance, try this:

$ pytest --import-mode=importlib

which uses importlib to import test modules, rather than manipulating sys.path or PYTHONPATH.

Mike T
  • 41,085
  • 18
  • 152
  • 203
0

A workaround is to manually edit the PYTHONPATH by changing tests/conftest.py to include

import sys
sys.path.pop(0)

before the first time my_module is imported, but it's not pretty and makes the assumption about where in the PYTHONPATH that item is going to show up. Of course, more code could be added to check explicitly, but that's really ugly:

import sys
from pathlib import Path
project_dir = str(Path(__file__).resolve().parent.parent)
sys.path = [p for p in sys.path if not p.startswith(project_dir)]
Chris L. Barnes
  • 475
  • 4
  • 13