pallets / flask

The Python micro framework for building web applications.
https://flask.palletsprojects.com
BSD 3-Clause "New" or "Revised" License
67.84k stars 16.2k forks source link

test_instance_config.py fails #3151

Closed vedantroy closed 5 years ago

vedantroy commented 5 years ago

Expected Behavior

The following set of commands should result in all tests being passed or skipped (no failures).

git clone https://github.com/pallets/flask
cd flask
python3 -m venv env
. env/bin/activate
pip install -e ".[dev]"
pip install pytest

Actual Behavior

I get the following failures:

=================================== FAILURES ===================================
____________________________ test_main_module_paths ____________________________

modules_tmpdir = local('/tmp/pytest-of-vedantroy/pytest-5/test_main_module_paths0/modules_tmpdir')
purge_module = <function purge_module.<locals>.inner at 0x7fdb8852a268>

    def test_main_module_paths(modules_tmpdir, purge_module):
        app = modules_tmpdir.join('main_app.py')
        app.write('import flask\n\napp = flask.Flask("__main__")')
        purge_module('main_app')

>       from main_app import app
E       ModuleNotFoundError: No module named 'main_app'

tests/test_instance_config.py:32: ModuleNotFoundError
________________________ test_uninstalled_package_paths ________________________

modules_tmpdir = local('/tmp/pytest-of-vedantroy/pytest-5/test_uninstalled_package_paths0/modules_tmpdir')
purge_module = <function purge_module.<locals>.inner at 0x7fdb88548f28>

    def test_uninstalled_package_paths(modules_tmpdir, purge_module):
        app = modules_tmpdir.mkdir('config_package_app')
        init = app.join('__init__.py')
        init.write(
            'import os\n'
            'import flask\n'
            'here = os.path.abspath(os.path.dirname(__file__))\n'
            'app = flask.Flask(__name__)\n'
        )
        purge_module('config_package_app')

>       from config_package_app import app
E       ModuleNotFoundError: No module named 'config_package_app'

tests/test_instance_config.py:61: ModuleNotFoundError
______________________ test_installed_module_paths[True] _______________________

modules_tmpdir = local('/tmp/pytest-of-vedantroy/pytest-5/test_installed_module_paths_Tr0/modules_tmpdir')
modules_tmpdir_prefix = local('/tmp/pytest-of-vedantroy/pytest-5/test_installed_module_paths_Tr0/modules_tmpdir')
purge_module = <function purge_module.<locals>.inner at 0x7fdb8852a268>
site_packages = local('/tmp/pytest-of-vedantroy/pytest-5/test_installed_module_paths_Tr0/modules_tmpdir/lib/python3.6/site-packages')
limit_loader = None

    def test_installed_module_paths(modules_tmpdir, modules_tmpdir_prefix,
                                    purge_module, site_packages, limit_loader):
        site_packages.join('site_app.py').write(
            'import flask\n'
            'app = flask.Flask(__name__)\n'
        )
        purge_module('site_app')

>       from site_app import app
E       ModuleNotFoundError: No module named 'site_app'

tests/test_instance_config.py:73: ModuleNotFoundError
______________________ test_installed_module_paths[False] ______________________

modules_tmpdir = local('/tmp/pytest-of-vedantroy/pytest-5/test_installed_module_paths_Fa0/modules_tmpdir')
modules_tmpdir_prefix = local('/tmp/pytest-of-vedantroy/pytest-5/test_installed_module_paths_Fa0/modules_tmpdir')
purge_module = <function purge_module.<locals>.inner at 0x7fdb884dd488>
site_packages = local('/tmp/pytest-of-vedantroy/pytest-5/test_installed_module_paths_Fa0/modules_tmpdir/lib/python3.6/site-packages')
limit_loader = None

    def test_installed_module_paths(modules_tmpdir, modules_tmpdir_prefix,
                                    purge_module, site_packages, limit_loader):
        site_packages.join('site_app.py').write(
            'import flask\n'
            'app = flask.Flask(__name__)\n'
        )
        purge_module('site_app')

>       from site_app import app
E       ModuleNotFoundError: No module named 'site_app'

tests/test_instance_config.py:73: ModuleNotFoundError
______________________ test_installed_package_paths[True] ______________________

limit_loader = None
modules_tmpdir = local('/tmp/pytest-of-vedantroy/pytest-5/test_installed_package_paths_T0/modules_tmpdir')
modules_tmpdir_prefix = local('/tmp/pytest-of-vedantroy/pytest-5/test_installed_package_paths_T0/modules_tmpdir')
purge_module = <function purge_module.<locals>.inner at 0x7fdb8850b950>
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7fdb884f5a90>

    def test_installed_package_paths(limit_loader, modules_tmpdir,
                                     modules_tmpdir_prefix, purge_module,
                                     monkeypatch):
        installed_path = modules_tmpdir.mkdir('path')
        monkeypatch.syspath_prepend(installed_path)

        app = installed_path.mkdir('installed_package')
        init = app.join('__init__.py')
        init.write('import flask\napp = flask.Flask(__name__)')
        purge_module('installed_package')

>       from installed_package import app
E       ModuleNotFoundError: No module named 'installed_package'

tests/test_instance_config.py:89: ModuleNotFoundError
_____________________ test_installed_package_paths[False] ______________________

limit_loader = None
modules_tmpdir = local('/tmp/pytest-of-vedantroy/pytest-5/test_installed_package_paths_F0/modules_tmpdir')
modules_tmpdir_prefix = local('/tmp/pytest-of-vedantroy/pytest-5/test_installed_package_paths_F0/modules_tmpdir')
purge_module = <function purge_module.<locals>.inner at 0x7fdb884dd488>
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7fdb8851b390>

    def test_installed_package_paths(limit_loader, modules_tmpdir,
                                     modules_tmpdir_prefix, purge_module,
                                     monkeypatch):
        installed_path = modules_tmpdir.mkdir('path')
        monkeypatch.syspath_prepend(installed_path)

        app = installed_path.mkdir('installed_package')
        init = app.join('__init__.py')
        init.write('import flask\napp = flask.Flask(__name__)')
        purge_module('installed_package')

