Opened 11 years ago

Closed 11 years ago

Last modified 11 years ago

#19745 closed Bug (fixed)

Wrong prompt for `createuser` management command (<django.utils.functional.__proxy__ object at ...>)

Reported by: Baptiste Mispelon Owned by: nobody
Component: contrib.auth Version: 1.5-beta-1
Severity: Release blocker Keywords: createuser repr py3
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: yes Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Using a fresh checkout, I created a new project, using all the default settings (except for DATABASES).

When running syncdb for the first time (or running createsuperuser anytime), the prompts are wrong.

Here's what it looks like with python 2.7:

$ python manage.py createsuperuser
<django.utils.functional.__proxy__ object at 0x7fe4c341a850> (leave blank to use 'bmispelon'): newuser
<django.utils.functional.__proxy__ object at 0x29d8c10>: foo@example.com
Password: 
Password (again): 
Superuser created successfully.


$ python manage.py createsuperuser
<django.utils.functional.__proxy__ object at 0x7f7717aed850> (leave blank to use 'bmispelon'): newuser
Error: That <django.utils.functional.__proxy__ object at 0x1d45ad0> is already taken.
<django.utils.functional.__proxy__ object at 0x7f7717aed850> (leave blank to use 'bmispelon'): ^C
Operation cancelled.

By comparison, here is what it looks like using python 3.2 (correct output):

$ python3 manage.py createsuperuser
Username (leave blank to use 'bmispelon'): newuser2
Email address: foo@example.com
Password: 
Password (again): 
Superuser created successfully.


$ python3 manage.py createsuperuser
Username (leave blank to use 'bmispelon'): newuser2
Error: That username is already taken.
Username (leave blank to use 'bmispelon'): ^C
Operation cancelled.

There are three issues here:

1) The name of the username field is displayed wrong
2) The name of the email field is displayed wrong
3) The error message when using an existing username is wrong.

The code in question is located in django/contrib/auth/management/commands/createsuperuser.py.
The first two were introduced by commit 55c585f1c7a9c91308193f0648caf36203174564 while the third one was introduced with an older one: b3b3db3d954a5226f870a0b4403343c78efae8dc

The issue can be fixed by wrapping the strings being formatted with six.u, like so:

from django.utils.six import u
# ...
input_msg = u("%s (leave blank to use '%s')") % (input_msg, default_username) # L87

However, I'm not sure of the implications of such a fix.

Attachments (3)

19745.diff (1.8 KB ) - added by Preston Holmes 11 years ago.
This patch fixes the symptoms - not sure how to test yet as I'm not sure what part of the current tests were resolving the lazy object in the output before - not sure.
testproject.tgz (4.1 KB ) - added by Preston Holmes 11 years ago.
test project that works in both py2 and py3 with earlier patch
19745-2.diff (3.5 KB ) - added by Claude Paroz 11 years ago.

Download all attachments as: .zip

Change History (13)

comment:1 by Aymeric Augustin, 11 years ago

Severity: NormalRelease blocker
Triage Stage: UnreviewedAccepted

Django should resolve lazy translations here.

Forcing unicode isn't the right solution because stdout is bytes in Python 2 and unicode in Python 3; wrapping in str() should work (to be tested).

Marking as a release blocker since the third bug is in 1.5 beta 1.

comment:2 by Baptiste Mispelon, 11 years ago

Actually the first two are present in 1.5b as well.

The commit is a different one though (not sure why): f5232597ea31bf274b02983f32ba89be4f7bf02b.

Is the problem the fact that lazy translations define __unicode__ and not __str__, which therefore falls back on using __repr__?

comment:3 by Aymeric Augustin, 11 years ago

Yes that's the problem.

Unfortunately these lazy translations are in user code, not in Django; otherwise we'd just use gettext instead of ugettext.

by Preston Holmes, 11 years ago

Attachment: 19745.diff added

This patch fixes the symptoms - not sure how to test yet as I'm not sure what part of the current tests were resolving the lazy object in the output before - not sure.

comment:4 by Preston Holmes, 11 years ago

Has patch: set
Needs tests: set

comment:5 by Preston Holmes, 11 years ago

stumped on testing - the call_command setting stdout and the associated OutputWrapper in BaseCommand.execute is not accessible to write the prompt to from inside the test or the test decorator.

by Preston Holmes, 11 years ago

Attachment: testproject.tgz added

test project that works in both py2 and py3 with earlier patch

by Claude Paroz, 11 years ago

Attachment: 19745-2.diff added

comment:6 by Claude Paroz, 11 years ago

Just attached my suggested fix. Preston's patch was in the right direction, but the removal of force_str is wrong, in my opinion (as input does need an encoded string on Python 2).

comment:7 by Preston Holmes, 11 years ago

Triage Stage: AcceptedReady for checkin

The assert is a great way to sort out the what is in the prompt (I was stuck in coming at it from the test funcs perspective). And the patch looks solid in all other ways.

comment:8 by Claude Paroz <claude@…>, 11 years ago

Resolution: fixed
Status: newclosed

In 2390fe3f4f8f52e24157d79b0c60247207c9716f:

Fixed #19745 -- Forced resolution of verbose names in createsupersuser

Thanks Baptiste Mispelon for the report and Preston Holmes for the review.

comment:9 by Claude Paroz <claude@…>, 11 years ago

In 933e956ba4b1ad5f8823f0a294ffc795e949edf1:

[1.5.x] Fixed #19745 -- Forced resolution of verbose names in createsupersuser

Thanks Baptiste Mispelon for the report and Preston Holmes for the review.
Backport of 2390fe3f4 from master.

comment:10 by Claude Paroz <claude@…>, 11 years ago

In 933e956ba4b1ad5f8823f0a294ffc795e949edf1:

[1.5.x] Fixed #19745 -- Forced resolution of verbose names in createsupersuser

Thanks Baptiste Mispelon for the report and Preston Holmes for the review.
Backport of 2390fe3f4 from master.

Note: See TracTickets for help on using tickets.
Back to Top