Skip to content

Feedback about --import-mode=importlib in pytest 6.0 #7245

Closed
@nicoddemus

Description

@nicoddemus
Member

This issue is a placeholder to gather feedback from users about the new --import-mode=importlib introduced in pytest 6.0.

It is our intention to change the default to importlib in future versions, and perhaps even eliminate the other --import-mode options (prepend and append).

Activity

The-Compiler

The-Compiler commented on Jul 12, 2020

@The-Compiler
Member

It looks like the pytest-bdd plugin is incompatible with --import-mode=importlib:

_______________________________ ERROR collecting tests/end2end/features/test_backforward_bdd.py _______________________________
tests/end2end/features/test_backforward_bdd.py:21: in <module>
    bdd.scenarios('backforward.feature')
.tox/py38-pyqt515/lib/python3.8/site-packages/pytest_bdd/scenario.py:296: in scenarios
    features_base_dir = get_features_base_dir(module)
.tox/py38-pyqt515/lib/python3.8/site-packages/pytest_bdd/scenario.py:241: in get_features_base_dir
    default_base_dir = os.path.dirname(caller_module.__file__)
E   AttributeError: 'NoneType' object has no attribute '__file__'

Relevant code:

def scenarios(*feature_paths, **kwargs):
    frame = inspect.stack()[1]
    module = inspect.getmodule(frame[0])    # <- this is None

    features_base_dir = kwargs.get("features_base_dir")
    if features_base_dir is None:
        features_base_dir = get_features_base_dir(module)

Any idea why this could be happening?

nicoddemus

nicoddemus commented on Jul 13, 2020

@nicoddemus
MemberAuthor

I think bdd.scenarios assumes the module given as arguments are available in sys.path, which is not the case when --import-mode=importlib.

Perhaps this will work (untested):

  module = inspect.getmodule(frame[0])
+ if module is None:
+     module = __import__(frame[0])
schperplata

schperplata commented on Aug 31, 2020

@schperplata

Maybe this issue should be transfered here?

nicoddemus

nicoddemus commented on Aug 31, 2020

@nicoddemus
MemberAuthor

Thanks @schperplata, but it seems that's a different issue however (I replied there).

graingert

graingert commented on Sep 1, 2020

@graingert
Member

refs: pytest-dev/py#203 (comment)

for me relative imports are broken when using --import-mode=importlib https://github.com/graingert/relative-imports-import-mode-importlib/blob/default/tests/test_foo.py#L1

============================================================================================================================== test session starts ===============================================================================================================================
platform linux -- Python 3.8.2, pytest-6.0.1, py-1.9.0, pluggy-0.13.1
rootdir: /home/graingert/projects/relative-imports-import-mode-importlib, configfile: pytest.ini
plugins: forked-1.3.0, cov-2.9.0, xdist-1.34.0, case-1.5.3, timeout-1.4.2
collected 0 items / 1 error                                                                                                                                                                                                                                                      

===================================================================================================================================== ERRORS =====================================================================================================================================
_______________________________________________________________________________________________________________________ ERROR collecting tests/test_foo.py _______________________________________________________________________________________________________________________
ImportError while importing test module '/home/graingert/projects/relative-imports-import-mode-importlib/tests/test_foo.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
tests/test_foo.py:1: in <module>
    from . import utils
E   ImportError: attempted relative import with no known parent package

when doing inline tests, I often use relative imports:

https://github.com/graingert/relative-imports-import-mode-importlib/blob/default/graingertspkg/tests/test_business_logic.py#L1

ImportError while importing test module '/home/graingert/projects/relative-imports-import-mode-importlib/graingertspkg/tests/test_business_logic.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
graingertspkg/tests/test_business_logic.py:1: in <module>
    from .. import business_logic
E   ImportError: attempted relative import with no known parent package

nicoddemus

nicoddemus commented on Sep 1, 2020

@nicoddemus
MemberAuthor

for me relative imports are broken

Not sure they are broken, imports using importlib by design won't add modules to sys.modules or change sys.path, which explains why it doesn't work for your use case.

This however brings an important point, that importlib is not recommended for tests included with package code if one wants to use relative imports.

We should consider that as documentation, and also weight this use case in an eventual future decision of changing the default --importmode.

76 remaining items

Loading
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

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @brettcannon@graingert@The-Compiler@nicoddemus@asottile

        Issue actions

          Feedback about --import-mode=importlib in pytest 6.0 · Issue #7245 · pytest-dev/pytest