>       from installed_package import app
E       ModuleNotFoundError: No module named 'installed_package'

tests/test_instance_config.py:89: ModuleNotFoundError
_______________________ test_prefix_package_paths[True] ________________________

limit_loader = None
modules_tmpdir = local('/tmp/pytest-of-vedantroy/pytest-5/test_prefix_package_paths_True0/modules_tmpdir')
modules_tmpdir_prefix = local('/tmp/pytest-of-vedantroy/pytest-5/test_prefix_package_paths_True0/modules_tmpdir')
purge_module = <function purge_module.<locals>.inner at 0x7fdb8850bc80>
site_packages = local('/tmp/pytest-of-vedantroy/pytest-5/test_prefix_package_paths_True0/modules_tmpdir/lib/python3.6/site-packages')

    def test_prefix_package_paths(limit_loader, modules_tmpdir,
                                  modules_tmpdir_prefix, purge_module,
                                  site_packages):
        app = site_packages.mkdir('site_package')
        init = app.join('__init__.py')
        init.write('import flask\napp = flask.Flask(__name__)')
        purge_module('site_package')

>       import site_package
E       ModuleNotFoundError: No module named 'site_package'

tests/test_instance_config.py:102: ModuleNotFoundError
_______________________ test_prefix_package_paths[False] _______________________

limit_loader = None
modules_tmpdir = local('/tmp/pytest-of-vedantroy/pytest-5/test_prefix_package_paths_Fals0/modules_tmpdir')
modules_tmpdir_prefix = local('/tmp/pytest-of-vedantroy/pytest-5/test_prefix_package_paths_Fals0/modules_tmpdir')
purge_module = <function purge_module.<locals>.inner at 0x7fdb8850bea0>
site_packages = local('/tmp/pytest-of-vedantroy/pytest-5/test_prefix_package_paths_Fals0/modules_tmpdir/lib/python3.6/site-packages')

    def test_prefix_package_paths(limit_loader, modules_tmpdir,
                                  modules_tmpdir_prefix, purge_module,
                                  site_packages):
        app = site_packages.mkdir('site_package')
        init = app.join('__init__.py')
        init.write('import flask\napp = flask.Flask(__name__)')
        purge_module('site_package')

>       import site_package
E       ModuleNotFoundError: No module named 'site_package'

tests/test_instance_config.py:102: ModuleNotFoundError
============== 8 failed, 492 passed, 13 skipped in 12.53 seconds ===============

Environment

Ubuntu 18 LTS. Here's the result of ls in the flask directory:

artwork           docs      Flask.egg-info  README.rst  tests
AUTHORS           env       LICENSE         scripts     tox.ini
CHANGES.rst       examples  Makefile        setup.cfg
CONTRIBUTING.rst  flask     MANIFEST.in     setup.py
davidism commented 5 years ago

This appears to be an issue with the upgrade from pytest 4.3.1 to 4.4.0. Downgrade and the tests pass.

@blueyed @nicoddemus I think the issue came from pytest-dev/pytest#4980 because the tests that are failing here use a fixture that uses monkeypatch.syspath_prepend, but I'm not clear what the change was or how to go about debugging or fixing it. Can you take a look?

blueyed commented 5 years ago

Does commenting https://github.com/pytest-dev/pytest/pull/4980/files#diff-1f034a0f101912ca729b09e39a3973bbR272 fix the tests then?

davidism commented 5 years ago

Yes, commenting out that line allows the tests to pass again.

blueyed commented 5 years ago

Hmm.. inside of tox it passes at least, right?

And with e.g. p -k test_main_module_paths it also passes sometimes for me?! (Python 3.7.3, pytest-4.4.1.dev15+gbc157417)

Will look into it later..

blueyed commented 5 years ago

This fixes it (for tests/test_instance_config.py::test_main_module_paths, but not all):

diff --git i/tests/test_instance_config.py w/tests/test_instance_config.py
index bc912c64..a7b66203 100644
--- i/tests/test_instance_config.py
+++ w/tests/test_instance_config.py
@@ -26,6 +26,8 @@ def test_explicit_instance_paths(modules_tmpdir):

 def test_main_module_paths(modules_tmpdir, purge_module):
     app = modules_tmpdir.join('main_app.py')
+    from importlib import invalidate_caches
+    invalidate_caches()
     app.write('import flask\n\napp = flask.Flask("__main__")')
     purge_module('main_app')

E.g. here it is also needed, likely due to some other fixture:

diff --git i/tests/test_instance_config.py w/tests/test_instance_config.py
index bc912c64..1f2be9ce 100644
--- i/tests/test_instance_config.py
+++ w/tests/test_instance_config.py
@@ -94,6 +94,8 @@ def test_installed_package_paths(limit_loader, modules_tmpdir,
 def test_prefix_package_paths(limit_loader, modules_tmpdir,
                               modules_tmpdir_prefix, purge_module,
                               site_packages):
+    from importlib import invalidate_caches
+    invalidate_caches()
     app = site_packages.mkdir('site_package')
     init = app.join('__init__.py')
     init.write('import flask\napp = flask.Flask(__name__)')
blueyed commented 5 years ago

invalidate_caches should be called in syspath_prepend also (only done with testdir.syspathinster)..

blueyed commented 5 years ago

https://github.com/pytest-dev/pytest/pull/5098 fixes it.