Opened 6 years ago
Closed 6 years ago
Last modified 6 years ago
#19745 closed Bug (fixed)
Wrong prompt for `createuser` management command (<django.utils.functional.__proxy__ object at ...>)
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 Changed 6 years ago by
comment:2 Changed 6 years ago by
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 Changed 6 years ago by
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.
Changed 6 years ago by
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 Changed 6 years ago by
comment:5 Changed 6 years ago by
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.
Changed 6 years ago by
test project that works in both py2 and py3 with earlier patch
Changed 6 years ago by
comment:6 Changed 6 years ago by
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 Changed 6 years ago by
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.
Django should resolve lazy translations here.
Forcing unicode isn't the right solution because
stdoutis 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.