必须使用LocaleRegexProvider实例作为第一个参数调用未绑定的方法__init __()(改为使用RegexURLPattern实例)

时间:2012-02-22 11:56:09

标签: python django

我正在研究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。我在这里缺少什么?

1 个答案:

答案 0 :(得分:4)

问题在于reload()函数,您在测试中使用该函数来重新加载网址设置。根据文件:

  

与Python中的所有其他对象一样旧   只有在引用计数降为零后才会回收对象。   模块命名空间中的名称将更新为指向任何新的或   改变了对象。对旧对象的其他引用(例如名称   模块外部)不会反弹以引用新对象   并且必须在它们出现的每个命名空间中进行更新(如果是)   期望的。

所以你正在重新加载urlresolvers模块,但这不是副作用的。来自旧urlresolvers的对象不会被reload销毁。在某些时候,你在内存实例中有两个RegexURLPattern类的副本。这些是不同的类(类对象),在代码中具有完全相同的名称和位置。当新RegexURLPattern类的对象不是旧RegexURLPattern对象的实例,并且无法调用它的基类构造函数时,这会导致您看到的错误。