Opened 10 years ago

Closed 10 years ago

#22592 closed Bug (invalid)

AbstractBaseUser.__str__ may return non-string (None)

Reported by: david.fischer.ch@… Owned by: nobody
Component: contrib.auth Version: dev
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Tested under Python 3.

I am writing unit-tests to ensure my custom signal handler works well.
The signal handler is registered to pre_save with sender=AUTH_USER_MODEL and it calls str(instance).

In one of the tests I set user's username to None and save the model, ...

user = User.objects.create(username='sam.fisher', first_name='Sam', last_name='Fisher', password='i_am_the_boss')

user.username = None
user.save()

pre_save signal handler:

...
str(instance)
...

Traceback (most recent call last):

File "/home/ubuntu/cloudncode_test/server/cloudncode_base/tests/test_models.py", line 44, in test_strip_none_works

self.user.save()

File "/home/ubuntu/cloudncode_test/venv/src/django/django/db/models/base.py", line 602, in save

force_update=force_update, update_fields=update_fields)

File "/home/ubuntu/cloudncode_test/venv/src/django/django/db/models/base.py", line 626, in save_base

update_fields=update_fields)

File "/home/ubuntu/cloudncode_test/venv/src/django/django/dispatch/dispatcher.py", line 198, in send

response = receiver(signal=self, sender=sender, named)

File "/home/ubuntu/cloudncode_test/server/cloudncode_base/models/signals.py", line 55, in strip_strings_and_validate_model

i = str(instance)

TypeError: str returned non-string (type NoneType)

Change History (3)

comment:1 by Tim Graham, 10 years ago

Doesn't look like a bug in Django to me... the exception is thrown by cloudncode_base/models/signals.py. Am I missing something?

comment:2 by david.fischer.ch@…, 10 years ago

Calling str(instance) is what triggered the faulty code.

I guess Python 3 does not allow implementing a str method that something that is not an instance of str.

david@n750jv:~$ python3
Python 3.4.0 (default, Apr 11 2014, 13:05:11) 
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> str(None)
'None'
>>> class Test(object):
...  def __str__(self):
...   return None
... 
>>> Test()
<__main__.Test object at 0x7fd076e4f860>
>>> str(Test())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __str__ returned non-string (type NoneType)
>>> 


comment:3 by Tim Graham, 10 years ago

Resolution: invalid
Status: newclosed

Right, a __str__() method must return a string, not None. I'm still not convinced what you are doing merits a change to Django as a username of None doesn't seem to make sense (could you just as easily use an empty string instead?). Please reopen with further justification is you disagree.

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