#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)
Change History (13)
comment:1 by , 12 years ago
Severity: | Normal → Release blocker |
---|---|
Triage Stage: | Unreviewed → Accepted |
comment:2 by , 12 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 , 12 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 , 12 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 , 12 years ago
Has patch: | set |
---|---|
Needs tests: | set |
comment:5 by , 12 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 , 12 years ago
Attachment: | testproject.tgz added |
---|
test project that works in both py2 and py3 with earlier patch
by , 12 years ago
Attachment: | 19745-2.diff added |
---|
comment:6 by , 12 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 , 12 years ago
Triage Stage: | Accepted → Ready 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 , 12 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
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 instr()
should work (to be tested).Marking as a release blocker since the third bug is in 1.5 beta 1.