flask_injector
flask_injector copied to clipboard
Using Dynaconf results in TypeError: __name__ must be set to a string object error
Hi
If I Add FlaskDynaconf(app)
before FlaskInjector(app=app, modules=[init_inject])
, it'll result in TypeError: __name__ must be set to a string object
this is the dynaconf project: https://dynaconf.readthedocs.io/en/latest/guides/flask.html
Please provide full stack trace and versions of the relevant software you're using, the exception itself provides almost no information.
sorry for lacking info. here's the stack trace:
TypeError: __name__ must be set to a string object
File "runpy.py", line 193, in _run_module_as_main
return _run_code(code, main_globals, None,
File "runpy.py", line 86, in _run_code
exec(code, run_globals)
File "__main__.py", line 45, in <module>
cli.main()
File "debugpy/../debugpy/server/cli.py", line 430, in main
run()
File "debugpy/../debugpy/server/cli.py", line 317, in run_module
run_module_as_main(target, alter_argv=True)
File "runpy.py", line 193, in _run_module_as_main
return _run_code(code, main_globals, None,
File "runpy.py", line 86, in _run_code
exec(code, run_globals)
File "__main__.py", line 15, in <module>
main(as_module=True)
File "flask/cli.py", line 967, in main
cli.main(args=sys.argv[1:], prog_name="python -m flask" if as_module else None)
File "flask/cli.py", line 586, in main
return super(FlaskGroup, self).main(*args, **kwargs)
File "click/core.py", line 782, in main
rv = self.invoke(ctx)
File "click/core.py", line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "click/core.py", line 1066, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "click/core.py", line 610, in invoke
return callback(*args, **kwargs)
File "click/decorators.py", line 73, in new_func
return ctx.invoke(f, obj, *args, **kwargs)
File "click/core.py", line 610, in invoke
return callback(*args, **kwargs)
File "flask/cli.py", line 848, in run_command
app = DispatchingApp(info.load_app, use_eager_loading=eager_loading)
File "flask/cli.py", line 305, in __init__
self._load_unlocked()
File "flask/cli.py", line 83, in find_best_app
app = call_factory(script_info, app_factory)
File "flask/cli.py", line 119, in call_factory
return app_factory()
File "app.py", line 36, in create_app
FlaskInjector(app=app, modules=[init_inject])
File "__init__.py", line 327, in __init__
process_dict(container, injector)
File "__init__.py", line 380, in process_dict
d[key] = wrap_fun(value, injector)
File "__init__.py", line 66, in wrap_fun
return wrap_function(fun, injector)
File "__init__.py", line 94, in wrap_function
def wrapper(*args: Any, **kwargs: Any) -> Any:
File "functools.py", line 54, in update_wrapper
setattr(wrapper, attr, value)
if I run FlaskDynaconf(app)
after FlaskInjector(app=app, modules=[init_inject])
everything works fine
Thanks. I have to repeat my request for you to provide full stack trace (including full file paths and package names, the trace you pasted is modified; you can mask some private/confidential details but not this much, I'd like to know what I'm dealing with and for the general structure to be intact) and versions of the relevant software (Python, Flask, Flask-Injector, Injector, Flask-Dynaconf).
sorry it took so long to answer, I was busy on other projects. here's an example project I set up: https://github.com/ahmadalli/flask-dynaconf-inject
when I run it with this commands, it fails with the same error:
pipenv shell
export FLASK_APP=microblog
flask run
The same for me, using FlaskDynaconf(app)
breaks FlaskInjector
call with mentioned error
I'm having the same issue. The problem seems to be that the current logic assumes that everything that has the __bindings__
or __call__
attribute should be wrapped. However, @functools.wraps
tries to set the __name__
attribute of the wrapping function (among others), which is problematic in this case, since the Dynaconf Configuration can be called, but has no __name__
. Consequently, trying to wrap it using functools causes an exception.
Note that as an (admittedly brittle) workaround, you can access app.jinja_env.globals['config']
once before applying Dynaconf , which seems to mask the issue by pinning the cached version of the config to the original Config class of the Flask app, which does not have the __call__
attribute.
Full sample code for reproduction:
from dynaconf import FlaskDynaconf
from flask import Flask
from flask_injector import FlaskInjector
app = Flask(__name__)
FlaskDynaconf(app)
FlaskInjector(app)
$ python --version
Python 3.8.2
requirements.txt
click==7.1.2
dynaconf==3.1.2
Flask==1.1.2
Flask-Injector==0.12.3
injector==0.18.4
itsdangerous==1.1.0
Jinja2==2.11.2
MarkupSafe==1.1.1
typing-extensions==3.7.4.3
Werkzeug==1.0.1
Stacktrace:
Traceback (most recent call last):
File "C:/Users/User/PycharmProjects/test_me/app.py", line 8, in <module>
FlaskInjector(app)
File "C:\Users\User\PycharmProjects\test_me\venv\lib\site-packages\flask_injector\__init__.py", line 327, in __init__
process_dict(container, injector)
File "C:\Users\User\PycharmProjects\test_me\venv\lib\site-packages\flask_injector\__init__.py", line 380, in process_dict
d[key] = wrap_fun(value, injector)
File "C:\Users\User\PycharmProjects\test_me\venv\lib\site-packages\flask_injector\__init__.py", line 66, in wrap_fun
return wrap_function(fun, injector)
File "C:\Users\User\PycharmProjects\test_me\venv\lib\site-packages\flask_injector\__init__.py", line 94, in wrap_function
def wrapper(*args: Any, **kwargs: Any) -> Any:
File "C:\Users\User\AppData\Local\Programs\Python\Python38\lib\functools.py", line 54, in update_wrapper
setattr(wrapper, attr, value)
TypeError: __name__ must be set to a string object