Merge branch 'master' of git://github.com/mitsuhiko/flask
This commit is contained in:
commit
048b3008ba
11 changed files with 141 additions and 30 deletions
13
CHANGES
13
CHANGES
|
|
@ -23,11 +23,15 @@ Release date to be announced, codename to be selected
|
||||||
1.0 the old behaviour will continue to work but issue dependency
|
1.0 the old behaviour will continue to work but issue dependency
|
||||||
warnings.
|
warnings.
|
||||||
- fixed a problem for Flask to run on jython.
|
- fixed a problem for Flask to run on jython.
|
||||||
|
- added a `PROPAGATE_EXCEPTIONS` configuration variable that can be
|
||||||
|
used to flip the setting of exception propagation which previously
|
||||||
|
was linked to `DEBUG` alone and is now linked to either `DEBUG` or
|
||||||
|
`TESTING`.
|
||||||
|
|
||||||
Version 0.6.1
|
Version 0.6.1
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
Bugfix release, release date to be announced.
|
Bugfix release, released on December 31st 2010
|
||||||
|
|
||||||
- Fixed an issue where the default `OPTIONS` response was
|
- Fixed an issue where the default `OPTIONS` response was
|
||||||
not exposing all valid methods in the `Allow` header.
|
not exposing all valid methods in the `Allow` header.
|
||||||
|
|
@ -36,6 +40,9 @@ Bugfix release, release date to be announced.
|
||||||
module setups.
|
module setups.
|
||||||
- Fixed an issue where the subdomain setting for modules was
|
- Fixed an issue where the subdomain setting for modules was
|
||||||
ignored for the static folder.
|
ignored for the static folder.
|
||||||
|
- Fixed a security problem that allowed clients to download arbitrary files
|
||||||
|
if the host server was a windows based operating system and the client
|
||||||
|
uses backslashes to escape the directory the files where exposed from.
|
||||||
|
|
||||||
Version 0.6
|
Version 0.6
|
||||||
-----------
|
-----------
|
||||||
|
|
@ -45,7 +52,7 @@ Released on July 27th 2010, codename Whisky
|
||||||
- after request functions are now called in reverse order of
|
- after request functions are now called in reverse order of
|
||||||
registration.
|
registration.
|
||||||
- OPTIONS is now automatically implemented by Flask unless the
|
- OPTIONS is now automatically implemented by Flask unless the
|
||||||
application explictly adds 'OPTIONS' as method to the URL rule.
|
application explicitly adds 'OPTIONS' as method to the URL rule.
|
||||||
In this case no automatic OPTIONS handling kicks in.
|
In this case no automatic OPTIONS handling kicks in.
|
||||||
- static rules are now even in place if there is no static folder
|
- static rules are now even in place if there is no static folder
|
||||||
for the module. This was implemented to aid GAE which will
|
for the module. This was implemented to aid GAE which will
|
||||||
|
|
@ -65,7 +72,7 @@ Released on July 27th 2010, codename Whisky
|
||||||
- added signalling support based on blinker. This feature is currently
|
- added signalling support based on blinker. This feature is currently
|
||||||
optional and supposed to be used by extensions and applications. If
|
optional and supposed to be used by extensions and applications. If
|
||||||
you want to use it, make sure to have `blinker`_ installed.
|
you want to use it, make sure to have `blinker`_ installed.
|
||||||
- refactored the way url adapters are created. This process is now
|
- refactored the way URL adapters are created. This process is now
|
||||||
fully customizable with the :meth:`~flask.Flask.create_url_adapter`
|
fully customizable with the :meth:`~flask.Flask.create_url_adapter`
|
||||||
method.
|
method.
|
||||||
- modules can now register for a subdomain instead of just an URL
|
- modules can now register for a subdomain instead of just an URL
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,11 @@ The following configuration values are used internally by Flask:
|
||||||
=============================== =========================================
|
=============================== =========================================
|
||||||
``DEBUG`` enable/disable debug mode
|
``DEBUG`` enable/disable debug mode
|
||||||
``TESTING`` enable/disable testing mode
|
``TESTING`` enable/disable testing mode
|
||||||
|
``PROPAGATE_EXCEPTIONS`` explicitly enable or disable the
|
||||||
|
propagation of exceptions. If not set or
|
||||||
|
explicitly set to `None` this is
|
||||||
|
implicitly true if either `TESTING` or
|
||||||
|
`DEBUG` is true.
|
||||||
``SECRET_KEY`` the secret key
|
``SECRET_KEY`` the secret key
|
||||||
``SESSION_COOKIE_NAME`` the name of the session cookie
|
``SESSION_COOKIE_NAME`` the name of the session cookie
|
||||||
``PERMANENT_SESSION_LIFETIME`` the lifetime of a permanent session as
|
``PERMANENT_SESSION_LIFETIME`` the lifetime of a permanent session as
|
||||||
|
|
@ -96,6 +101,9 @@ The following configuration values are used internally by Flask:
|
||||||
.. versionadded:: 0.6
|
.. versionadded:: 0.6
|
||||||
``MAX_CONTENT_LENGTH``
|
``MAX_CONTENT_LENGTH``
|
||||||
|
|
||||||
|
.. versionadded:: 0.7
|
||||||
|
``PROPAGATE_EXCEPTIONS``
|
||||||
|
|
||||||
Configuring from Files
|
Configuring from Files
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -106,4 +106,4 @@ Werkzeug and Flask will be ported to Python 3 as soon as a solution for
|
||||||
WSGI is found, and we will provide helpful tips how to upgrade existing
|
WSGI is found, and we will provide helpful tips how to upgrade existing
|
||||||
applications to Python 3. Until then, we strongly recommend using Python
|
applications to Python 3. Until then, we strongly recommend using Python
|
||||||
2.6 and 2.7 with activated Python 3 warnings during development, as well
|
2.6 and 2.7 with activated Python 3 warnings during development, as well
|
||||||
as the unicode literals `__future__` feature.
|
as the Unicode literals `__future__` feature.
|
||||||
|
|
|
||||||
|
|
@ -81,16 +81,23 @@ context are appended to it.
|
||||||
Additionally there is a convenient helper method
|
Additionally there is a convenient helper method
|
||||||
(:meth:`~blinker.base.Signal.connected_to`). that allows you to
|
(:meth:`~blinker.base.Signal.connected_to`). that allows you to
|
||||||
temporarily subscribe a function to a signal with is a context manager on
|
temporarily subscribe a function to a signal with is a context manager on
|
||||||
its own which simplifies the example above::
|
its own. Because the return value of the context manager cannot be
|
||||||
|
specified that way one has to pass the list in as argument::
|
||||||
|
|
||||||
from flask import template_rendered
|
from flask import template_rendered
|
||||||
|
|
||||||
def captured_templates(app):
|
def captured_templates(app, recorded):
|
||||||
recorded = []
|
|
||||||
def record(sender, template, context):
|
def record(sender, template, context):
|
||||||
recorded.append((template, context))
|
recorded.append((template, context))
|
||||||
return template_rendered.connected_to(record, app)
|
return template_rendered.connected_to(record, app)
|
||||||
|
|
||||||
|
The example above would then look like this::
|
||||||
|
|
||||||
|
templates = []
|
||||||
|
with captured_templates(app, templates):
|
||||||
|
...
|
||||||
|
template, context = templates[0]
|
||||||
|
|
||||||
.. admonition:: Blinker API Changes
|
.. admonition:: Blinker API Changes
|
||||||
|
|
||||||
The :meth:`~blinker.base.Signal.connected_to` method arrived in Blinker
|
The :meth:`~blinker.base.Signal.connected_to` method arrived in Blinker
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,23 @@
|
||||||
Unicode in Flask
|
Unicode in Flask
|
||||||
================
|
================
|
||||||
|
|
||||||
Flask like Jinja2 and Werkzeug is totally unicode based when it comes to
|
Flask like Jinja2 and Werkzeug is totally Unicode based when it comes to
|
||||||
text. Not only these libraries, also the majority of web related Python
|
text. Not only these libraries, also the majority of web related Python
|
||||||
libraries that deal with text. If you don't know unicode so far, you
|
libraries that deal with text. If you don't know Unicode so far, you
|
||||||
should probably read `The Absolute Minimum Every Software Developer
|
should probably read `The Absolute Minimum Every Software Developer
|
||||||
Absolutely, Positively Must Know About Unicode and Character Sets
|
Absolutely, Positively Must Know About Unicode and Character Sets
|
||||||
<http://www.joelonsoftware.com/articles/Unicode.html>`_. This part of the
|
<http://www.joelonsoftware.com/articles/Unicode.html>`_. This part of the
|
||||||
documentation just tries to cover the very basics so that you have a
|
documentation just tries to cover the very basics so that you have a
|
||||||
pleasant experience with unicode related things.
|
pleasant experience with Unicode related things.
|
||||||
|
|
||||||
Automatic Conversion
|
Automatic Conversion
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
Flask has a few assumptions about your application (which you can change
|
Flask has a few assumptions about your application (which you can change
|
||||||
of course) that give you basic and painless unicode support:
|
of course) that give you basic and painless Unicode support:
|
||||||
|
|
||||||
- the encoding for text on your website is UTF-8
|
- the encoding for text on your website is UTF-8
|
||||||
- internally you will always use unicode exclusively for text except
|
- internally you will always use Unicode exclusively for text except
|
||||||
for literal strings with only ASCII character points.
|
for literal strings with only ASCII character points.
|
||||||
- encoding and decoding happens whenever you are talking over a protocol
|
- encoding and decoding happens whenever you are talking over a protocol
|
||||||
that requires bytes to be transmitted.
|
that requires bytes to be transmitted.
|
||||||
|
|
@ -29,27 +29,27 @@ address documents on servers (so called URIs or URLs). However HTML which
|
||||||
is usually transmitted on top of HTTP supports a large variety of
|
is usually transmitted on top of HTTP supports a large variety of
|
||||||
character sets and which ones are used, are transmitted in an HTTP header.
|
character sets and which ones are used, are transmitted in an HTTP header.
|
||||||
To not make this too complex Flask just assumes that if you are sending
|
To not make this too complex Flask just assumes that if you are sending
|
||||||
unicode out you want it to be UTF-8 encoded. Flask will do the encoding
|
Unicode out you want it to be UTF-8 encoded. Flask will do the encoding
|
||||||
and setting of the appropriate headers for you.
|
and setting of the appropriate headers for you.
|
||||||
|
|
||||||
The same is true if you are talking to databases with the help of
|
The same is true if you are talking to databases with the help of
|
||||||
SQLAlchemy or a similar ORM system. Some databases have a protocol that
|
SQLAlchemy or a similar ORM system. Some databases have a protocol that
|
||||||
already transmits unicode and if they do not, SQLAlchemy or your other ORM
|
already transmits Unicode and if they do not, SQLAlchemy or your other ORM
|
||||||
should take care of that.
|
should take care of that.
|
||||||
|
|
||||||
The Golden Rule
|
The Golden Rule
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
So the rule of thumb: if you are not dealing with binary data, work with
|
So the rule of thumb: if you are not dealing with binary data, work with
|
||||||
unicode. What does working with unicode in Python 2.x mean?
|
Unicode. What does working with Unicode in Python 2.x mean?
|
||||||
|
|
||||||
- as long as you are using ASCII charpoints only (basically numbers,
|
- as long as you are using ASCII charpoints only (basically numbers,
|
||||||
some special characters of latin letters without umlauts or anything
|
some special characters of latin letters without umlauts or anything
|
||||||
fancy) you can use regular string literals (``'Hello World'``).
|
fancy) you can use regular string literals (``'Hello World'``).
|
||||||
- if you need anything else than ASCII in a string you have to mark
|
- if you need anything else than ASCII in a string you have to mark
|
||||||
this string as unicode string by prefixing it with a lowercase `u`.
|
this string as Unicode string by prefixing it with a lowercase `u`.
|
||||||
(like ``u'Hänsel und Gretel'``)
|
(like ``u'Hänsel und Gretel'``)
|
||||||
- if you are using non-unicode characters in your Python files you have
|
- if you are using non-Unicode characters in your Python files you have
|
||||||
to tell Python which encoding your file uses. Again, I recommend
|
to tell Python which encoding your file uses. Again, I recommend
|
||||||
UTF-8 for this purpose. To tell the interpreter your encoding you can
|
UTF-8 for this purpose. To tell the interpreter your encoding you can
|
||||||
put the ``# -*- coding: utf-8 -*-`` into the first or second line of
|
put the ``# -*- coding: utf-8 -*-`` into the first or second line of
|
||||||
|
|
@ -61,21 +61,21 @@ Encoding and Decoding Yourself
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
||||||
If you are talking with a filesystem or something that is not really based
|
If you are talking with a filesystem or something that is not really based
|
||||||
on unicode you will have to ensure that you decode properly when working
|
on Unicode you will have to ensure that you decode properly when working
|
||||||
with unicode interface. So for example if you want to load a file on the
|
with Unicode interface. So for example if you want to load a file on the
|
||||||
filesystem and embed it into a Jinja2 template you will have to decode it
|
filesystem and embed it into a Jinja2 template you will have to decode it
|
||||||
from the encoding of that file. Here the old problem that text files do
|
from the encoding of that file. Here the old problem that text files do
|
||||||
not specify their encoding comes into play. So do yourself a favour and
|
not specify their encoding comes into play. So do yourself a favour and
|
||||||
limit yourself to UTF-8 for text files as well.
|
limit yourself to UTF-8 for text files as well.
|
||||||
|
|
||||||
Anyways. To load such a file with unicode you can use the built-in
|
Anyways. To load such a file with Unicode you can use the built-in
|
||||||
:meth:`str.decode` method::
|
:meth:`str.decode` method::
|
||||||
|
|
||||||
def read_file(filename, charset='utf-8'):
|
def read_file(filename, charset='utf-8'):
|
||||||
with open(filename, 'r') as f:
|
with open(filename, 'r') as f:
|
||||||
return f.read().decode(charset)
|
return f.read().decode(charset)
|
||||||
|
|
||||||
To go from unicode into a specific charset such as UTF-8 you can use the
|
To go from Unicode into a specific charset such as UTF-8 you can use the
|
||||||
:meth:`unicode.encode` method::
|
:meth:`unicode.encode` method::
|
||||||
|
|
||||||
def write_file(filename, contents, charset='utf-8'):
|
def write_file(filename, contents, charset='utf-8'):
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
:license: BSD, see LICENSE for more details.
|
:license: BSD, see LICENSE for more details.
|
||||||
"""
|
"""
|
||||||
from __future__ import with_statement
|
from __future__ import with_statement
|
||||||
import sqlite3
|
from sqlite3 import dbapi2 as sqlite3
|
||||||
from contextlib import closing
|
from contextlib import closing
|
||||||
from flask import Flask, request, session, g, redirect, url_for, abort, \
|
from flask import Flask, request, session, g, redirect, url_for, abort, \
|
||||||
render_template, flash
|
render_template, flash
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
"""
|
"""
|
||||||
from __future__ import with_statement
|
from __future__ import with_statement
|
||||||
import time
|
import time
|
||||||
import sqlite3
|
from sqlite3 import dbapi2 as sqlite3
|
||||||
from hashlib import md5
|
from hashlib import md5
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from contextlib import closing
|
from contextlib import closing
|
||||||
|
|
|
||||||
33
flask/app.py
33
flask/app.py
|
|
@ -189,6 +189,7 @@ class Flask(_PackageBoundObject):
|
||||||
default_config = ImmutableDict({
|
default_config = ImmutableDict({
|
||||||
'DEBUG': False,
|
'DEBUG': False,
|
||||||
'TESTING': False,
|
'TESTING': False,
|
||||||
|
'PROPAGATE_EXCEPTIONS': None,
|
||||||
'SECRET_KEY': None,
|
'SECRET_KEY': None,
|
||||||
'SESSION_COOKIE_NAME': 'session',
|
'SESSION_COOKIE_NAME': 'session',
|
||||||
'PERMANENT_SESSION_LIFETIME': timedelta(days=31),
|
'PERMANENT_SESSION_LIFETIME': timedelta(days=31),
|
||||||
|
|
@ -198,6 +199,11 @@ class Flask(_PackageBoundObject):
|
||||||
'MAX_CONTENT_LENGTH': None
|
'MAX_CONTENT_LENGTH': None
|
||||||
})
|
})
|
||||||
|
|
||||||
|
#: the test client that is used with when `test_client` is used.
|
||||||
|
#:
|
||||||
|
#: .. versionadded:: 0.7
|
||||||
|
test_client_class = None
|
||||||
|
|
||||||
def __init__(self, import_name, static_path=None):
|
def __init__(self, import_name, static_path=None):
|
||||||
_PackageBoundObject.__init__(self, import_name)
|
_PackageBoundObject.__init__(self, import_name)
|
||||||
if static_path is not None:
|
if static_path is not None:
|
||||||
|
|
@ -303,6 +309,18 @@ class Flask(_PackageBoundObject):
|
||||||
self.jinja_env = self.create_jinja_environment()
|
self.jinja_env = self.create_jinja_environment()
|
||||||
self.init_jinja_globals()
|
self.init_jinja_globals()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def propagate_exceptions(self):
|
||||||
|
"""Returns the value of the `PROPAGATE_EXCEPTIONS` configuration
|
||||||
|
value in case it's set, otherwise a sensible default is returned.
|
||||||
|
|
||||||
|
.. versionadded:: 0.7
|
||||||
|
"""
|
||||||
|
rv = self.config['PROPAGATE_EXCEPTIONS']
|
||||||
|
if rv is not None:
|
||||||
|
return rv
|
||||||
|
return self.testing or self.debug
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def logger(self):
|
def logger(self):
|
||||||
"""A :class:`logging.Logger` object for this application. The
|
"""A :class:`logging.Logger` object for this application. The
|
||||||
|
|
@ -416,7 +434,7 @@ class Flask(_PackageBoundObject):
|
||||||
options.setdefault('use_debugger', self.debug)
|
options.setdefault('use_debugger', self.debug)
|
||||||
return run_simple(host, port, self, **options)
|
return run_simple(host, port, self, **options)
|
||||||
|
|
||||||
def test_client(self):
|
def test_client(self, use_cookies=True):
|
||||||
"""Creates a test client for this application. For information
|
"""Creates a test client for this application. For information
|
||||||
about unit testing head over to :ref:`testing`.
|
about unit testing head over to :ref:`testing`.
|
||||||
|
|
||||||
|
|
@ -430,9 +448,16 @@ class Flask(_PackageBoundObject):
|
||||||
|
|
||||||
.. versionchanged:: 0.4
|
.. versionchanged:: 0.4
|
||||||
added support for `with` block usage for the client.
|
added support for `with` block usage for the client.
|
||||||
|
|
||||||
|
.. versionadded:: 0.7
|
||||||
|
The `use_cookies` parameter was added as well as the ability
|
||||||
|
to override the client to be used by setting the
|
||||||
|
:attr:`test_client_class` attribute.
|
||||||
"""
|
"""
|
||||||
from flask.testing import FlaskClient
|
cls = self.test_client_class
|
||||||
return FlaskClient(self, self.response_class, use_cookies=True)
|
if cls is None:
|
||||||
|
from flask.testing import FlaskClient as cls
|
||||||
|
return cls(self, self.response_class, use_cookies=use_cookies)
|
||||||
|
|
||||||
def open_session(self, request):
|
def open_session(self, request):
|
||||||
"""Creates or opens a new session. Default implementation stores all
|
"""Creates or opens a new session. Default implementation stores all
|
||||||
|
|
@ -682,7 +707,7 @@ class Flask(_PackageBoundObject):
|
||||||
"""
|
"""
|
||||||
got_request_exception.send(self, exception=e)
|
got_request_exception.send(self, exception=e)
|
||||||
handler = self.error_handlers.get(500)
|
handler = self.error_handlers.get(500)
|
||||||
if self.debug:
|
if self.propagate_exceptions:
|
||||||
raise
|
raise
|
||||||
self.logger.exception('Exception on %s [%s]' % (
|
self.logger.exception('Exception on %s [%s]' % (
|
||||||
request.path,
|
request.path,
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,13 @@ else:
|
||||||
_tojson_filter = json.dumps
|
_tojson_filter = json.dumps
|
||||||
|
|
||||||
|
|
||||||
|
# what separators does this operating system provide that are not a slash?
|
||||||
|
# this is used by the send_from_directory function to ensure that nobody is
|
||||||
|
# able to access files from outside the filesystem.
|
||||||
|
_os_alt_seps = list(sep for sep in [os.path.sep, os.path.altsep]
|
||||||
|
if sep not in (None, '/'))
|
||||||
|
|
||||||
|
|
||||||
def _endpoint_from_view_func(view_func):
|
def _endpoint_from_view_func(view_func):
|
||||||
"""Internal helper that returns the default endpoint for a given
|
"""Internal helper that returns the default endpoint for a given
|
||||||
function. This always is the function name.
|
function. This always is the function name.
|
||||||
|
|
@ -413,7 +420,10 @@ def send_from_directory(directory, filename, **options):
|
||||||
forwarded to :func:`send_file`.
|
forwarded to :func:`send_file`.
|
||||||
"""
|
"""
|
||||||
filename = posixpath.normpath(filename)
|
filename = posixpath.normpath(filename)
|
||||||
if filename.startswith(('/', '../')):
|
for sep in _os_alt_seps:
|
||||||
|
if sep in filename:
|
||||||
|
raise NotFound()
|
||||||
|
if os.path.isabs(filename) or filename.startswith('../'):
|
||||||
raise NotFound()
|
raise NotFound()
|
||||||
filename = os.path.join(directory, filename)
|
filename = os.path.join(directory, filename)
|
||||||
if not os.path.isfile(filename):
|
if not os.path.isfile(filename):
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ def _register_module(module, static_path):
|
||||||
state.app.add_url_rule(path + '/<path:filename>',
|
state.app.add_url_rule(path + '/<path:filename>',
|
||||||
endpoint='%s.static' % module.name,
|
endpoint='%s.static' % module.name,
|
||||||
view_func=module.send_static_file,
|
view_func=module.send_static_file,
|
||||||
subdomain=module.subdomain)
|
subdomain=state.subdomain)
|
||||||
return _register
|
return _register
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import re
|
||||||
import sys
|
import sys
|
||||||
import flask
|
import flask
|
||||||
import unittest
|
import unittest
|
||||||
|
from threading import Thread
|
||||||
from logging import StreamHandler
|
from logging import StreamHandler
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
@ -28,6 +29,15 @@ sys.path.append(os.path.join(example_path, 'flaskr'))
|
||||||
sys.path.append(os.path.join(example_path, 'minitwit'))
|
sys.path.append(os.path.join(example_path, 'minitwit'))
|
||||||
|
|
||||||
|
|
||||||
|
def has_encoding(name):
|
||||||
|
try:
|
||||||
|
import codecs
|
||||||
|
codecs.lookup(name)
|
||||||
|
return True
|
||||||
|
except LookupError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
# config keys used for the ConfigTestCase
|
# config keys used for the ConfigTestCase
|
||||||
TEST_KEY = 'foo'
|
TEST_KEY = 'foo'
|
||||||
SECRET_KEY = 'devkey'
|
SECRET_KEY = 'devkey'
|
||||||
|
|
@ -547,7 +557,6 @@ class BasicFunctionalityTestCase(unittest.TestCase):
|
||||||
"No ValueError exception should have been raised \"%s\"" % e
|
"No ValueError exception should have been raised \"%s\"" % e
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_test_app_proper_environ(self):
|
def test_test_app_proper_environ(self):
|
||||||
app = flask.Flask(__name__)
|
app = flask.Flask(__name__)
|
||||||
app.config.update(
|
app.config.update(
|
||||||
|
|
@ -619,6 +628,33 @@ class BasicFunctionalityTestCase(unittest.TestCase):
|
||||||
"No ValueError exception should have been raised \"%s\"" % e
|
"No ValueError exception should have been raised \"%s\"" % e
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_exception_propagation(self):
|
||||||
|
def apprunner(configkey):
|
||||||
|
app = flask.Flask(__name__)
|
||||||
|
@app.route('/')
|
||||||
|
def index():
|
||||||
|
1/0
|
||||||
|
c = app.test_client()
|
||||||
|
if config_key is not None:
|
||||||
|
app.config[config_key] = True
|
||||||
|
try:
|
||||||
|
resp = c.get('/')
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
self.fail('expected exception')
|
||||||
|
else:
|
||||||
|
assert c.get('/').status_code == 500
|
||||||
|
|
||||||
|
# we have to run this test in an isolated thread because if the
|
||||||
|
# debug flag is set to true and an exception happens the context is
|
||||||
|
# not torn down. This causes other tests that run after this fail
|
||||||
|
# when they expect no exception on the stack.
|
||||||
|
for config_key in 'TESTING', 'PROPAGATE_EXCEPTIONS', 'DEBUG', None:
|
||||||
|
t = Thread(target=apprunner, args=(config_key,))
|
||||||
|
t.start()
|
||||||
|
t.join()
|
||||||
|
|
||||||
|
|
||||||
class JSONTestCase(unittest.TestCase):
|
class JSONTestCase(unittest.TestCase):
|
||||||
|
|
||||||
|
|
@ -671,6 +707,9 @@ class JSONTestCase(unittest.TestCase):
|
||||||
assert rv.status_code == 200
|
assert rv.status_code == 200
|
||||||
assert rv.data == u'정상처리'.encode('utf-8')
|
assert rv.data == u'정상처리'.encode('utf-8')
|
||||||
|
|
||||||
|
if not has_encoding('euc-kr'):
|
||||||
|
test_modified_url_encoding = None
|
||||||
|
|
||||||
|
|
||||||
class TemplatingTestCase(unittest.TestCase):
|
class TemplatingTestCase(unittest.TestCase):
|
||||||
|
|
||||||
|
|
@ -957,6 +996,21 @@ class ModuleTestCase(unittest.TestCase):
|
||||||
else:
|
else:
|
||||||
assert 0, 'expected exception'
|
assert 0, 'expected exception'
|
||||||
|
|
||||||
|
# testcase for a security issue that may exist on windows systems
|
||||||
|
import os
|
||||||
|
import ntpath
|
||||||
|
old_path = os.path
|
||||||
|
os.path = ntpath
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
f('..\\__init__.py')
|
||||||
|
except NotFound:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
assert 0, 'expected exception'
|
||||||
|
finally:
|
||||||
|
os.path = old_path
|
||||||
|
|
||||||
|
|
||||||
class SendfileTestCase(unittest.TestCase):
|
class SendfileTestCase(unittest.TestCase):
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue