pytest: Pytest should't import conftest if __init__ raises Skipped

I have a package that needs to support Python 3 and 2 code. To accommodate this I’ve created a test directory specifically aimed at testing my Python 3 code. Within that directory I have an __init__.py with the following contents:

import sys
import pytest

if sys.version_info < (3, 0):
    pytest.skip("skipping Python 3 only tests", allow_module_level=True)

If I place a conftest.py file inside the directory containing this __init__.py and running pytest using Python 2 I get the following output:

==================================== test session starts =====================================
platform darwin -- Python 2.7.15, pytest-4.6.9, py-1.8.1, pluggy-0.13.1
plugins: env-info-0.3.0, mock-2.0.0, cov-2.8.1
collected 0 items / 1 skipped                                                                

================================== short test summary info ===================================
SKIPPED [1] xxxxxxxxxxxxxxxxx.py: skipping Python 3 only tests

-- Docs: https://docs.pytest.org/en/latest/warnings.html
=========================== 1 skipped, 1 warnings in 0.12 seconds ============================
ERROR: InvocationError for command xxx/bin/python -m pytest tests (exited with code 5)

I’m not really sure what’s gone wrong, but this only occurs if I have a conftest.py within the directory I’m trying to skip, removing the conftest.py allows things to work again. If I use an explicit --ignore test_my_py_3_stuff instead of the programatic skipping, everything seems to work even if I have a conftest.py file.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 15 (7 by maintainers)

Most upvoted comments

To be honest, EoL for Python 2 was announced over a decade ago, and we’re already passed it. There’s been almost 12 years worth of moments to implement backwards compatibility. That should really be a top priority at this point.

@rmorshea https://doc.pytest.org/en/latest/skipping.html#skipping-test-functions <- allow_module_level might help, i believe you would still need a conftest with collect_ignore in some way to make sure the files are really skipped

@rmorshea you’ll want to have it raise it at test runtime. If it’s in the global scope, then it will still be happening while python itself is still parsing package, before pytest gets involved (or at least while pytest is importing it, so it’d have to be importing in a try/except, but I’m not sure if it is or isn’t). To get it to happen at test runtime, it’ll need to be in a fixture, e.g.:

@pytest.fixture(scope="session", autouse=True)
def check_python_version():
    if sys.version_info < (3, 0):
        pytest.skip("skipping Python 3 only tests")

The scope for this is session, so that it only happens once for the whole package, and happens as soon as possible.

It looks like the docs recommend the approach you were taking, so it could be a bug that it didn’t initially work for you, but that approach may actually only work for a single module, and the approach in my example is more stable in the long run because it uses more fundamental features of pytest.