Note that there are some explanatory texts on larger screens.

plurals
  1. POImported modules become None when running a function
    text
    copied!<p><strong>Update</strong>: some more debugging info at the bottom of this post, which reveals something very screwy in the python state.</p> <p>I have a module which imports, among other things, the django User object.</p> <p>The import works fine, and the code loads. However, when you call a function in that module that uses the User object, it errors saying that User is a NoneType.</p> <p>There are also a number of other imports, and some module level global variables which are also None by the time the function is called.</p> <p>Oddly, this is only a problem in our staging environments (Ubuntu 12.04). It works fine locally, which probably most closely resembles staging with extra python packages for dev work. Also fine in production.</p> <p>Has anyone come across this before, and have any ideas what might cause it?</p> <p>Here's the code:</p> <pre><code>import urllib import time import urlparse # Django imports from django.db.models.signals import post_delete from django.db import models from django.contrib.auth.models import User from backends.cache.dualcache import cache # Piston imports from managers import TokenManager, ConsumerManager from signals import consumer_post_delete KEY_SIZE = 18 SECRET_SIZE = 32 VERIFIER_SIZE = 10 CONSUMER_STATES = ( ('pending', 'Pending'), ('accepted', 'Accepted'), ('canceled', 'Canceled'), ('rejected', 'Rejected') ) def generate_random(length=SECRET_SIZE): return User.objects.make_random_password(length=length) class Consumer(models.Model): name = models.CharField(max_length=255) description = models.TextField() key = models.CharField(max_length=KEY_SIZE) secret = models.CharField(max_length=SECRET_SIZE) status = models.CharField(max_length=16, choices=CONSUMER_STATES, default='pending') objects = ConsumerManager() def __unicode__(self): return u"Consumer %s with key %s" % (self.name, self.key) def generate_random_codes(self): key = User.objects.make_random_password(length=KEY_SIZE) secret = generate_random(SECRET_SIZE) while Consumer.objects.filter(key__exact=key, secret__exact=secret).count(): secret = generate_random(SECRET_SIZE) self.key = key self.secret = secret self.save() </code></pre> <p>and here's the work around, which means basically to import what you need again inside the function:</p> <pre><code>import urllib import time import urlparse # Django imports from django.db.models.signals import post_delete from django.db import models from django.contrib.auth.models import User from backends.cache.dualcache import cache # Piston imports from managers import TokenManager, ConsumerManager from signals import consumer_post_delete KEY_SIZE = 18 SECRET_SIZE = 32 VERIFIER_SIZE = 10 CONSUMER_STATES = ( ('pending', 'Pending'), ('accepted', 'Accepted'), ('canceled', 'Canceled'), ('rejected', 'Rejected') ) def generate_random(length=SECRET_SIZE): return User.objects.make_random_password(length=length) class Consumer(models.Model): name = models.CharField(max_length=255) description = models.TextField() key = models.CharField(max_length=KEY_SIZE) secret = models.CharField(max_length=SECRET_SIZE) status = models.CharField(max_length=16, choices=CONSUMER_STATES, default='pending') objects = ConsumerManager() def __unicode__(self): return u"Consumer %s with key %s" % (self.name, self.key) def generate_random_codes(self): from piston.models import KEY_SIZE, SECRET_SIZE, Consumer from django.contrib.auth.models import User from piston.models import generate_random key = User.objects.make_random_password(length=KEY_SIZE) secret = generate_random(SECRET_SIZE) while Consumer.objects.filter(key__exact=key, secret__exact=secret).count(): secret = generate_random(SECRET_SIZE) self.key = key self.secret = secret self.save() </code></pre> <p>Here's the stack trace. The error is caused by the line:</p> <pre><code>key = User.objects.make_random_password(length=KEY_SIZE) </code></pre> <p>in the generate_random_codes function.</p> <pre><code>Traceback: File "/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response 111. response = callback(request, *callback_args, **callback_kwargs) File "/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/contrib/admin/options.py" in wrapper 366. return self.admin_site.admin_view(view)(*args, **kwargs) File "/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view 91. response = view_func(request, *args, **kwargs) File "/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/views/decorators/cache.py" in _wrapped_view_func 89. response = view_func(request, *args, **kwargs) File "/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/contrib/admin/sites.py" in inner 196. return view(request, *args, **kwargs) File "/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapper 25. return bound_func(*args, **kwargs) File "/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view 91. response = view_func(request, *args, **kwargs) File "/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/utils/decorators.py" in bound_func 21. return func(self, *args2, **kwargs2) File "/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/db/transaction.py" in inner 224. return func(*args, **kwargs) File "/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/contrib/admin/options.py" in add_view 970. form = ModelForm(initial=initial) File "/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/forms/models.py" in __init__ 234. self.instance = opts.model() File "/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/db/models/base.py" in __init__ 349. val = field.get_default() File "/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/db/models/fields/related.py" in get_default 983. field_default = super(ForeignKey, self).get_default() File "/sites/tellybug/shared/webserver/local/lib/python2.7/site-packages/django/db/models/fields/__init__.py" in get_default 379. return self.default() File "/sites/tellybug/releases/b92109dd526607b2af92ad6b7f494f3f06e31bb2/webserver/tellybug/tbapp/models/tellybugapp.py" in generate_new_consumer 11. consumer.generate_random_codes() File "/sites/tellybug/releases/b92109dd526607b2af92ad6b7f494f3f06e31bb2/webserver/tellybug/piston/models.py" in generate_random_codes 57. key = User.objects.make_random_password(length=KEY_SIZE) Exception Type: AttributeError at /admin/tbapp/tellybugapp/add/ Exception Value: 'NoneType' object has no attribute 'objects' </code></pre> <p><strong>Update</strong>: It's not something just deleting the User object - something is wrecking the entire context in the function.</p> <pre><code>def generate_random_codes(self): """ Used to generate random key/secret pairings. Use this after you've added the other data in place of save(). c = Consumer() c.name = "My consumer" c.description = "An app that makes ponies from the API." c.user = some_user_object c.generate_random_codes() """ import sys print "Globals", globals() print "Name ", __name__ print "Package ", __package__ print "Sys modules", sys.modules['piston.models'].__dict__ key = User.objects.make_random_password(length=KEY_SIZE) </code></pre> <p>With these print statements, the output is:</p> <pre><code>Globals {'ColumnFamilyMap': None, 'datetime': None, 'KEY_SIZE': None, 'TokenManager': None, 'ConsistencyLevel': None, 'Nonce': None, 'uuid': None, 'cache': None, 'urllib': None, '__package__': None, 'models': None, 'User': None, .... } Name None Package None Sys modules {'ColumnFamilyMap': &lt;class 'pycassa.columnfamilymap.ColumnFamilyMap'&gt;, 'datetime': &lt;type 'datetime.datetime'&gt;, 'KEY_SIZE': 18, 'NonceType': &lt;class 'piston.models.NonceType'&gt;, 'OAuthToken': &lt;class 'piston.models.OAuthToken'&gt;, 'TokenManager': &lt;class 'piston.managers.TokenManager'&gt;, 'ConsistencyLevel': &lt;class 'pycassa.cassandra.ttypes.ConsistencyLevel'&gt;, 'Nonce': &lt;class 'piston.models.Nonce'&gt;, 'uuid': &lt;module 'uuid' from '/usr/lib/python2.7/uuid.pyc'&gt;, ...} </code></pre> <p>Note that both <code>__package__</code> and <code>__name__</code> are undefined, which I thought was pretty much impossible, and that while the sys.modules version of the module has a correct <code>__dict__</code>, the return value from <code>globals()</code> is nonsense.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload