title: Imported modules become None when running a function
body: <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>