несвязанный метод __init __ () должен вызываться с экземпляром LocaleRegexProvider в качестве первого аргумента (вместо этого получен экземпляр RegexURLPattern) - PullRequest
2 голосов
/ 22 февраля 2012

Я работаю над патчем для django-localeurl , и я столкнулся с проблемой, которая озадачивает меня.Чтобы проверить функциональность, добавленную моим патчем, я добавил тесты, которые вызывают эту ошибку, когда я запускаю их для транка Django (без проблем со старыми версиями):

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)

Но когда я читаю код, который вызывает это исключение , я не вижу, как это может произойти.Чтобы понять ситуацию, я добавил операторы print над строкой, где вызывается база __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)., что вызывает исключение при вызове LocaleRegexProvider.__init__.Мое предположение, кажется, подтверждается результатом isinstance, но распечатка __bases__ противоречит этому.Я думал, что если LocaleRegexProvider находится в списке базовых классов, isinstance всегда должно возвращать True.Что мне здесь не хватает?

1 Ответ

4 голосов
/ 22 февраля 2012

Проблема заключается в функции reload () , которую вы используете в своих тестах для перезагрузки настроек URL. Согласно документации:

Как и все остальные объекты в Python, старые объекты восстанавливаются только после того, как их число ссылок упадет до нуля. Имена в пространстве имен модуля обновляются, чтобы указывать на любой новый или измененные объекты. Другие ссылки на старые объекты (например, имена внешние по отношению к модулю) не отскок, чтобы обратиться к новым объектам и должны быть обновлены в каждом пространстве имен, где они встречаются, если это желательно.

Итак, вы перезагружаете модуль urlresolvers, но это не побочный эффект. Объекты из старого urlresolvers не уничтожаются reload. В какой-то момент у вас в памяти есть экземпляры двух экземпляров класса RegexURLPattern. Это разные классы (объекты классов) с одинаковым именем и расположением в коде. Это вызывает ошибки, которые вы видите, когда объект нового класса RegexURLPattern не является экземпляром старого объекта RegexURLPattern и его конструктор базового класса не может быть вызван.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...