From f5b8c082847baa8a902cef22c43a5d50d7a55bdc Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Thu, 15 Jul 2010 14:35:02 +0200 Subject: [PATCH] endpoint is optional for modules. This fixes #86 --- flask/app.py | 6 ++---- flask/helpers.py | 9 +++++++++ flask/module.py | 15 ++++++++++++--- tests/flask_tests.py | 12 ++++++++++++ 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/flask/app.py b/flask/app.py index 415bf753..16da7939 100644 --- a/flask/app.py +++ b/flask/app.py @@ -23,7 +23,7 @@ from werkzeug.routing import Map, Rule from werkzeug.exceptions import HTTPException, InternalServerError, NotFound from .helpers import _PackageBoundObject, url_for, get_flashed_messages, \ - _tojson_filter + _tojson_filter, _endpoint_from_view_func from .wrappers import Request, Response from .config import ConfigAttribute, Config from .ctx import _RequestContext @@ -496,9 +496,7 @@ class Flask(_PackageBoundObject): added and handled by the standard request handling. """ if endpoint is None: - assert view_func is not None, 'expected view func if endpoint ' \ - 'is not provided.' - endpoint = view_func.__name__ + endpoint = _endpoint_from_view_func(view_func) options['endpoint'] = endpoint methods = options.pop('methods', ('GET',)) provide_automatic_options = False diff --git a/flask/helpers.py b/flask/helpers.py index d76090c4..fc309e67 100644 --- a/flask/helpers.py +++ b/flask/helpers.py @@ -59,6 +59,15 @@ else: _tojson_filter = json.dumps +def _endpoint_from_view_func(view_func): + """Internal helper that returns the default endpoint for a given + function. This always is the function name. + """ + assert view_func is not None, 'expected view func if endpoint ' \ + 'is not provided.' + return view_func.__name__ + + def jsonify(*args, **kwargs): """Creates a :class:`~flask.Response` with the JSON representation of the given arguments with an `application/json` mimetype. The arguments diff --git a/flask/module.py b/flask/module.py index 8935359e..9eaa4f82 100644 --- a/flask/module.py +++ b/flask/module.py @@ -9,7 +9,7 @@ :license: BSD, see LICENSE for more details. """ -from .helpers import _PackageBoundObject +from .helpers import _PackageBoundObject, _endpoint_from_view_func def _register_module(module, static_path): @@ -127,15 +127,24 @@ class Module(_PackageBoundObject): return f return decorator - def add_url_rule(self, rule, endpoint, view_func=None, **options): + def add_url_rule(self, rule, endpoint=None, view_func=None, **options): """Like :meth:`Flask.add_url_rule` but for a module. The endpoint for the :func:`url_for` function is prefixed with the name of the module. + + .. versionchanged:: 0.6 + The `endpoint` argument is now optional and will default to the + function name to consistent with the function of the same name + on the application object. """ def register_rule(state): the_rule = rule if state.url_prefix: the_rule = state.url_prefix + rule - state.app.add_url_rule(the_rule, '%s.%s' % (self.name, endpoint), + the_endpoint = endpoint + if the_endpoint is None: + the_endpoint = _endpoint_from_view_func(view_func) + state.app.add_url_rule(the_rule, '%s.%s' % (self.name, + the_endpoint), view_func, **options) self._record(register_rule) diff --git a/tests/flask_tests.py b/tests/flask_tests.py index b3b68b37..f2451223 100644 --- a/tests/flask_tests.py +++ b/tests/flask_tests.py @@ -612,6 +612,18 @@ class ModuleTestCase(unittest.TestCase): assert c.get('/admin/login').data == 'admin login' assert c.get('/admin/logout').data == 'admin logout' + def test_default_endpoint_name(self): + app = flask.Flask(__name__) + mod = flask.Module(__name__, 'frontend') + def index(): + return 'Awesome' + mod.add_url_rule('/', view_func=index) + app.register_module(mod) + rv = app.test_client().get('/') + assert rv.data == 'Awesome' + with app.test_request_context(): + assert flask.url_for('frontend.index') == '/' + def test_request_processing(self): catched = [] app = flask.Flask(__name__)