Repository navigation
Jinja/Flask get_flashed_messages fails #82
Copy link
Copy link
Open
Description
Flask-Injector 0.14.0
Injector 0.20.1
Flask 2.1.3
Minimum reproducible example: https://gist.github.com/NoRePercussions/00a26a4d801a91b01a916f818dd27092
Summary
- Flask-Injector adds injection capabilities to Jinja templates
get_flashed_messagesfrom Flask gets a list of internal messages- While calling
get_flashed_messages, F-I attempts to inject:
> Providing {'with_categories': <class 'bool'>, 'category_filter': typing.Iterable[str]} for <function get_flashed_messages at 0x103838670>
>> Injector.get(<class 'bool'>, scope=<class 'injector.NoScope'>) using <injector.ClassProvider object at 0x107b89b20>
>> Creating <class 'bool'> object with {}
>> Providing {} for <slot wrapper '__init__' of 'object' objects>
>> -> False
[2023-07-12 17:35:53,377] ERROR in app: Exception on / [GET]
Traceback (most recent call last):
File "/Users/-/Projects/PycharmProjects/FlaskInjectorError/venv/lib/python3.9/site-packages/injector/__init__.py", line 637, in get_binding
return self._get_binding(interface, only_this_binder=is_scope or is_assisted_builder)
File "/Users/-/Projects/PycharmProjects/FlaskInjectorError/venv/lib/python3.9/site-packages/injector/__init__.py", line 631, in _get_binding
raise KeyError
KeyError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/-/Projects/PycharmProjects/FlaskInjectorError/venv/lib/python3.9/site-packages/flask/app.py", line 2073, in wsgi_app
response = self.full_dispatch_request()
File "/Users/-/Projects/PycharmProjects/FlaskInjectorError/venv/lib/python3.9/site-packages/flask/app.py", line 1519, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/-/Projects/PycharmProjects/FlaskInjectorError/venv/lib/python3.9/site-packages/flask/app.py", line 1517, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/-/Projects/PycharmProjects/FlaskInjectorError/venv/lib/python3.9/site-packages/flask/app.py", line 1503, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "/Users/-/Projects/PycharmProjects/FlaskInjectorError/app.py", line 8, in hello_world
return render_template("helloworld.html")
File "/Users/-/Projects/PycharmProjects/FlaskInjectorError/venv/lib/python3.9/site-packages/flask/templating.py", line 154, in render_template
return _render(
File "/Users/-/Projects/PycharmProjects/FlaskInjectorError/venv/lib/python3.9/site-packages/flask/templating.py", line 128, in _render
rv = template.render(context)
File "/Users/-/Projects/PycharmProjects/FlaskInjectorError/venv/lib/python3.9/site-packages/jinja2/environment.py", line 1301, in render
self.environment.handle_exception()
File "/Users/-/Projects/PycharmProjects/FlaskInjectorError/venv/lib/python3.9/site-packages/jinja2/environment.py", line 936, in handle_exception
raise rewrite_traceback_stack(source=source)
File "/Users/-/Projects/PycharmProjects/FlaskInjectorError/templates/helloworld.html", line 1, in top-level template code
<!DOCTYPE html>
File "/Users/-/Projects/PycharmProjects/FlaskInjectorError/venv/lib/python3.9/site-packages/flask_injector/__init__.py", line 89, in wrapper
return injector.call_with_injection(callable=fun, args=args, kwargs=kwargs)
File "/Users/-/Projects/PycharmProjects/FlaskInjectorError/venv/lib/python3.9/site-packages/injector/__init__.py", line 999, in call_with_injection
dependencies = self.args_to_inject(
File "/Users/-/Projects/PycharmProjects/FlaskInjectorError/venv/lib/python3.9/site-packages/injector/__init__.py", line 91, in wrapper
return function(*args, **kwargs)
File "/Users/-/Projects/PycharmProjects/FlaskInjectorError/venv/lib/python3.9/site-packages/injector/__init__.py", line 1047, in args_to_inject
instance: Any = self.get(interface)
File "/Users/-/Projects/PycharmProjects/FlaskInjectorError/venv/lib/python3.9/site-packages/injector/__init__.py", line 932, in get
binding, binder = self.binder.get_binding(interface)
File "/Users/-/Projects/PycharmProjects/FlaskInjectorError/venv/lib/python3.9/site-packages/injector/__init__.py", line 646, in get_binding
binding = self.create_binding(interface)
File "/Users/-/Projects/PycharmProjects/FlaskInjectorError/venv/lib/python3.9/site-packages/injector/__init__.py", line 560, in create_binding
provider = self.provider_for(interface, to)
File "/Users/-/Projects/PycharmProjects/FlaskInjectorError/venv/lib/python3.9/site-packages/injector/__init__.py", line 622, in provider_for
raise UnknownProvider('couldn\'t determine provider for %r to %r' % (interface, to))
injector.UnknownProvider: couldn't determine provider for typing.Iterable[str] to None
Other concerns
- Jinja's error trace appears to not identify the right error location?
- F-I's injection appears to be blindly applied to all methods I call in Jinja, regardless of whether I want injection on them
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
NoRePercussions commentedon Jul 12, 2023
If I disable
auto_bind:However, the app runs fine if Flask-Injector is not installed.
So far I haven't found any other methods in my actual web app with this issue.
olehkodak commentedon Aug 11, 2023
It's because:
Flask-Injector lets you inject dependencies into Jinja environment globals functions
(And I would even say it obliges them to be introduced into the Standard Context.)
and,
The following global variables are available within Jinja2 templates by default in the Standard Context
(by the way, the "url_for()" is there, too)
So,
Or, the best solution, in my opinion:
I can't imagine a single use case where dependencies must be injected into the Standard template context. It's annoying and painful.
jstasiak commentedon Sep 5, 2023
I think the conclusion here would be the "inject in many places even if they don't declare they need injection" aspect of Flask-Injector's behavior is problematic.
It'd be a breaking change but I'm open to changing that.