我正在研究a patch for django-localeurl,我遇到了困扰我的问题。为了测试我的补丁添加的功能,我添加了一些测试,当我针对Django trunk运行它时会触发此错误(旧版本没问题):
Traceback (most recent call last):
File "/home/al/dev/projects/django-localeurl/localeurl/tests/tests.py", line 498, in test_change_locale_check_session_disabled
self.client.post('/change/', data={'locale': 'de', 'next': '/foo'})
File "/home/al/dev/projects/django-localeurl/.tox/py26-trunk/lib/python2.6/site-packages/django/test/client.py", line 449, in post
response = super(Client, self).post(path, data=data, content_type=content_type, **extra)
File "/home/al/dev/projects/django-localeurl/.tox/py26-trunk/lib/python2.6/site-packages/django/test/client.py", line 262, in post
return self.request(**r)
File "/home/al/dev/projects/django-localeurl/.tox/py26-trunk/lib/python2.6/site-packages/django/test/client.py", line 381, in request
response = self.handler(environ)
File "/home/al/dev/projects/django-localeurl/.tox/py26-trunk/lib/python2.6/site-packages/django/test/client.py", line 84, in __call__
response = self.get_response(request)
File "/home/al/dev/projects/django-localeurl/.tox/py26-trunk/lib/python2.6/site-packages/django/core/handlers/base.py", line 179, in get_response
response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
File "/home/al/dev/projects/django-localeurl/.tox/py26-trunk/lib/python2.6/site-packages/django/core/handlers/base.py", line 224, in handle_uncaught_exception
if resolver.urlconf_module is None:
File "/home/al/dev/projects/django-localeurl/.tox/py26-trunk/lib/python2.6/site-packages/django/core/urlresolvers.py", line 323, in urlconf_module
self._urlconf_module = import_module(self.urlconf_name)
File "/home/al/dev/projects/django-localeurl/.tox/py26-trunk/lib/python2.6/site-packages/django/utils/importlib.py", line 35, in import_module
__import__(name)
File "/home/al/dev/projects/django-localeurl/localeurl/urls.py", line 5, in <module>
url(r'^change/', change_locale, name='localeurl_change_locale'),
File "/home/al/dev/projects/django-localeurl/.tox/py26-trunk/lib/python2.6/site-packages/django/conf/urls/__init__.py", line 60, in url
return RegexURLPattern(regex, view, kwargs, name)
File "/home/al/dev/projects/django-localeurl/.tox/py26-trunk/lib/python2.6/site-packages/django/core/urlresolvers.py", line 172, in __init__
LocaleRegexProvider.__init__(self, regex)
TypeError: unbound method __init__() must be called with LocaleRegexProvider instance as first argument (got RegexURLPattern instance instead)
但是当我读到the code that triggers this exception时,我看不出这是怎么发生的。为了理解这种情况,我将那些打印语句添加到调用基类__init__
的行上方:
print
print "self.__class__:", self.__class__
print "self.__class__.__bases__:", self.__class__.__bases__
print "isinstance(self, LocaleRegexProvider):", isinstance(self, LocaleRegexProvider)
print
LocaleRegexProvider.__init__(self, regex)
在某些情况下,这会给我预期的输出:
self.__class__: <class 'django.core.urlresolvers.RegexURLPattern'>
self.__class__.__bases__: (<class 'django.core.urlresolvers.LocaleRegexProvider'>,)
isinstance(self, LocaleRegexProvider): True
但在某些情况下,它给了我这个奇怪的结果:
self.__class__: <class 'django.core.urlresolvers.RegexURLPattern'>
self.__class__.__bases__: (<class 'django.core.urlresolvers.LocaleRegexProvider'>,)
isinstance(self, LocaleRegexProvider): False
最初我认为Django的其他部分可能会动态更改RegexURLPattern
实例的基类(此处称为self
),这会在调用{{1}时引发异常}。我的假设似乎被LocaleRegexProvider.__init__
的结果所证实,但打印出isinstance
与此相矛盾。我认为如果__bases__
在基类列表中,LocaleRegexProvider
应该始终返回isinstance
。我在这里缺少什么?
答案 0 :(得分:4)
问题在于reload()函数,您在测试中使用该函数来重新加载网址设置。根据文件:
与Python中的所有其他对象一样旧 只有在引用计数降为零后才会回收对象。 模块命名空间中的名称将更新为指向任何新的或 改变了对象。对旧对象的其他引用(例如名称 模块外部)不会反弹以引用新对象 并且必须在它们出现的每个命名空间中进行更新(如果是) 期望的。
所以你正在重新加载urlresolvers
模块,但这不是副作用的。来自旧urlresolvers
的对象不会被reload
销毁。在某些时候,你在内存实例中有两个RegexURLPattern
类的副本。这些是不同的类(类对象),在代码中具有完全相同的名称和位置。当新RegexURLPattern
类的对象不是旧RegexURLPattern
对象的实例,并且无法调用它的基类构造函数时,这会导致您看到的错误。