On Sat, Oct 2, 2010 at 8:01 PM, Carl Meyer <carl.j.me...@gmail.com> wrote:
>
>
> On Oct 2, 4:34 am, Russell Keith-Magee <russ...@keith-magee.com>
> wrote:
>> I can't argue with the fact that setting variables in __init__() is a
>> common idiom in Python generally, and this is certainly a weakness of
>> copy on call that will fail in non-thread safe ways.
>>
>> My counterclaim is that the move to class-based views is largely
>> driven by a desire to discourage the use of arguments in this way. We
>> want to discourage people from using arguments to class-based views,
>> and use subclassing instead.
>
> Talking about __init__ arguments is a red herring:
>
> class Foo(View):
>    def __init__(self):
>        self.bar = []
>        self.baz = {}
>
> I can't count the number of times I've done this; can you? This is an
> outright failure mode for copy-on-call; no __init__ arguments are
> involved.
>
> (I was wrong in my earlier message; this can fail in single-threaded
> development in consecutive requests. However, the failure is still
> subtle, and depending on the details of what you're doing in the view,
> may only manifest under certain circumstances. It still falls firmly
> in the category of a confusing and non-explicit failure.)
>
>> Lets be clear here - I don't particularly like *any* of the options on
>> the table so far. However, my opinion is that copy on call is the
>> option that will provide the least surprising behavior for the most
>> common use cases -- having a subset of arguments to __init__ being
>> unsafe is less surprising to me that having *all* attributes on self
>> either unsafe, or actively prohibited.
>
> It may be less surprising to you, but it's not at all clear to me that
> you are representative of Django users in that :-) It is far more
> surprising for me for such a low-level API to be making such odd fine-
> grained distinctions about whether I can safely assign mutable or
> immutable things to my instance in my __init__ method.
>
> The issue is not only the frequency of failure, but how explicit/clear
> it is. The failure here is so obscure and difficult to track down, it
> is likely to generate an outsize support burden. In contrast, raising
> an error on assigning to self can be completely explicit; no hours of
> painful and confusing debugging necessary.
>
> Let's also be clear to distinguish "just document that you don't store
> state on self" vs "raise an error if you set an attribute on self."
> These are proposals with very different characteristics in terms of
> likely confusion and support burden.

Agreed. The "just document" approach is a non-starter; the 'error when
you set attribute on self' is at least a technically viable option.

My problem with the error-based approach is entirely conceptual -- it
feels to me like throwing the baby out with the bathwater. I'm having
a lot of trouble with the idea that class instances have state in
every other Python class instance, and if we introduce an API that
physically prohibits instance state that -- no matter how good the
technical reasoning --  we're going to:

 * Cause confusion amongst new users as to why this seemingly obvious
thing can't be done

 * Ignore the legitimate occasions where using state is a useful
architectural approach.

>> We could even wrap the "no args to __init__" error check in a method
>> that enables it to be overridden and silenced in a subclass; that way,
>> introducing the potentially un-threadsafe behavior would need to be an
>
> Again, arguments to __init__ are not the issue. What would have to be
> checked is any assignment to self that takes place in __init__. How do
> you propose to check that?

I don't. You've got me -- in my haste to propose an idea, I hadn't
considered assigning state in the constructor.

I'm thinking on my feet at the moment, but the only way I can think to
resolve this would be to remove the copy() call; effectively making
the __call__() a factory that produces a new class instance that
shares all the methods of the class-based view, but none of the state
created at initialization. However, this is starting to get into the
same territory as why the __new__ approach isn't particularly
appealing.

Yours,
Russ Magee %-)

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.

Reply via email to