2013-06-13 1 views
8

업데이트 :이 포스트의 하단에 디버깅 정보가 추가되어 파이썬 상태가 매우 불안해졌습니다.임포트 된 모듈은 아무 기능도 수행하지 않습니다.

다른 것들 중에서 django User 객체를 가져 오는 모듈이 있습니다.

가져 오기가 정상적으로 작동하며 코드가로드됩니다. 그러나 User 객체를 사용하는 모듈에서 함수를 호출하면 User가 NoneType이라는 오류가 발생합니다.

기타 많은 가져 오기가 있으며 모듈 수준의 전역 변수도 있으며 함수가 호출 될 때까지 없음입니다.

이상하게도 이것은 준비 환경 (우분투 12.04)에서만 문제가됩니다. 그것은 로컬에서 잘 작동하는데, 아마도 dev 작업을위한 여분의 파이썬 패키지를 사용하여 준비 작업과 가장 유사 할 것입니다. 프로덕션에서도 괜찮습니다.

아무도 이런 문제를 경험하지 못했고 어떤 아이디어가 있었습니까?

여기에 코드입니다 :

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() 

여기 당신이 함수 내에서 다시 필요 가져올 기본적으로 의미하는 주변의 일을이다 :

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() 

여기 스택 추적입니다. 이 오류는 generate_random_codes 함수의

key = User.objects.make_random_password(length=KEY_SIZE) 

행에 의해 발생합니다.

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' 

업데이트 : 그것은 단지 사용자 개체를 삭제하는 것이 아니다 - 어떤 함수의 전체 문맥을 부수고있다. 이러한 인쇄 문으로

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) 

, 출력은 : 내가 생각 모두 __package____name__가 정의되지

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': <class 'pycassa.columnfamilymap.ColumnFamilyMap'>, 'datetime': <type 'datetime.datetime'>, 'KEY_SIZE': 18, 'NonceType': <class 'piston.models.NonceType'>, 'OAuthToken': <class 'piston.models.OAuthToken'>, 'TokenManager': <class 'piston.managers.TokenManager'>, 'ConsistencyLevel': <class 'pycassa.cassandra.ttypes.ConsistencyLevel'>, 'Nonce': <class 'piston.models.Nonce'>, 'uuid': <module 'uuid' from '/usr/lib/python2.7/uuid.pyc'>, ...} 

주, 거의 불가능했다, 그 동안의 sys.modules에 버전 모듈에 올바른 __dict__이 있으면 globals()의 반환 값은 의미가 없습니다.

+1

예외를 throw하는 코드와 전체 추적을 표시하십시오. –

+0

모델에서 오류가 발생하지 않았습니까? 흔적을 보여주십시오. –

+0

감사합니다. 스택 추적 및 오류를 발생시키는 라인이 추가되었습니다. –

답변

7

이것은 모듈이 가비지 수집 된 후에도 여전히 실행중인 가져온 모듈의 함수에서 발생합니다.

코드가 문제를 재현하기에 충분하지 않기 때문에 다음은 동작을 보여주는 간단한 예제입니다. 다음을 포함하는 파일을 만들고이를 Python 명령 줄 또는 다른 파일에서 가져옵니다. 최상위 수준에서 을 실행하면 작동하지 않습니다. 그것을 실행

import sys 
import threading 

x = "foo" 

def run(): 
    while True: 
     print "%s %s\n" % (sys, x) 

threading.Thread(target = run).start() 
sys.stdin.readline() 

는 : 파이썬 종료하는 동안

$ python 
>>> import evil_threading 
<module 'sys' (built-in)> foo 

<module 'sys' (built-in)> foo 
... press Ctrl-C 
None None 

None None 
... press Ctrl-\ to kill the Python interpreter 

, 모듈은 None으로 설정됩니다. This is an obscure Python behaviour that was removed in 3.4. 이 예에서는 주 스레드를 종료하면 종료되지만 다른 스레드는 여전히 실행 중이므로 모듈은 None으로 표시됩니다.

from here이라는 간단한 예제가 있으며 sys.modules에서 모듈 참조를 직접 삭제하여 똑같은 작업을 수행합니다.

import sys 
print sys 
del sys.modules['__main__'] 
print sys 
관련 문제