#12121 closed (fixed)
deepcopy(model_instance) causes infinite recursion since r11681
Reported by: | Johannes Dollinger | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Keywords: | ||
Cc: | immel@… | Triage Stage: | Unreviewed |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | yes |
Easy pickings: | no | UI/UX: | no |
Description
deepcopy(mode_instance)
causes infinite recursion in Model.__reduce__()
since r11681.
$ python tests/runtests.py queries ... RuntimeError: maximum recursion depth exceeded ...
Attachments (2)
Change History (20)
comment:1 by , 15 years ago
Resolution: | → worksforme |
---|---|
Status: | new → closed |
comment:2 by , 15 years ago
To clarify - I don't see this behaviour under MacOS, using Python 2.5, under SQLite, Postgres and MySQL. I'm willing to accept that you're seeing this problem, but we're going to need a lot more detail that you have provided so far.
comment:3 by , 15 years ago
$ sqlite3 --version 3.6.5 $ svn up At revision 11690. $ export PYTHONPATH=`pwd` $ export DJANGO_SETTINGS_MODULE=settings $ cat settings.py DEBUG = True DATABASE_ENGINE = 'sqlite3' DATABASE_NAME = 'test.db' INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', ) $ python django/bin/django-admin.py syncdb --noinput $ python django/bin/django-admin.py shell Python 2.5 (r25:51918, Sep 19 2006, 08:49:13) [GCC 4.0.1 (Apple Computer, Inc. build 5341)] on darwin Type "help", "copyright", "credits" or "license" for more information. (InteractiveConsole) >>> from django.contrib.contenttypes.models import ContentType >>> ct = ContentType.objects.all()[0] >>> ct <ContentType: content type> >>> from django.db.models import Q >>> Q(ct=ct) <django.db.models.query_utils.Q object at 0xdd0a30> >>> Q(ct=ct) | Q(foo=True) Traceback (most recent call last): ... RuntimeError: maximum recursion depth exceeded >>> $ python tests/runtests.py queries ====================================================================== FAIL: Doctest: regressiontests.queries.models.__test__.API_TESTS ... $
comment:4 by , 15 years ago
The test passes for me under sqlite3, python2.5. My SQLite is version 3.6.16
however.
comment:5 by , 15 years ago
Perhaps it might shed some light if you did not trim all of the traceback, that might give a clue what is causing the recursion. FWIW I cannot recreate on Ubuntu nor Windows, with a somewhat lower level sqlite3:
kmt@lbox:~/django/trunk$ svn up At revision 11690. kmt@lbox:~/django/trunk$ svn diff kmt@lbox:~/django/trunk$ sqlite3 --version 3.5.9 kmt@lbox:~/django/trunk$ export PYTHONPATH=`pwd` kmt@lbox:~/django/trunk$ export DJANGO_SETTINGS_MODULE=settings kmt@lbox:~/django/trunk$ cat settings.py DATABASE_ENGINE = 'sqlite3' DATABASE_NAME = 'test.db' INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', ) kmt@lbox:~/django/trunk$ python django/bin/django-admin.py syncdb --noinput kmt@lbox:~/django/trunk$ python django/bin/django-admin.py shell Python 2.5.2 (r252:60911, Oct 5 2008, 19:24:49) [GCC 4.3.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. (InteractiveConsole) >>> from django.contrib.contenttypes.models import ContentType >>> ct = ContentType.objects.all()[0] >>> ct <ContentType: content type> >>> from django.db.models import Q >>> Q(ct=ct) <django.db.models.query_utils.Q object at 0x84f09cc> >>> Q(ct=ct) | Q(foo=True) <django.db.models.query_utils.Q object at 0x84f0c4c> >>> quit() kmt@lbox:~/django/trunk$ python tests/runtests.py queries ---------------------------------------------------------------------- Ran 6 tests in 1.185s OK kmt@lbox:~/django/trunk$
I don't have any Macs to try.
comment:6 by , 15 years ago
Resolution: | worksforme |
---|---|
Status: | closed → reopened |
Searching for a python bug, I stumbled over a blog post from Malcolm: http://www.pointy-stick.com/blog/2009/03/23/yak-shaving-advanced-players/. Let me quote:
"Next morning, somebody reports an infinite recursion problem. That was very odd, since the code I wrote looked pretty correct in that area. The key seemed to be that they were using Python 2.4. Even creating a diff between the pickle module for Python 2.4 and the one for 2.5 was unenlightening, so the problem was deeper than that.
I'm not 100% sure if this is a bug in Python versions prior to 2.5, or just an undocumented side-effect. The end result is that if you write a __reduce__()
method, you can't do the natural thing and dispatch to the same method on the superclass if you don't need to do anything special. At least, not in Python 2.3 or 2.4. Django supports those versions, so I had to work around.
Not a big problem, once I diagnosed it (turns out the existing test suite caught the problem when I ran it under Python 2.4), and fixed easily enough."
The ticket was #10547, the commit r10099. Apparently, my Apple "python 2.5" has some 2.4 bugs in it.
comment:7 by , 15 years ago
Here's the requested traceback:
>>> Q(ct=ct) | Q(foo=True) Traceback (most recent call last): File "<console>", line 1, in <module> File "/Users/emulbreh/Projekte/django/trunk/django/db/models/query_utils.py", line 159, in __or__ return self._combine(other, self.OR) File "/Users/emulbreh/Projekte/django/trunk/django/db/models/query_utils.py", line 154, in _combine obj = deepcopy(self) File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/copy.py", line 173, in deepcopy y = copier(memo) File "/Users/emulbreh/Projekte/django/trunk/django/utils/tree.py", line 61, in __deepcopy__ obj.children = deepcopy(self.children, memodict) File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/copy.py", line 162, in deepcopy y = copier(x, memo) File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/copy.py", line 227, in _deepcopy_list y.append(deepcopy(a, memo)) File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/copy.py", line 162, in deepcopy y = copier(x, memo) File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/copy.py", line 234, in _deepcopy_tuple y.append(deepcopy(a, memo)) File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/copy.py", line 181, in deepcopy rv = reductor(2) File "/Users/emulbreh/Projekte/django/trunk/django/db/models/base.py", line 356, in __reduce__ return super(Model, self).__reduce__() ... File "/Users/emulbreh/Projekte/django/trunk/django/db/models/base.py", line 356, in __reduce__ return super(Model, self).__reduce__() RuntimeError: maximum recursion depth exceeded
by , 15 years ago
Attachment: | 12121.reduce_deferred.diff added |
---|
comment:8 by , 15 years ago
Has patch: | set |
---|---|
Patch needs improvement: | set |
Just replacing super(Model, self).__reduce__()
broke the cache
tests.
comment:9 by , 15 years ago
Note: The patch is bad. Model.__reduce__()
cannot be removed. It's required for dynamically created models.
follow-ups: 11 13 comment:10 by , 15 years ago
@emulbreh: I've just attached a patch which passes for me - however, I don't have a copy of Python 2.4 (or a broken version of Python 2.5) available. Can you validate that this patch works for you?
comment:11 by , 15 years ago
Replying to russellm:
I've got Python2.4 on both Ubuntu and Windows. Was able to see the infinite recursion failure once the early level of Python was identified as the cause, just confirmed the queries test passes with the patch.
comment:12 by , 15 years ago
Resolution: | → fixed |
---|---|
Status: | reopened → closed |
follow-up: 14 comment:13 by , 15 years ago
Replying to russellm:
@emulbreh: I've just attached a patch which passes for me - however, I don't have a copy of Python 2.4 (or a broken version of Python 2.5) available. Can you validate that this patch works for you?
It works, thanks.
comment:14 by , 15 years ago
Replying to emulbreh:
Replying to russellm:
@emulbreh: I've just attached a patch which passes for me - however, I don't have a copy of Python 2.4 (or a broken version of Python 2.5) available. Can you validate that this patch works for you?
It works, thanks.
Which means: with my broken Python 2.5, too.
comment:15 by , 15 years ago
I can confirm this bug on Red Hat under python 2.4.3. Where I see it is attempting to pickle an object for caching (using locmem cache) -- infinite recursion on Model.reduce.
Using python 2.5 works fine.
comment:16 by , 15 years ago
@rfugger - are you reporting that this is *still* a problem? This should have been fixed by r11691; if it still exists for Python 2.4.3, then we have more work to do; a test case that triggers the infinite recursion would be most helpful.
comment:17 by , 15 years ago
Cc: | added |
---|
I ran the full test suite before I committed, and I just re-ran the queries test specifically - I don't see this failure.