Skip to content

Unable to test a Flask app with default (rewritting) assertions #317

@pytestbot

Description

@pytestbot

Originally reported by: Sean Lynch (BitBucket: techniq, GitHub: techniq)


Due to how Flask determines it's instance_path (http://flask.pocoo.org/docs/config/#instance-folders), py.test will throw the following error on a simple test

Test

#!python

from flask import Flask

def test_example():
    app = Flask(__name__)
    assert True

Results / error

#!python

    def test_example():
>       app = Flask(__name__)

test_flask.py:5: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <flask.app.Flask object at 0x10fd1e810>, import_name = 'test_flask', static_path = None, static_url_path = None
static_folder = 'static', template_folder = 'templates', instance_path = None, instance_relative_config = False

    def __init__(self, import_name, static_path=None, static_url_path=None,
                 static_folder='static', template_folder='templates',
                 instance_path=None, instance_relative_config=False):
        _PackageBoundObject.__init__(self, import_name,
                                     template_folder=template_folder)
        if static_path is not None:
            from warnings import warn
            warn(DeprecationWarning('static_path is now called '
                                    'static_url_path'), stacklevel=2)
            static_url_path = static_path

        if static_url_path is not None:
            self.static_url_path = static_url_path
        if static_folder is not None:
            self.static_folder = static_folder
        if instance_path is None:
>           instance_path = self.auto_find_instance_path()

../../../.virtualenvs/pytest-flask/lib/python2.7/site-packages/flask/app.py:303: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <flask.app.Flask object at 0x10fd1e810>

    def auto_find_instance_path(self):
        """Tries to locate the instance path if it was not provided to the
            constructor of the application class.  It will basically calculate
            the path to a folder named ``instance`` next to your main file or
            the package.

            .. versionadded:: 0.8
            """
>       prefix, package_path = find_package(self.import_name)

../../../.virtualenvs/pytest-flask/lib/python2.7/site-packages/flask/app.py:608: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

import_name = 'test_flask'

    def find_package(import_name):
        """Finds a package and returns the prefix (or None if the package is
        not installed) as well as the folder that contains the package or
        module as a tuple.  The package path returned is the module that would
        have to be added to the pythonpath in order to make it possible to
        import the module.  The prefix is the path below which a UNIX like
        folder structure exists (lib, share etc.).
        """
        root_mod_name = import_name.split('.')[0]
        loader = pkgutil.get_loader(root_mod_name)
        if loader is None or import_name == '__main__':
            # import name is not found, or interactive/main module
            package_path = os.getcwd()
        else:
            # For .egg, zipimporter does not have get_filename until Python 2.7.
            if hasattr(loader, 'get_filename'):
                filename = loader.get_filename(root_mod_name)
            elif hasattr(loader, 'archive'):
                # zipimporter's loader.archive points to the .egg or .zip
                # archive filename is dropped in call to dirname below.
                filename = loader.archive
            else:
                # At least one loader is missing both get_filename and archive:
                # Google App Engine's HardenedModulesHook
                #
                # Fall back to imports.
                __import__(import_name)
                filename = sys.modules[import_name].__file__
            package_path = os.path.abspath(os.path.dirname(filename))
            # package_path ends with __init__.py for a package
>           if loader.is_package(root_mod_name):
E           AttributeError: 'AssertionRewritingHook' object has no attribute 'is_package'

The solution is simple (as outlined in the docs: http://pytest.org/latest/assert.html#advanced-assertion-introspection), pass assert=reinterp or assert=plain when running the test.

While not a major issue, it would be great if py.test could test a Flask app without needing to know this knowledge, either by gracefully degrading assertions from module rewriting to reinterp by default, or somehow fixing the root issue of module rewriting with what Flask expects.

Thoughts?


Metadata

Metadata

Assignees

No one assigned

    Labels

    type: bugproblem that needs to be addressed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions