Re: AbstractUser to get more abstract

2013-09-17 Thread Russell Keith-Magee
On Wed, Sep 18, 2013 at 1:27 PM, Luke Sneeringer wrote:

> Russell,
> I would *love* to do the work for the email-login analogue you describe.
> I actually proposed just such a thing a few months ago but was rebuffed.
>

I'm sorry to hear this. Out of interest, did a member of the core team
actually say "no", or was it just a matter of proposing something and not
getting traction?

If it was the latter, it's important to remember that the core team are all
volunteers, and sometimes the spare time of the core team doesn't
necessarily match up with the spare time of volunteers in the wider
community. As a result, well intentioned and desired work sometimes gets
ignored. It's not (necessarily) being ignored because it was bad -- often
it's just "we don't have enough cycles *right now*.


> However, I think this would be extremely useful. Also, I am, in fact,
> looking to get involved with Django development, as I haven't quite
> navigated the hurdles successfully.
>
> I do have one request, though. Is there a core developer that would be
> willing to "mentor" my work on this, so I can make sure I am writing
> something worthy of acceptance?
>

Well, I'm willing to mentor the effort.

Like I've indicated, the first step isn't to write code at all - it's to
get a good summary of the state of play of existing implementations.
Multiple people have already taken a swing at an implementation; before we
commit to one particular codebase, we need to understand what has already
been offered by the community.

Yours,
Russ Magee %-)

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
For more options, visit https://groups.google.com/groups/opt_out.


Re: AbstractUser to get more abstract

2013-09-17 Thread Luke Sneeringer
Russell,
I would love to do the work for the email-login analogue you describe. I 
actually proposed just such a thing a few months ago but was rebuffed. However, 
I think this would be extremely useful. Also, I am, in fact, looking to get 
involved with Django development, as I haven't quite navigated the hurdles 
successfully.

I do have one request, though. Is there a core developer that would be willing 
to "mentor" my work on this, so I can make sure I am writing something worthy 
of acceptance?

L

On Sep 12, 2013, at 5:41 PM, Russell Keith-Magee  
wrote:

> 
> On Fri, Sep 13, 2013 at 4:44 AM, Abdulaziz Alfoudari 
>  wrote:
> This is a continuation of my post on stackoverflow.
> 
> With the introduction of Django 1.5, it was possible to create a custom User 
> model which is flexible enough to have any user profile the developer wants 
> created. However, looking at a very common problem which is using the email 
> as the primary user identifier instead of username, the solution requires 
> copying most of Django's internal definition of AbstractUser and that is only 
> to remove the username field.
> 
> A better solution in my opinion is make AbstractUser even more abstract by 
> removing username field, and allowing the developer to explicitly specify the 
> field to be used as the user identifier. This will require a tiny extra work 
> for those that use the current default behavior, but it will also greatly 
> reduce the work needed for the very common problem of using email as the user 
> identifier.
> 
> Please share your thoughts and opinions on this.
> 
> The short answer: this isn't going to happen. AbstractUser is a released and 
> documented API, so we're not in a position to change it in the way you 
> describe without causing massive inconvenience to everyone that is using it 
> at present (at least, I don't see an obvious way that this could be done).
> 
> However, ticket #20824 describes a proposal to add an email-login analog of 
> Django's built-in user. This would make introduction of email-based login a 
> matter of 2 lines of configuration. This ticket is really just waiting on 
> someone to prepare a patch… and it should be a relatively simple patch to 
> prepare. If you're looking to get involved in Django development, this would 
> be an easy place to start.
> 
> Yours,
> Russ Magee %-)
> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Django developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to django-developers+unsubscr...@googlegroups.com.
> To post to this group, send email to django-developers@googlegroups.com.
> Visit this group at http://groups.google.com/group/django-developers.
> For more options, visit https://groups.google.com/groups/opt_out.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
For more options, visit https://groups.google.com/groups/opt_out.


Re: AbstractUser to get more abstract

2013-09-17 Thread Russell Keith-Magee
Hi all

It's great to see this discussion is happening -- however, given that we're
debating the merits of different architectural approaches, with the aim of
presenting a single approach for final inclusion in Django master, it would
be worthwhile formalising the discussion. This is something we've done on a
number of other occasions -- the discussion about pluggable contrib.auth:

https://code.djangoproject.com/wiki/ContribAuthImprovements

And the introduction of contrib.messages:

https://code.djangoproject.com/wiki/SessionMessages

are two good examples. This sort of summary is very helpful for the core
team because it means we don't need to track hundreds of messages over
dozens of threads -- we can focus on the end point of the discussion and
make a clear decision.

I've set up a stub page here:

https://code.djangoproject.com/wiki/ContribEmailAuth

Feel free to fill in details. Try to keep the discussion objective; if
there's a matter of opinion/taste in discussion, flag it as such.


Yours,
Russ Magee %-)




On Tue, Sep 17, 2013 at 11:01 PM, tanderegg wrote:

