mirror of https://github.com/pallets/flask.git
Fixes for PEP451 import loaders and pytest 5.x
- pytest 5.x drops python2 compatibility and therefore only implements PEP 451 - pytest 5.x made the repr of `ExcInfo` less confusing (fixed tests depending on the old format)
This commit is contained in:
parent
b9c2267272
commit
a5ecdfa7a5
|
@ -10,6 +10,7 @@ Unreleased
|
|||
requires upgrading to Werkzeug 0.15.5. :issue:`3249`
|
||||
- ``send_file`` url quotes the ":" and "/" characters for more
|
||||
compatible UTF-8 filename support in some browsers. :issue:`3074`
|
||||
- Fixes for PEP451 import loaders and pytest 5.x. :issue:`3275`
|
||||
|
||||
|
||||
Version 1.0.3
|
||||
|
|
|
@ -188,7 +188,7 @@ should be closed.
|
|||
with pytest.raises(sqlite3.ProgrammingError) as e:
|
||||
db.execute('SELECT 1')
|
||||
|
||||
assert 'closed' in str(e)
|
||||
assert 'closed' in str(e.value)
|
||||
|
||||
The ``init-db`` command should call the ``init_db`` function and output
|
||||
a message.
|
||||
|
|
|
@ -12,7 +12,7 @@ def test_get_close_db(app):
|
|||
with pytest.raises(sqlite3.ProgrammingError) as e:
|
||||
db.execute('SELECT 1')
|
||||
|
||||
assert 'closed' in str(e)
|
||||
assert 'closed' in str(e.value)
|
||||
|
||||
|
||||
def test_init_db_command(runner, monkeypatch):
|
||||
|
|
|
@ -789,19 +789,38 @@ def _matching_loader_thinks_module_is_package(loader, mod_name):
|
|||
loader.__class__.__name__)
|
||||
|
||||
|
||||
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]
|
||||
def _find_package_path(root_mod_name):
|
||||
"""Find the path where the module's root exists in"""
|
||||
if sys.version_info >= (3, 4):
|
||||
import importlib.util
|
||||
|
||||
try:
|
||||
spec = importlib.util.find_spec(root_mod_name)
|
||||
if spec is None:
|
||||
raise ValueError("not found")
|
||||
# ImportError: the machinery told us it does not exist
|
||||
# ValueError:
|
||||
# - the module name was invalid
|
||||
# - the module name is __main__
|
||||
# - *we* raised `ValueError` due to `spec` being `None`
|
||||
except (ImportError, ValueError):
|
||||
pass # handled below
|
||||
else:
|
||||
# namespace package
|
||||
if spec.origin in {"namespace", None}:
|
||||
return os.path.dirname(next(iter(spec.submodule_search_locations)))
|
||||
# a package (with __init__.py)
|
||||
elif spec.submodule_search_locations:
|
||||
return os.path.dirname(os.path.dirname(spec.origin))
|
||||
# just a normal module
|
||||
else:
|
||||
return os.path.dirname(spec.origin)
|
||||
|
||||
# we were unable to find the `package_path` using PEP 451 loaders
|
||||
loader = pkgutil.get_loader(root_mod_name)
|
||||
if loader is None or import_name == '__main__':
|
||||
if loader is None or root_mod_name == '__main__':
|
||||
# import name is not found, or interactive/main module
|
||||
package_path = os.getcwd()
|
||||
return os.getcwd()
|
||||
else:
|
||||
# For .egg, zipimporter does not have get_filename until Python 2.7.
|
||||
if hasattr(loader, 'get_filename'):
|
||||
|
@ -815,17 +834,29 @@ def find_package(import_name):
|
|||
# Google App Engine's HardenedModulesHook
|
||||
#
|
||||
# Fall back to imports.
|
||||
__import__(import_name)
|
||||
filename = sys.modules[import_name].__file__
|
||||
__import__(root_mod_name)
|
||||
filename = sys.modules[root_mod_name].__file__
|
||||
package_path = os.path.abspath(os.path.dirname(filename))
|
||||
|
||||
# In case the root module is a package we need to chop of the
|
||||
# rightmost part. This needs to go through a helper function
|
||||
# because of python 3.3 namespace packages.
|
||||
if _matching_loader_thinks_module_is_package(
|
||||
loader, root_mod_name):
|
||||
if _matching_loader_thinks_module_is_package(loader, root_mod_name):
|
||||
package_path = os.path.dirname(package_path)
|
||||
|
||||
return package_path
|
||||
|
||||
|
||||
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.partition('.')
|
||||
package_path = _find_package_path(root_mod_name)
|
||||
site_parent, site_folder = os.path.split(package_path)
|
||||
py_prefix = os.path.abspath(sys.prefix)
|
||||
if package_path.startswith(py_prefix):
|
||||
|
|
|
@ -1219,17 +1219,17 @@ def test_response_type_errors():
|
|||
|
||||
with pytest.raises(TypeError) as e:
|
||||
c.get('/none')
|
||||
assert 'returned None' in str(e)
|
||||
assert 'returned None' in str(e.value)
|
||||
|
||||
with pytest.raises(TypeError) as e:
|
||||
c.get('/small_tuple')
|
||||
assert 'tuple must have the form' in str(e)
|
||||
assert 'tuple must have the form' in str(e.value)
|
||||
|
||||
pytest.raises(TypeError, c.get, '/large_tuple')
|
||||
|
||||
with pytest.raises(TypeError) as e:
|
||||
c.get('/bad_type')
|
||||
assert 'it was a bool' in str(e)
|
||||
assert 'it was a bool' in str(e.value)
|
||||
|
||||
pytest.raises(TypeError, c.get, '/bad_wsgi')
|
||||
|
||||
|
@ -1622,7 +1622,7 @@ def test_debug_mode_complains_after_first_request(app, client):
|
|||
@app.route('/foo')
|
||||
def broken():
|
||||
return 'Meh'
|
||||
assert 'A setup function was called' in str(e)
|
||||
assert 'A setup function was called' in str(e.value)
|
||||
|
||||
app.debug = False
|
||||
|
||||
|
@ -1677,9 +1677,9 @@ def test_routing_redirect_debugging(app, client):
|
|||
with client:
|
||||
with pytest.raises(AssertionError) as e:
|
||||
client.post('/foo', data={})
|
||||
assert 'http://localhost/foo/' in str(e)
|
||||
assert 'http://localhost/foo/' in str(e.value)
|
||||
assert ('Make sure to directly send '
|
||||
'your POST-request to this URL') in str(e)
|
||||
'your POST-request to this URL') in str(e.value)
|
||||
|
||||
rv = client.get('/foo', data={}, follow_redirects=True)
|
||||
assert rv.data == b'success'
|
||||
|
|
|
@ -468,8 +468,8 @@ class TestSendfile(object):
|
|||
def test_send_file_object_without_mimetype(self, app, req_ctx):
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
flask.send_file(StringIO("LOL"))
|
||||
assert 'Unable to infer MIME-type' in str(excinfo)
|
||||
assert 'no filename is available' in str(excinfo)
|
||||
assert 'Unable to infer MIME-type' in str(excinfo.value)
|
||||
assert 'no filename is available' in str(excinfo.value)
|
||||
|
||||
flask.send_file(StringIO("LOL"), attachment_filename='filename')
|
||||
|
||||
|
|
Loading…
Reference in New Issue