Skip to content

The template_filter decorator doesn't work if you don't pass an argument #5729

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
alexwlchan opened this issue May 12, 2025 · 8 comments · May be fixed by #5735 or #5736
Open

The template_filter decorator doesn't work if you don't pass an argument #5729

alexwlchan opened this issue May 12, 2025 · 8 comments · May be fixed by #5735 or #5736

Comments

@alexwlchan
Copy link
Contributor

What's the issue?

You can use template_filter as a decorator, but it only registers the filter if you write an explicit name or an empty set of parentheses. If you call it without parens, the filter doesn't get registered.

It's a small difference and can be confusing.

Minimal example

Consider the following program:

from flask import Flask, render_template_string


app = Flask(__name__)


@app.template_filter
def double(x):
    return x * 2


@app.route("/")
def index():
    return render_template_string("2 times 2 is {{ 2 | double }}")

If you run this app (flask run --port 8008 --debug) and then open it in your browser (http://localhost:8008) you'll get an error:

jinja2.exceptions.TemplateAssertionError: No filter named 'double'.

This is confusing, and it took me a while to realise the missing parentheses in app.template_filter were at fault.

Suggested fix

I think it would be helpful if the decorator either:

  • Supported being called without parentheses, or
  • Printed an explicit warning if called this way, e.g. Did you use 'template_filter' as a decorator without parentheses? You need to call it with 'template_filter()'

This is caught by type checkers, but not everybody type checks their Python and the error message is less obvious:

Argument 1 to "template_filter" of "App" has incompatible type "Callable[[Any], Any]"; expected "str | None"

I've had a look at the relevant code, and I'd be happy to provide a patch if you think this is a useful change.

Environment

  • Python version: Python 3.11.11
  • Flask version: Flask 3.1.0
@kadai0308

This comment has been minimized.

@Gable-github

This comment has been minimized.

@ThiefMaster

This comment has been minimized.

@kadai0308

This comment has been minimized.

@kadai0308 kadai0308 linked a pull request May 17, 2025 that will close this issue
4 tasks
@lekuG12

This comment has been minimized.

@ThiefMaster

This comment has been minimized.

@lekuG12

This comment has been minimized.

@davidism
Copy link
Member

davidism commented May 22, 2025

What is it about this that has attracted five completely new contributors who aren't reading the contributing guide:

Anyone is welcome to work on any open ticket in any project's issue tracker, without asking first. Before starting, check if anyone else is assigned to the issue, or if there are any linked open pull requests. Look through the issue for that information as well as discussion and other linked issues for context.

@pallets pallets locked as off-topic and limited conversation to collaborators May 22, 2025
ding-alex added a commit to ding-alex/flask that referenced this issue May 22, 2025
This fixes an issue where template decorators like @app.template_filter
don't work when used without parentheses. The fix allows the decorators
to be used in both ways:

- @app.template_filter
- @app.template_filter()

The following decorators have been fixed:
- template_filter, template_test, template_global in Flask
- app_template_filter, app_template_test, app_template_global in Blueprint

Fixes pallets#5729
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.