> Quick addendum: I forgot that django-libtech-emailuser does not use an
> AbstractUser intermediary step, it simply has one model.  My approach has
> an abstract model, just like auth.User, with a concrete model that inherits
> from it and is swappable.
>
> -Tim
>
>
> On Tuesday, September 17, 2013 10:46:32 AM UTC-4, tanderegg wrote:
>>
>> Hi Jorge -
>>
>> Thanks for the response.  Rookie mistake: I had cloned from 1.6.x stable
>> instead of master, the branch is now fixed to be branched from
>> django/master from 10 minutes ago, that should resolve your conflicts.
>>
>> In terms of API, the API I went with is basically identical to the API
>> used in django-libtech-emailuser, with the exception that I did not include
>> a new password_reset form.  Testing showed this was not necessary, the one
>> in django.contrib.auth works fine with my model.  The reason our API's are
>> the same is because we both copied the existing API for
>> django.contrib.auth.User exactly.  This means first_name and last_name,
>> along with the email, password, is_active, is_staff, and is_superuser all
>> exist in the auth_email.AbstractUser model, just like they do in
>> auth.AbstractUser.
>>
>> I went this route one the principle that simplicity is best, and I wanted
>> folks to get the exact same behaviour from auth_email.AbstractUser, and
>> auth_email.User, that they would expect from auth.AbstractUser and
>> auth.User.
>>
>> django-libtech-emailuser did not includ any tests, so my code goes beyond
>> that to include a small test suite that covers everything I thought was
>> nesseccary to cover.
>>
>> I did not go the route of django-authtools because I felt that it went
>> above and beyond the scope of this ticket, since it included multiple
>> layers of abstraction, a rewrite of the views to use Class Based Views,
>> etc.  I felt that if I were to go that route, then the re-write should
>> occur in django.contrib.auth, not in my extension of it.  Hence, out of
>> scope for this ticket since that could potentially affect an established
>> API.
>>
>> Let me know if that logic makes sense!
>>
>> Tim
>>
>> On Tuesday, September 17, 2013 3:25:01 AM UTC-4, Jorge Cardoso Leitão
>> wrote:
>>>
>>> Hi Tim.
>>>
>>> Thanks for posting this here. I was not aware of this ticket.
>>> Thank you also for taking the initiative and starting moving on this
>>> front.
>>>
>>> First of all, like you, I'm also recent in Django dev. This means that
>>> most likely, we will both make mistakes in the approach.
>>> The important is that we learn with them, and that is also why we are in
>>> a community of more experience users.
>>>
>>>
>>> Let me try to convey why is important that we take into account what
>>> other people have already done (i.e. existing apps).
>>>
>>> I'm using django-authtools; I found the the app is has tests and it is
>>> well documented.
>>> I'm using it in production and so far I didn't found any issue.
>>>
>>> My point is: the main reason we try to use existing code is not because
>>> the code is there, but because it is normally tested (both UnitTests and
>>> people using it and reporting issues) and documented, which means it is
>>> less prone to errors and more robust to integration.
>>>
>>> That said, I would start by comparing APIs.
>>> That allow us to have a solid ground on what there is already out there,
>>> to see if any of the existing apps fulfils our expectations of what we
>>> would like to have in the core.
>>>
>>> I tried to clone your branch ticket_20824 from github to compare your
>>> app with django-authtools, but it is (far) behind Django master branch,
>>> which is causing merge conflicts that I don't know how to resolve (because
>>> I don't know what you are exactly doing).
>>> Maybe I'm doing something wrong or I don't know enough of git, but could
>>> you please tell us (or maybe is just me that need to be told!) how can we
>>> compare

Re: AbstractUser to get more abstract

2013-09-17 Thread Russell Keith-Magee
Hi Aaron,

The motivation? Simple practicality.

contrib.auth ships with a known manifest of models. If you add extra User
models to contrib.auth, *every* Django project in existence will  gain
extra User models -- unless we develop a whole lot of extra infrastructure
to *not* install certain models.

Putting the "email-User' model in a separate app should mean it's a 2-line
configuration to opt into a "standardised" email-based User model, and no
special "don't install this model" infrastructure will be required.

As for the argument that there will be code duplication -- there shouldn't
be. A contrib email-auth app isn't going to *replace* contrib.auth.
contrib.auth has to be there for all the AUTH_USER_MODEL stuff to work.
There might be a need for some refactoring of contrib.auth to provide
better extension points, but we certainly aren't going to be reproducing
the entirety of contrib.auth in contrib.emailauth -- emailauth will be
extending the base provided by auth.

Yours,
Russ Magee %-)

On Wed, Sep 18, 2013 at 5:08 AM, Aaron Merriam wrote:

> Russel, I'm curious if you could expand/explain your motivation on having
> this implemented as a separate contrib application rather than including it
> with django.contrib.auth
>
> On Thursday, September 12, 2013 5:41:29 PM UTC-6, Russell Keith-Magee
> wrote:
>
>>
>> On Fri, Sep 13, 2013 at 4:44 AM, Abdulaziz Alfoudari <
>> aziz.al...@gmail.com> wrote:
>>
>>> This is a continuation of my post on 
>>> stackoverflow
>>> .
>>>
>>> With the introduction of Django 1.5, it was possible to create a custom
>>> User model which is flexible enough to have any user profile the developer
>>> wants created. However, looking at a very common problem which is using the
>>> email as the primary user identifier instead of username, the solution
>>> requires copying most of Django's internal definition of AbstractUser and
>>> that is only to remove the username field.
>>>
>>> A better solution in my opinion is make AbstractUser even more abstract
>>> by removing username field, and allowing the developer to explicitly
>>> specify the field to be used as the user identifier. This will require a
>>> tiny extra work for those that use the current default behavior, but it
>>> will also greatly reduce the work needed for the very common problem of
>>> using email as the user identifier.
>>>
>>> Please share your thoughts and opinions on this.
>>>
>>
>> The short answer: this isn't going to happen. AbstractUser is a released
>> and documented API, so we're not in a position to change it in the way you
>> describe without causing massive inconvenience to everyone that is using it
>> at present (at least, I don't see an obvious way that this could be done).
>>
>> However, ticket #20824 describes a proposal to add an email-login analog
>> of Django's built-in user. This would make introduction of email-based
>> login a matter of 2 lines of configuration. This ticket is really just
>> waiting on someone to prepare a patch… and it should be a relatively simple
>> patch to prepare. If you're looking to get involved in Django development,
>> this would be an easy place to start.
>>
>> Yours,
>> Russ Magee %-)
>>
>>  --
> You received this message because you are subscribed to the Google Groups
> "Django developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To post to this group, send email to django-developers@googlegroups.com.
> Visit this group at http://groups.google.com/group/django-developers.
> For more options, visit https://groups.google.com/groups/opt_out.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
For more options, visit https://groups.google.com/groups/opt_out.


Re: Question about new tests

2013-09-17 Thread Florian Apolloner
Hi Justin,

many core developers haven't been at DjangoCon US, so would you mind to 
summarize a few things like: What is the roadmap, how do you plan to tackle 
things; who is involved + whatever else you think would be nice to know for 
someone who more or less heard the first time of this from your mail here.

Thanks & regards,
Florian

On Tuesday, September 17, 2013 7:55:08 PM UTC+2, Justin Holmes wrote:
>
> I'm working on the #unsetting project (ie, making all of Django's 
> internals work without having to import the settings global).
>
> We have two key areas that now seem to work without running settings: mail 
> and templating.
>
> I want to demonstrate these with tests.  Where shall I put these tests?
>
> 1) Alongside the respective tests for these features (ie, tests.mail)?
> 2) As a regression test (ie, also in tests.mail, but demonstrating that 
> the inane errors no longer appear)
> 3) Alongside the unsetting config?
>
> -- 
> Justin Holmes
> Chief Chocobo Breeder, slashRoot
>
> slashRoot: Coffee House and Tech Dojo
> New Paltz, NY 12561
> 845.633.8330 
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
For more options, visit https://groups.google.com/groups/opt_out.


Re: AbstractUser to get more abstract

