1

So, yesterday I posted a problem with a class method I was having (Can an object method return an instance of the object?) and the answer was "You can change it to a class method if you like, but there's no reason your code shouldn't work as it is." Changing it to a class method worked, so I moved on with my life. Now I'm having another problem where the below method (same class) didn't work, telling me that 'NoneType' object has no attribute 'objects'. I jumped into the debugger, and the exact same code worked fine when entered manually. I moved the import User line from the top of the file into the function itself, and now it works. This is the only place in the file where the User class is used. Person and User are not linked with a foreign key relationship--they just share a username and we do the lookup that way.

I should also add that both of these methods worked fine up until a few days ago, and I haven't been able to find any alterations of them in our commit history.

Class Person(models.Model):

    def to_user(self):
        '''returns user linked to Person or None(needed for some third
            party packages)'''
        try:
            from django.contrib.auth.models import User
            return User.objects.get(username=str(self.username))
        except ObjectDoesNotExist:
            print("No associated user found using username {0}".format(self.username))
            return None
Community
  • 1
  • 1
thumbtackthief
  • 6,093
  • 10
  • 41
  • 87
  • So, where else in your code do you do `User = None` then? – Martijn Pieters May 16 '14 at 17:49
  • If all you changed was *move* the import, then *at some point* your module global `User` was rebound to `None`, for that exception to occur. You'll need to figure out where that point is. – Martijn Pieters May 16 '14 at 17:50
  • Nowhere! Yesterday (see linked question) they accused me of the same thing (setting Person=None in that case) but I couldn't find anything like it. Also, if I had, I can't see why changing it to a class method would have fixed the problem. – thumbtackthief May 16 '14 at 17:51
  • Not finding it is not the same thing as it not happening though. Note that even `sys.modules['your.module.name'].User = None` would qualify (e.g. something *outside* of the module tampering with the module globals). – Martijn Pieters May 16 '14 at 17:53
  • I'll check, but, question: Wouldn't moving it trip an error, then, as I'd be referencing something I hadn't yet imported? – thumbtackthief May 16 '14 at 17:53
  • (I did a search across my entire code base for `User = None`. I found it in one unrelated file, commented out the entire file, and reran my code. Same error (with the import statement moved back to the top)) – thumbtackthief May 16 '14 at 17:55
  • Setting globals to `None` appears to be a more prevalent problem in your code, however. The rebinding doesn't necessarily take place with such a blatant statement; `import somemodule; for key in vars(somemodule): setattr(somemodule, key, None)` would rebind all global names in that module to `None`. – Martijn Pieters May 16 '14 at 18:03
  • These are just examples; but you now have run twice into exceptions where a global in your module has been rebound to `None`. – Martijn Pieters May 16 '14 at 18:04
  • You are not, by any chance, running code triggered by a `__del__` hook are you? That would also run when the Python interpreter shuts down, and until Python 3.4, module globals were rebound to `None` at that time to prevent circular references from messing up tearing down the modules. – Martijn Pieters May 16 '14 at 18:05
  • I can be certain I didn't write anything like that (because I have no idea what you're talking about) but someone else on my team might have. I'll investigate. For what it's worth, both of those problems occurred in methods on the same model (Person) and methods relating it to User. – thumbtackthief May 16 '14 at 19:03

1 Answers1

0

Because I had a circular import.

thumbtackthief
  • 6,093
  • 10
  • 41
  • 87