Hi Carl,

On Tuesday 21 June 2016 19:32:15 Carl Meyer wrote:
> Hi Shai,
> 
> On 06/20/2016 11:07 PM, Shai Berger wrote:
> > Well, we can change decorator_from_middleware to introspect the
> > middleware itself and decide accordingly:
> > 
> > -- if it does not have process_request or process_response as callable
> > attributes, and it is callable itself, it is a new-style middleware
> 
> "Does not have process_request and process_response as callable
> attributes" isn't reliable -- there's nothing preventing a new-style
> middleware from having such methods and calling them from `__call__` 

That was an "if", not "if and only if". 

> (in fact any middleware converted using MiddlewareMixin will fit this
> description).
> 

And I suggested a way to deal with them in the next two paragraphs:

> > -- if it does, we can define a new attribute '_dep5' (or something) whose
> > presence will indicate a dep5-compatible middleware. This attribute can
> > be defined on the transition mixin, so that people who use it for
> > transition don't have to care
> > 
> > -- if it has callable process_request/process_response and doesn't have
> > _dep5 then it is an old-style middleware
> > 

...except that on second thought, rather than just looking for its presence, 
we could look for it to be truthy -- so a middleware could explicitly mark 
itself as "old style" for the decorator, by setting it to False.

> 
> We can indeed introspect to try to auto-detect. It's a bit more complex
> due to the different `__init__` signature as well, and it would fail in
> case someone defined __call__ on an old-style middleware for some
> reason, but I've already written the code for this in
> https://github.com/django/django/pull/6765
> 

I missed the difference in __init__, but if you already took care of it...

> The main reason I abandoned auto-detection for this second attempt is
> that the behavior of these new-style view decorators is different enough
> that I'd like to provide better flexibility for third-party projects.
> Imagine a third-party project that currently provides both a middleware
> and a view decorator, created by decorator_from_middleware. Now they are
> adding Django 1.10 compatibility. If we auto-detect, and they inherit
> their middleware from the transition mixin so it's cross-compatible,
> decorator_from_middleware will suddenly detect it as new-style, leaving
> them no way to continue to provide their old decorator with fully
> backwards-compatible behavior.
> 

So, for middlewares where it matters, inherit the mixin and specify the 
attribute as False.

> Basically, I think middleware_decorator does something that's
> fundamentally different enough from decorator_from_middleware that it is
> clearer to make it a separate function and let people make explicit
> choices about which one they are using.
> 

And yet the plan is to deprecate decorator_from_middleware -- that is, "rob" 
people of that choice later on. As long as we intend to do that, I think it 
better to minimize churn.

Shai.

Reply via email to