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
Preserve wsgify default args #203
Preserve wsgify default args #203
Conversation
As discussed with @mmerickel in |
I wrote up this patch last night, and I've been thinking about it some more. I'm not sure this is the right thing to do. Specifically, while the difference between
In addition, the whole story of default arguments seems a bit confusing:
So I'm submitting this for discussion, because it may be that the correct fix is actually some clearer documentation about when default arguments are used and when they are not. (i.e. "If you use the resulting callable as I'd be interested to hear what others think. |
When treating the result of `wsgify` or `wsgify.middleware` as a callable, arguments passed to the args/kwargs options to wsgify (and, by extension, to the middleware factory) are currently being dropped. This adds a couple of tests to demonstrate this, as well as a couple of tests to ensure that overriding args from the actual callable invocation remains possible. N.B. middleware only supports passing kwargs (and not args) through from the intermediary stages (i.e. from unbound middleware -> middleware factory -> app).
wsgify objects can be created with args/kwargs at construction time: def hello(req, name): return "Hello, %s!" % name app = wsgify(hello, args=("Fred",)) Previously, these arguments would only be passed to the underlying function (here, `hello`) when using the wsgify object as a callable that accepts `(environ, start_response)`. If you used the object as a callable taking a request (as documented) then the default args would be discarded. That is, continuing the above example: req = Request.blank('/') resp = req.get_response(app) # => "Hello, Fred" BUT app(req) # => raises TypeError This is perhaps most confusing when it interacts with `wsgify.middleware`. For example: @wsgify.middleware def add_magic_header(req, app, value='seated ducks'): resp = req.get_response(app) resp.headers['Magic-Header'] = value return resp app = add_magic_header(app, value='flying elephants') resp1 = req.get_response(app) resp2 = app(req) resp1.headers['Magic-Header'] # => 'flying elephants' resp2.headers['Magic-Header'] # => 'seated ducks' This commit ensures that if variadic arguments or keyword arguments are not provided in a call like app(req) then the defaults are used.
31c1595
to
ab38688
Compare
Since your last comment, have you had any other thoughts on how you expect this behave? If not I was planning on closing this PR for now. I don't have a good answer to any of your questions. |
I think it's surprising that the defaults are not used and so I think I'm in support of this PR. |
Heh. Thanks folks. 👍 |
We'll see what breaks when I do the next release. I think the fix is for the better! Thanks for contributing! |
wsgify objects can be created with args/kwargs at construction time:
Previously, these arguments would only be passed to the underlying
function (here,
hello
) when using the wsgify object as a callable thataccepts
(environ, start_response)
. If you used the object as acallable taking a request (as documented) then the default args would be
discarded.
That is, continuing the above example:
BUT
This is perhaps most confusing when it interacts with
wsgify.middleware
. For example:(An executable example of the above can be found here.)
This pull request ensures that if variadic arguments or keyword arguments are
not provided in a call like
then the defaults are used.