2013-09-17 Thread Aaron Merriam
Russel, I'm curious if you could expand/explain your motivation on having 
this implemented as a separate contrib application rather than including it 
with django.contrib.auth

On Thursday, September 12, 2013 5:41:29 PM UTC-6, Russell Keith-Magee wrote:
>
>
> On Fri, Sep 13, 2013 at 4:44 AM, Abdulaziz Alfoudari 
> 
> > wrote:
>
>> This is a continuation of my post on 
>> stackoverflow
>> .
>>
>> With the introduction of Django 1.5, it was possible to create a custom 
>> User model which is flexible enough to have any user profile the developer 
>> wants created. However, looking at a very common problem which is using the 
>> email as the primary user identifier instead of username, the solution 
>> requires copying most of Django's internal definition of AbstractUser and 
>> that is only to remove the username field.
>>
>> A better solution in my opinion is make AbstractUser even more abstract 
>> by removing username field, and allowing the developer to explicitly 
>> specify the field to be used as the user identifier. This will require a 
>> tiny extra work for those that use the current default behavior, but it 
>> will also greatly reduce the work needed for the very common problem of 
>> using email as the user identifier.
>>
>> Please share your thoughts and opinions on this.
>>
>
> The short answer: this isn't going to happen. AbstractUser is a released 
> and documented API, so we're not in a position to change it in the way you 
> describe without causing massive inconvenience to everyone that is using it 
> at present (at least, I don't see an obvious way that this could be done).
>
> However, ticket #20824 describes a proposal to add an email-login analog 
> of Django's built-in user. This would make introduction of email-based 
> login a matter of 2 lines of configuration. This ticket is really just 
> waiting on someone to prepare a patch… and it should be a relatively simple 
> patch to prepare. If you're looking to get involved in Django development, 
> this would be an easy place to start.
>
> Yours,
> Russ Magee %-)
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
For more options, visit https://groups.google.com/groups/opt_out.


Question about new tests

2013-09-17 Thread Justin Holmes
I'm working on the #unsetting project (ie, making all of Django's internals
work without having to import the settings global).

We have two key areas that now seem to work without running settings: mail
and templating.

I want to demonstrate these with tests.  Where shall I put these tests?

1) Alongside the respective tests for these features (ie, tests.mail)?
2) As a regression test (ie, also in tests.mail, but demonstrating that the
inane errors no longer appear)
3) Alongside the unsetting config?

-- 
Justin Holmes
Chief Chocobo Breeder, slashRoot

slashRoot: Coffee House and Tech Dojo
New Paltz, NY 12561
845.633.8330

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
For more options, visit https://groups.google.com/groups/opt_out.


Re: AbstractUser to get more abstract

2013-09-17 Thread tanderegg
Hi Jorge -

Thanks for the response.  Rookie mistake: I had cloned from 1.6.x stable 
instead of master, the branch is now fixed to be branched from 
django/master from 10 minutes ago, that should resolve your conflicts.

In terms of API, the API I went with is basically identical to the API used 
in django-libtech-emailuser, with the exception that I did not include a 
new password_reset form.  Testing showed this was not necessary, the one in 
django.contrib.auth works fine with my model.  The reason our API's are the 
same is because we both copied the existing API for 
django.contrib.auth.User exactly.  This means first_name and last_name, 
along with the email, password, is_active, is_staff, and is_superuser all 
exist in the auth_email.AbstractUser model, just like they do in 
auth.AbstractUser.

I went this route one the principle that simplicity is best, and I wanted 
folks to get the exact same behaviour from auth_email.AbstractUser, and 
auth_email.User, that they would expect from auth.AbstractUser and 
auth.User.

django-libtech-emailuser did not includ any tests, so my code goes beyond 
that to include a small test suite that covers everything I thought was 
nesseccary to cover.

I did not go the route of django-authtools because I felt that it went 
above and beyond the scope of this ticket, since it included multiple 
layers of abstraction, a rewrite of the views to use Class Based Views, 
etc.  I felt that if I were to go that route, then the re-write should 
occur in django.contrib.auth, not in my extension of it.  Hence, out of 
scope for this ticket since that could potentially affect an established 
API.

Let me know if that logic makes sense!

Tim

On Tuesday, September 17, 2013 3:25:01 AM UTC-4, Jorge Cardoso Leitão wrote:
>
> Hi Tim.
>
> Thanks for posting this here. I was not aware of this ticket.
> Thank you also for taking the initiative and starting moving on this front.
>
> First of all, like you, I'm also recent in Django dev. This means that 
> most likely, we will both make mistakes in the approach.
> The important is that we learn with them, and that is also why we are in a 
> community of more experience users.
>
>
> Let me try to convey why is important that we take into account what other 
> people have already done (i.e. existing apps).
>
> I'm using django-authtools; I found the the app is has tests and it is 
> well documented.
> I'm using it in production and so far I didn't found any issue.
>
> My point is: the main reason we try to use existing code is not because 
> the code is there, but because it is normally tested (both UnitTests and 
> people using it and reporting issues) and documented, which means it is 
> less prone to errors and more robust to integration.
>
> That said, I would start by comparing APIs.
> That allow us to have a solid ground on what there is already out there, 
> to see if any of the existing apps fulfils our expectations of what we 
> would like to have in the core.
>
> I tried to clone your branch ticket_20824 from github to compare your app 
> with django-authtools, but it is (far) behind Django master branch, which 
> is causing merge conflicts that I don't know how to resolve (because I 
> don't know what you are exactly doing).
> Maybe I'm doing something wrong or I don't know enough of git, but could 
> you please tell us (or maybe is just me that need to be told!) how can we 
> compare your patch with Django-master?
>
> Let me try to give an example:
>
> After taking a look at github.com/Liberationtech/django-libtech-emailuser
> , the following are the main differences and similarities with 
> django-authtools.
> Please notice that I'm a (so far) 1-time comitter of django-authtools, so 
> take this comparison with appropriate care as I'm certainly biased.
>
> Where they are *similar*:
>
> 1. Both are subclasses of AbstractBaseUser and PermissionsMixin (thus 
> allow permissions API to be used)
>
> 2. Both implement the required forms for creation, change, passwordReset.
>
> 3. Both implement admin interface
>
> Where they are *different*:
>
> 1. Models implementation:
>
> emailuser uses one model with 3 fields: email, first_name, last_name 
> (USERNAME_FIELD = 'email)
>
> django-authtools uses defines three models: 
>
> A. AbstractUserMail (with one field 'email', like emailuser),
> B. AbstractNamedUser, derived from AbstractUserMail with an additional 
> field "name". 
> C. User, derived from AbstractNamedUser, which is swappable and 
> non-abstract.
>
> 2. django-authtools has tests, emailuser doesn't
>
> 3. django-authtools is documented, emailuser doesn't
>
> 4. django-authtools implements views, emailuser doesn't.
>
> 5. they have different licences, but I don't know enough about them to 
> know what are the differences.
>
> 6. django-authtools passes on travis-ci.org tests, and, as far as I know, 
> enforces clean commit history (don't know if it is relevant thought).
>
> 7. usermail has a form to ask reset-password (by emai

Re: AbstractUser to get more abstract

2013-09-17 Thread Aaron Merriam
Up front, I'm one of the developers of django-authtools

I'm feel strongly that a new contrib application is the wrong way to 
accomplish this.  Based on my memory of auth and django-authtools, most of 
`auth` will just work with the AbstractEmailUser class provided by 
django-authtools.  Why not just include a new swappable user class in 
django.contrib.auth that uses email as username?  I believe that all of the 
built in django.contrib.auth views will work with the AbstractEmailUser 
model in django-authtools, All of the forms from django.contrib.auth except 
UserCreationForm and UserChangeForm work with AbstractEmailUser.  There 
would need to be changes to the ModelAdmin provided by django.contrib.auth. 
django-authtools has a ModelAdmin that works for the normal auth.User and 
with AbstractEmailUser, which would be a very minor change to 
django.contrib.auth.admin

Adding a new contrib application for this seems very heavy weight and to 
duplicate a lot of logic that already has a well established home.  Is 
there other support for doing this more inline with the way it was done in 
django-authtools.

On Tuesday, September 17, 2013 9:01:18 AM UTC-6, tanderegg wrote:
>
> Quick addendum: I forgot that django-libtech-emailuser does not use an 
> AbstractUser intermediary step, it simply has one model.  My approach has 
> an abstract model, just like auth.User, with a concrete model that inherits 
> from it and is swappable.
>
> -Tim
>
> On Tuesday, September 17, 2013 10:46:32 AM UTC-4, tanderegg wrote:
>>
>> Hi Jorge -
>>
>> Thanks for the response.  Rookie mistake: I had cloned from 1.6.x stable 
>> instead of master, the branch is now fixed to be branched from 
>> django/master from 10 minutes ago, that should resolve your conflicts.
>>
>> In terms of API, the API I went with is basically identical to the API 
>> used in django-libtech-emailuser, with the exception that I did not include 
>> a new password_reset form.  Testing showed this was not necessary, the one 
>> in django.contrib.auth works fine with my model.  The reason our API's are 
>> the same is because we both copied the existing API for 
>> django.contrib.auth.User exactly.  This means first_name and last_name, 
>> along with the email, password, is_active, is_staff, and is_superuser all 
>> exist in the auth_email.AbstractUser model, just like they do in 
>> auth.AbstractUser.
>>
>> I went this route one the principle that simplicity is best, and I wanted 
>> folks to get the exact same behaviour from auth_email.AbstractUser, and 
>> auth_email.User, that they would expect from auth.AbstractUser and 
>> auth.User.
>>
>> django-libtech-emailuser did not includ any tests, so my code goes beyond 
>> that to include a small test suite that covers everything I thought was 
>> nesseccary to cover.
>>
>> I did not go the route of django-authtools because I felt that it went 
>> above and beyond the scope of this ticket, since it included multiple 
>> layers of abstraction, a rewrite of the views to use Class Based Views, 
>> etc.  I felt that if I were to go that route, then the re-write should 
>> occur in django.contrib.auth, not in my extension of it.  Hence, out of 
>> scope for this ticket since that could potentially affect an established 
>> API.
>>
>> Let me know if that logic makes sense!
>>
>> Tim
>>
>> On Tuesday, September 17, 2013 3:25:01 AM UTC-4, Jorge Cardoso Leitão 
>> wrote:
>>>
>>> Hi Tim.
>>>
>>> Thanks for posting this here. I was not aware of this ticket.
>>> Thank you also for taking the initiative and starting moving on this 
>>> front.
>>>
>>> First of all, like you, I'm also recent in Django dev. This means that 
>>> most likely, we will both make mistakes in the approach.
>>> The important is that we learn with them, and that is also why we are in 
>>> a community of more experience users.
>>>
>>>
>>> Let me try to convey why is important that we take into account what 
>>> other people have already done (i.e. existing apps).
>>>
>>> I'm using django-authtools; I found the the app is has tests and it is 
>>> well documented.
>>> I'm using it in production and so far I didn't found any issue.
>>>
>>> My point is: the main reason we try to use existing code is not because 
>>> the code is there, but because it is normally tested (both UnitTests and 
>>> people using it and reporting issues) and documented, which means it is 
>>> less prone to errors and more robust to integration.
>>>
>>> That said, I would start by comparing APIs.
>>> That allow us to have a solid ground on what there is already out there, 
>>> to see if any of the existing apps fulfils our expectations of what we 
>>> would like to have in the core.
>>>
>>> I tried to clone your branch ticket_20824 from github to compare your 
>>> app with django-authtools, but it is (far) behind Django master branch, 
>>> which is causing merge conflicts that I don't know how to resolve (because 
>>> I don't know what you are exactly doing).
>>> Maybe I'm doing som

Re: AbstractUser to get more abstract

2013-09-17 Thread tanderegg
Quick addendum: I forgot that django-libtech-emailuser does not use an 
AbstractUser intermediary step, it simply has one model.  My approach has 
an abstract model, just like auth.User, with a concrete model that inherits 
from it and is swappable.

-Tim

On Tuesday, September 17, 2013 10:46:32 AM UTC-4, tanderegg wrote:
>
> Hi Jorge -
>
> Thanks for the response.  Rookie mistake: I had cloned from 1.6.x stable 
> instead of master, the branch is now fixed to be branched from 
> django/master from 10 minutes ago, that should resolve your conflicts.
>
> In terms of API, the API I went with is basically identical to the API 
> used in django-libtech-emailuser, with the exception that I did not include 
> a new password_reset form.  Testing showed this was not necessary, the one 
> in django.contrib.auth works fine with my model.  The reason our API's are 
> the same is because we both copied the existing API for 
> django.contrib.auth.User exactly.  This means first_name and last_name, 
> along with the email, password, is_active, is_staff, and is_superuser all 
> exist in the auth_email.AbstractUser model, just like they do in 
> auth.AbstractUser.
>
> I went this route one the principle that simplicity is best, and I wanted 
> folks to get the exact same behaviour from auth_email.AbstractUser, and 
> auth_email.User, that they would expect from auth.AbstractUser and 
> auth.User.
>
> django-libtech-emailuser did not includ any tests, so my code goes beyond 
> that to include a small test suite that covers everything I thought was 
> nesseccary to cover.
>
> I did not go the route of django-authtools because I felt that it went 
> above and beyond the scope of this ticket, since it included multiple 
> layers of abstraction, a rewrite of the views to use Class Based Views, 
> etc.  I felt that if I were to go that route, then the re-write should 
> occur in django.contrib.auth, not in my extension of it.  Hence, out of 
> scope for this ticket since that could potentially affect an established 
> API.
>
> Let me know if that logic makes sense!
>
> Tim
>
> On Tuesday, September 17, 2013 3:25:01 AM UTC-4, Jorge Cardoso Leitão 
> wrote:
>>
>> Hi Tim.
>>
>> Thanks for posting this here. I was not aware of this ticket.
>> Thank you also for taking the initiative and starting moving on this 
>> front.
>>
>> First of all, like you, I'm also recent in Django dev. This means that 
>> most likely, we will both make mistakes in the approach.
>> The important is that we learn with them, and that is also why we are in 
>> a community of more experience users.
>>
>>
>> Let me try to convey why is important that we take into account what 
>> other people have already done (i.e. existing apps).
>>
>> I'm using django-authtools; I found the the app is has tests and it is 
>> well documented.
>> I'm using it in production and so far I didn't found any issue.
>>
>> My point is: the main reason we try to use existing code is not because 
>> the code is there, but because it is normally tested (both UnitTests and 
>> people using it and reporting issues) and documented, which means it is 
>> less prone to errors and more robust to integration.
>>
>> That said, I would start by comparing APIs.
>> That allow us to have a solid ground on what there is already out there, 
>> to see if any of the existing apps fulfils our expectations of what we 
>> would like to have in the core.
>>
>> I tried to clone your branch ticket_20824 from github to compare your app 
>> with django-authtools, but it is (far) behind Django master branch, which 
>> is causing merge conflicts that I don't know how to resolve (because I 
>> don't know what you are exactly doing).
>> Maybe I'm doing something wrong or I don't know enough of git, but could 
>> you please tell us (or maybe is just me that need to be told!) how can we 
>> compare your patch with Django-master?
>>
>> Let me try to give an example:
>>
>> After taking a look at github.com/Liberationtech/django-libtech-emailuser
>> , the following are the main differences and similarities with 
>> django-authtools.
>> Please notice that I'm a (so far) 1-time comitter of django-authtools, so 
>> take this comparison with appropriate care as I'm certainly biased.
>>
>> Where they are *similar*:
>>
>> 1. Both are subclasses of AbstractBaseUser and PermissionsMixin (thus 
>> allow permissions API to be used)
>>
>> 2. Both implement the required forms for creation, change, passwordReset.
>>
>> 3. Both implement admin interface
>>
>> Where they are *different*:
>>
>> 1. Models implementation:
>>
>> emailuser uses one model with 3 fields: email, first_name, last_name 
>> (USERNAME_FIELD = 'email)
>>
>> django-authtools uses defines three models: 
>>
>> A. AbstractUserMail (with one field 'email', like emailuser),
>> B. AbstractNamedUser, derived from AbstractUserMail with an additional 
>> field "name". 
>> C. User, derived from AbstractNamedUser, which is swappable and 
>> non-abstract.
>>
>> 2. django-aut

Re: Benchmarking 1.5 vs 1.6

2013-09-17 Thread Anssi Kääriäinen
I applied the patch with comment modification to 1.6.x and master.

It seems the change did a lot of good to all of query benchmarks. Most 
1.6.x ORM results are now 1.1 to 1.3x faster than in 1.5.x. Full results in 
the end of this post.

There is still some problems, template rendering seems to be 10% slower. 
model_creation is still 1.15x slower than in 1.5.x. url_reverse is 1.2x 
slower. I don't have time to investigate these more, and in any case these 
aren't critical regressions in any way.

For those who want to run the suite - it seems that if you have new enough 
processor the speed throttling is done in silicon. In that case it will be 
really, really hard to get stable results from djangobench. The best you 
can do is use big amount of trials (-t) and look at the minimum runtime 
instead of the average. There might be some tools for your operating system 
to switch CPU throttling to minimum, so google for those.

 - Anssi

The full results again for latest stable/1.6.x vs stable/1.5.x:

Running 'default_middleware' benchmark ...
Min: 0.000664 -> 0.000336: 1.9766x faster
Avg: 0.000794 -> 0.000398: 1.9932x faster
Significant (t=6.607238)
Stddev: 0.00031 -> 0.00029: 1.0583x smaller (N = 50)

Running 'form_clean' benchmark ...
Min: 0.21 -> 0.22: 1.0455x slower
Avg: 0.26 -> 0.23: 1.1314x faster
Not significant
Stddev: 0.2 -> 0.0: 6.9991x smaller (N = 50)

Running 'form_create' benchmark ...
Min: 0.46 -> 0.55: 1.1979x slower
Avg: 0.49 -> 0.000737: 14.9229x slower # Outlier, as mentioned earlier
Not significant
Stddev: 0.1 -> 0.00481: 415.8844x larger (N = 50)

Running 'l10n_render' benchmark ...
Min: 0.005955 -> 0.006949: 1.1669x slower
Avg: 0.006347 -> 0.007402: 1.1661x slower
Significant (t=-3.120463)
Stddev: 0.00150 -> 0.00186: 1.2448x larger (N = 50)

Running 'model_creation' benchmark ...
Min: 0.000170 -> 0.000199: 1.1697x slower
Avg: 0.000186 -> 0.000218: 1.1725x slower
Significant (t=-2.009837)
Stddev: 0.8 -> 0.8: 1.0107x smaller (N = 50)

Running 'model_delete' benchmark ...
Min: 0.000225 -> 0.000240: 1.0668x slower
Avg: 0.000232 -> 0.000256: 1.1057x slower
Significant (t=-4.861734)
Stddev: 0.2 -> 0.3: 1.7163x larger (N = 50)

Running 'model_save_existing' benchmark ...
Min: 0.033559 -> 0.011296: 2.9709x faster
Avg: 0.034041 -> 0.011363: 2.9959x faster
Significant (t=169.025764)
Stddev: 0.00094 -> 0.00010: 9.0688x smaller (N = 50)

Running 'model_save_new' benchmark ...
Min: 0.022818 -> 0.011384: 2.0044x faster
Avg: 0.033812 -> 0.011772: 2.8721x faster
Significant (t=82.502660)
Stddev: 0.00177 -> 0.00065: 2.7339x smaller (N = 50)

Running 'multi_value_dict' benchmark ...
Min: 0.43 -> 0.44: 1.0335x slower
Avg: 0.79 -> 0.81: 1.0363x slower
Not significant
Stddev: 0.2 -> 0.2: 1.0079x larger (N = 50)

Running 'qs_filter_chaining' benchmark ...
Min: 0.002281 -> 0.000742: 3.0742x faster
Avg: 0.002331 -> 0.000765: 3.0468x faster
Significant (t=133.899536)
Stddev: 0.7 -> 0.4: 1.5650x smaller (N = 50)

Running 'query_aggregate' benchmark ...
Min: 0.000254 -> 0.000209: 1.2144x faster
Avg: 0.000316 -> 0.000215: 1.4680x faster
Significant (t=3.067214)
Stddev: 0.00023 -> 0.1: 16.9474x smaller (N = 50)

Running 'query_all' benchmark ...
Min: 0.024302 -> 0.021535: 1.1285x faster
Avg: 0.025855 -> 0.023171: 1.1158x faster
Significant (t=5.678997)
Stddev: 0.00243 -> 0.00230: 1.0566x smaller (N = 50)

Running 'query_all_multifield' benchmark ...
Min: 0.050120 -> 0.048104: 1.0419x faster
Avg: 0.052968 -> 0.050711: 1.0445x faster
Significant (t=3.563558)
Stddev: 0.00353 -> 0.00276: 1.2772x smaller (N = 50)

Running 'query_annotate' benchmark ...
Min: 0.000521 -> 0.000438: 1.1894x faster
Avg: 0.000533 -> 0.000453: 1.1781x faster
Significant (t=11.172131)
Stddev: 0.3 -> 0.4: 1.2886x larger (N = 50)

Running 'query_complex_filter' benchmark ...
Min: 0.000166 -> 0.000119: 1.3948x faster
Avg: 0.000172 -> 0.000123: 1.3995x faster
Significant (t=12.315270)
Stddev: 0.3 -> 0.1: 2.4050x smaller (N = 50)

Running 'query_count' benchmark ...
Min: 0.000211 -> 0.000170: 1.2412x faster
Avg: 0.000215 -> 0.000177: 1.2131x faster
Significant (t=9.985689)
Stddev: 0.1 -> 0.3: 4.9672x larger (N = 50)

Running 'query_dates' benchmark ...
Min: 0.000540 -> 0.000433: 1.2472x faster
Avg: 0.000550 -> 0.000446: 1.2348x faster
Significant (t=21.074766)
Stddev: 0.2 -> 0.3: 1.4789x larger (N = 50)

Running 'query_delete' benchmark ...
Min: 0.000260 -> 0.000215: 1.2095x faster
Avg: 0.000284 -> 0.000228: 1.2420x faster
Significant (t=7.900090)
Stddev: 0.4 -> 0.3: 1.1254x smaller (N = 50)

Running 'query_delete_related' benchmark ...
Min: 0.000308 -> 0.000275: 1.1206x faster
Avg: 0.000337 -> 0.000300: 1.1247x faster
Not significant
Stddev: 0.00017 -> 0.00013: 1.3042x smaller (N = 50)

Running 'query_distinct' benchmark ...
Min: 0.000339 -> 0.000281: 1.2071x faster
Avg: 0.000352 -> 0.000285: 1.2336x faster
Significant

Re: Benchmarking 1.5 vs 1.6

2013-09-17 Thread Jeremy Dunck
It may be useful to place a comment where @wraps was removed, lest some later 
do-gooder "fix" it.

On Sep 17, 2013, at 12:06 AM, Marc Tamlyn  wrote:

> Can't say I'm hugely worried about perfect tracebacks and introspection with 
> internal kind of functions here if it affects performance. The patch looks 
> good. I'd add a comment to say why we're not using @wraps in that context 
> though so someone doesn't go back and add it.
> 
> On 17 Sep 2013 07:57, "Anssi Kääriäinen"  wrote:
>> I did some investigation to query_iterator, and most of the slowdown is 
>> caused by functools.wraps. When used in nested context @wraps seems to be 
>> really slow. For example, try this with and without @wraps: 
>> http://pastebin.com/5ejAKuKd
>> 
>> Should we care about this slowdown? Can we do without @wraps? My 
>> understanding is that @wraps gives you __name__, __module__ and __doc__ 
>> which are easy to do manually. In addition it gives introspection the right 
>> args and kwargs for the wrapped function (so that IDEs see it correctly). 
>> This will be a lot harder to do manually, and doing so will likely result in 
>> similar slowdown.
>> 
>> The biggest hit case is if somebody is looping over a raw SQL queryset with 
>> .fetchone(). This use case will be severely punished. Even .execute(); 
>> .fetchmany() has a 1.5x slowdown (the benchmark is this one: 
>> https://github.com/django/djangobench/commit/94fc28d99f95c65d26d0fad8af44e46c49282220
>>  - simple SELECT + fetchall() for the ten returned rows.
>> 
>> I have created a patch that removes the usage of @wraps and makes 
>> connection.wrap_database_errors a cached_property. The cached_property 
>> should be safe as the context manager created by wrap_database_errors is 
>> stateless. This patch gets rid of the slowdown (1.00-1.05x slower in 
>> repeated runs for raw_sql benchmark). With just removed @wraps the slowdown 
>> is 1.1x. The patch is here: 
>> https://github.com/akaariai/django/commit/eafc373c16350abe51c565c8aefbe36cabf5219e
>> 
>> Should I apply the patch, and should I apply it to stable/1.6.x, too? 
>> Removal of @wraps is really low risk, usage of @cached_property is also low 
>> risk, but not as low as removal of @wraps.
>> 
>>  - Anssi
>> 
>> On Saturday, September 14, 2013 9:21:43 PM UTC+3, Anssi Kääriäinen wrote:
>>> 
>>> I just ran djangobench comparing 1.5 to 1.6. The biggest thing seems to be 
>>> form_create bechmark, the average is 15x slower. But for some reason the 
>>> minimum runtime is just 1.16x slower. This seems a bit strange. This might 
>>> be worth more investigation.
>>> 
>>> Otherwise there doens't seem to be anything alarming going on. Most ORM 
>>> operations are slightly faster (likely due to __deepcopy__ removal).
>>> 
>>> There are a couple of individual benchmarks worth mentioning... url_reverse 
>>> and query_iterator are slower (1.15x and 1.12x respectively). The 
>>> default_middleware and qs_filter_chaining benchmarks have gained a lot 
>>> (2.0x and 3.1x respectively). model_save_existing/model_save_new are faster 
>>> (2x+), but model_creation is slightly slower. I suspect there is something 
>>> going on with connection creation or transactions for model_creation, after 
>>> all model_creation is a convenience method for model.__init__ + 
>>> model_save_new which both aren't slower.
>>> 
>>> What else? url_reverse and template compliation under i18n slightly slower. 
>>> For the rest of benchmarks, see below.
>>> 
>>> Running 'default_middleware' benchmark ...
>>> Min: 0.001260 -> 0.000554: 2.2755x faster
>>> Avg: 0.001389 -> 0.000681: 2.0394x faster
>>> Significant (t=8.222155)
>>> Stddev: 0.00037 -> 0.00048: 1.2843x larger (N = 50)
>>> 
>>> Running 'form_clean' benchmark ...
>>> Min: 0.42 -> 0.42: no change
>>> Avg: 0.49 -> 0.43: 1.1341x faster
>>> Not significant
>>> Stddev: 0.4 -> 0.1: 6.6718x smaller (N = 50)
>>> 
>>> Running 'form_create' benchmark ...
>>> Min: 0.85 -> 0.99: 1.1657x slower
>>> Avg: 0.88 -> 0.001396: 15.8410x slower
>>> Not significant
>>> Stddev: 0.1 -> 0.00916: 783.3314x larger (N = 50)
>>> 
>>> Running 'l10n_render' benchmark ...
>>> Min: 0.011702 -> 0.014151: 1.2093x slower
>>> Avg: 0.012200 -> 0.014846: 1.2169x slower
>>> Significant (t=-4.824893)
>>> Stddev: 0.00233 -> 0.00310: 1.3311x larger (N = 50)
>>> 
>>> Running 'model_creation' benchmark ...
>>> Min: 0.000311 -> 0.000400: 1.2860x slower
>>> Avg: 0.000336 -> 0.000432: 1.2840x slower
>>> Significant (t=-2.799691)
>>> Stddev: 0.00015 -> 0.00019: 1.2751x larger (N = 50)
>>> 
>>> Running 'model_delete' benchmark ...
>>> Min: 0.000407 -> 0.000468: 1.1500x slower
>>> Avg: 0.000423 -> 0.000484: 1.1440x slower
>>> Significant (t=-7.131460)
>>> Stddev: 0.5 -> 0.4: 1.1807x smaller (N = 50)
>>> 
>>> Running 'model_save_existing' benchmark ...
>>> Min: 0.062923 -> 0.021829: 2.8826x faster
>>> Avg: 0.063206 -> 0.022001: 2.8729x faster
>>> Significant (t=793.026302)
>>> Stddev: 0.00034 -> 0.0001

Re: AbstractUser to get more abstract

2013-09-17 Thread Jorge Cardoso Leitão
Hi Tim.

Thanks for posting this here. I was not aware of this ticket.
Thank you also for taking the initiative and starting moving on this front.

First of all, like you, I'm also recent in Django dev. This means that most 
likely, we will both make mistakes in the approach.
The important is that we learn with them, and that is also why we are in a 
community of more experience users.


Let me try to convey why is important that we take into account what other 
people have already done (i.e. existing apps).

I'm using django-authtools; I found the the app is has tests and it is well 
documented.
I'm using it in production and so far I didn't found any issue.

My point is: the main reason we try to use existing code is not because the 
code is there, but because it is normally tested (both UnitTests and people 
using it and reporting issues) and documented, which means it is less prone to 
errors and more robust to integration.

That said, I would start by comparing APIs.
That allow us to have a solid ground on what there is already out there, to see 
if any of the existing apps fulfils our expectations of what we would like to 
have in the core.

I tried to clone your branch ticket_20824 from github to compare your app with 
django-authtools, but it is (far) behind Django master branch, which is causing 
merge conflicts that I don't know how to resolve (because I don't know what you 
are exactly doing).
Maybe I'm doing something wrong or I don't know enough of git, but could you 
please tell us (or maybe is just me that need to be told!) how can we compare 
your patch with Django-master?

Let me try to give an example:

After taking a look at github.com/Liberationtech/django-libtech-emailuser, the 
following are the main differences and similarities with django-authtools.
Please notice that I'm a (so far) 1-time comitter of django-authtools, so take 
this comparison with appropriate care as I'm certainly biased.

Where they are similar:

1. Both are subclasses of AbstractBaseUser and PermissionsMixin (thus allow 
permissions API to be used)

2. Both implement the required forms for creation, change, passwordReset.

3. Both implement admin interface

Where they are different:

1. Models implementation:

emailuser uses one model with 3 fields: email, first_name, last_name 
(USERNAME_FIELD = 'email)

django-authtools uses defines three models: 

A. AbstractUserMail (with one field 'email', like emailuser),
B. AbstractNamedUser, derived from AbstractUserMail with an additional 
field "name". 
C. User, derived from AbstractNamedUser, which is swappable and 
non-abstract.

2. django-authtools has tests, emailuser doesn't

3. django-authtools is documented, emailuser doesn't

4. django-authtools implements views, emailuser doesn't.

5. they have different licences, but I don't know enough about them to know 
what are the differences.

6. django-authtools passes on travis-ci.org tests, and, as far as I know, 
enforces clean commit history (don't know if it is relevant thought).

7. usermail has a form to ask reset-password (by email?), but I didn't found 
any implementation of the actual reset.


Tom, would you be willing to provide the differences and similarities of your 
API with django-authtools and emailuser, or teach me how can I compare it 
against django-master so I can make a comparison?
It would be nice to have your API documented here so we can take the most out 
of the all existing implementations.

Best regards,
Jorge

On Sep 16, 2013, at 10:04 PM, tanderegg  wrote:

> Hey folks - I took a crack at implementing this, please check out my comment 
> here (which contains a link to the branch in my fork): 
> https://code.djangoproject.com/ticket/20824#comment:4
> 
> Let me know if I missed anything!
> 
> Tim
> 
> On Friday, September 13, 2013 1:03:23 AM UTC-4, Aaron Merriam wrote:
> Check out django-authtools
> 
> https://django-authtools.readthedocs.org/en/latest/
> 
> Provides a few abstract base classes that make this very easy to accomplish.  
> I'm sure there are other 3rd party apps doing the same.
> 
> 
> On Thursday, September 12, 2013 2:44:53 PM UTC-6, Abdulaziz Alfoudari wrote:
> This is a continuation of my post on stackoverflow.
> 
> With the introduction of Django 1.5, it was possible to create a custom User 
> model which is flexible enough to have any user profile the developer wants 
> created. However, looking at a very common problem which is using the email 
> as the primary user identifier instead of username, the solution requires 
> copying most of Django's internal definition of AbstractUser and that is only 
> to remove the username field.
> 
> A better solution in my opinion is make AbstractUser even more abstract by 
> removing username field, and allowing the developer to explicitly specify the 
> field to be used as the user identifier. This will require a tiny extra work 
> for those that use the current default behavior, but it will also greatly 
> re

Re: Benchmarking 1.5 vs 1.6

2013-09-17 Thread Marc Tamlyn
Can't say I'm hugely worried about perfect tracebacks and introspection
with internal kind of functions here if it affects performance. The patch
looks good. I'd add a comment to say why we're not using @wraps in that
context though so someone doesn't go back and add it.
On 17 Sep 2013 07:57, "Anssi Kääriäinen"  wrote:

> I did some investigation to query_iterator, and most of the slowdown is
> caused by functools.wraps. When used in nested context @wraps seems to be
> really slow. For example, try this with and without @wraps:
> http://pastebin.com/5ejAKuKd
>
> Should we care about this slowdown? Can we do without @wraps? My
> understanding is that @wraps gives you __name__, __module__ and __doc__
> which are easy to do manually. In addition it gives introspection the right
> args and kwargs for the wrapped function (so that IDEs see it correctly).
> This will be a lot harder to do manually, and doing so will likely result
> in similar slowdown.
>
> The biggest hit case is if somebody is looping over a raw SQL queryset
> with .fetchone(). This use case will be severely punished. Even .execute();
> .fetchmany() has a 1.5x slowdown (the benchmark is this one:
> https://github.com/django/djangobench/commit/94fc28d99f95c65d26d0fad8af44e46c49282220-
>  simple SELECT + fetchall() for the ten returned rows.
>
> I have created a patch that removes the usage of @wraps and makes
> connection.wrap_database_errors a cached_property. The cached_property
> should be safe as the context manager created by wrap_database_errors is
> stateless. This patch gets rid of the slowdown (1.00-1.05x slower in
> repeated runs for raw_sql benchmark). With just removed @wraps the slowdown
> is 1.1x. The patch is here:
> https://github.com/akaariai/django/commit/eafc373c16350abe51c565c8aefbe36cabf5219e
>
> Should I apply the patch, and should I apply it to stable/1.6.x, too?
> Removal of @wraps is really low risk, usage of @cached_property is also low
> risk, but not as low as removal of @wraps.
>
>  - Anssi
>
> On Saturday, September 14, 2013 9:21:43 PM UTC+3, Anssi Kääriäinen wrote:
>>
>> I just ran djangobench comparing 1.5 to 1.6. The biggest thing seems to
>> be form_create bechmark, the average is 15x slower. But for some reason the
>> minimum runtime is just 1.16x slower. This seems a bit strange. This might
>> be worth more investigation.
>>
>> Otherwise there doens't seem to be anything alarming going on. Most ORM
>> operations are slightly faster (likely due to __deepcopy__ removal).
>>
>> There are a couple of individual benchmarks worth mentioning...
>> url_reverse and query_iterator are slower (1.15x and 1.12x respectively).
>> The default_middleware and qs_filter_chaining benchmarks have gained a lot
>> (2.0x and 3.1x respectively). model_save_existing/model_**save_new are
>> faster (2x+), but model_creation is slightly slower. I suspect there is
>> something going on with connection creation or transactions for
>> model_creation, after all model_creation is a convenience method for
>> model.__init__ + model_save_new which both aren't slower.
>>
>> What else? url_reverse and template compliation under i18n slightly
>> slower. For the rest of benchmarks, see below.
>>
>> Running 'default_middleware' benchmark ...
>> Min: 0.001260 -> 0.000554: 2.2755x faster
>> Avg: 0.001389 -> 0.000681: 2.0394x faster
>> Significant (t=8.222155)
>> Stddev: 0.00037 -> 0.00048: 1.2843x larger (N = 50)
>>
>> Running 'form_clean' benchmark ...
>> Min: 0.42 -> 0.42: no change
>> Avg: 0.49 -> 0.43: 1.1341x faster
>> Not significant
>> Stddev: 0.4 -> 0.1: 6.6718x smaller (N = 50)
>>
>> Running 'form_create' benchmark ...
>> Min: 0.85 -> 0.99: 1.1657x slower
>> Avg: 0.88 -> 0.001396: 15.8410x slower
>> Not significant
>> Stddev: 0.1 -> 0.00916: 783.3314x larger (N = 50)
>>
>> Running 'l10n_render' benchmark ...
>> Min: 0.011702 -> 0.014151: 1.2093x slower
>> Avg: 0.012200 -> 0.014846: 1.2169x slower
>> Significant (t=-4.824893)
>> Stddev: 0.00233 -> 0.00310: 1.3311x larger (N = 50)
>>
>> Running 'model_creation' benchmark ...
>> Min: 0.000311 -> 0.000400: 1.2860x slower
>> Avg: 0.000336 -> 0.000432: 1.2840x slower
>> Significant (t=-2.799691)
>> Stddev: 0.00015 -> 0.00019: 1.2751x larger (N = 50)
>>
>> Running 'model_delete' benchmark ...
>> Min: 0.000407 -> 0.000468: 1.1500x slower
>> Avg: 0.000423 -> 0.000484: 1.1440x slower
>> Significant (t=-7.131460)
>> Stddev: 0.5 -> 0.4: 1.1807x smaller (N = 50)
>>
>> Running 'model_save_existing' benchmark ...
>> Min: 0.062923 -> 0.021829: 2.8826x faster
>> Avg: 0.063206 -> 0.022001: 2.8729x faster
>> Significant (t=793.026302)
>> Stddev: 0.00034 -> 0.00014: 2.3570x smaller (N = 50)
>>
>> Running 'model_save_new' benchmark ...
>> Min: 0.041341 -> 0.021819: 1.8947x faster
>> Avg: 0.063127 -> 0.022379: 2.8208x faster
>> Significant (t=76.086085)
>> Stddev: 0.00344 -> 0.00158: 2.1770x smaller (N = 50)
>>
>> Running 'multi_value_dict' benchmark ...
>> Min: 0.000