[Django] #24690: ArrayField data bleeds between instances when using field.append(item)

61 views
Skip to first unread message

Django

unread,
Apr 22, 2015, 4:45:57 PM4/22/15
to django-...@googlegroups.com
#24690: ArrayField data bleeds between instances when using field.append(item)
----------------------------------+---------------------------------
Reporter: redbeard0x0a | Owner:
Type: Bug | Status: new
Component: contrib.postgres | Version: 1.8
Severity: Normal | Keywords: ArrayField postgres
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
----------------------------------+---------------------------------
I found an issue when upgrading to Django 1.8 and using the new ArrayField
and a model's instance methods.

This code will cause Model#array_field's data to bleed between different
instances.

{{{
def add_to_array(self, item):
if item not in self.array_field:
self.array_field.append(item)
}}}

However, this code does the correct thing:

{{{
def add_to_array(self, item):
existing = self.array_field

if item not in self.array_field:
self.array_field = existing + [item]
}}}

I put together a django project/app with the code and tests that show the
problems with self.array_field.append(). It also has a Vagrant file setup
that should also exhibit the problems.

https://github.com/redbeard0x0a/django18bug

--
Ticket URL: <https://code.djangoproject.com/ticket/24690>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Apr 22, 2015, 5:27:02 PM4/22/15
to django-...@googlegroups.com
#24690: ArrayField data bleeds between instances when using field.append(item)
-------------------------------------+------------------------------------

Reporter: redbeard0x0a | Owner:
Type: Bug | Status: new
Component: contrib.postgres | Version: 1.8
Severity: Release blocker | Resolution:
Keywords: ArrayField postgres | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+------------------------------------
Changes (by timgraham):

* needs_better_patch: => 0
* stage: Unreviewed => Accepted
* severity: Normal => Release blocker
* needs_tests: => 0
* needs_docs: => 0


--
Ticket URL: <https://code.djangoproject.com/ticket/24690#comment:1>

Django

unread,
May 1, 2015, 7:23:38 AM5/1/15
to django-...@googlegroups.com
#24690: ArrayField data bleeds between instances when using field.append(item)
-------------------------------------+-------------------------------------
Reporter: redbeard0x0a | Owner:
Type: Bug | Status: closed
Component: contrib.postgres | Version: 1.8
Severity: Release blocker | Resolution:
| worksforme

Keywords: ArrayField postgres | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by mjtamlyn):

* status: new => closed
* resolution: => worksforme


Comment:

The issue in your example code is that you have used `default=[]`. This
default is shared between all instances and in this case it is mutable, so
you are modifying the default array.

The correct code is to use `default=list`.

I don't consider this a bug in Django - this is the same behaviour as you
would get if you have code like:
{{{
def myfunc(foo, bar=[]):
bar.append(foo)
return bar
}}}
The first call to `myfunc(1)` would return `[1]`, the second `[1, 1]`,
etc.

--
Ticket URL: <https://code.djangoproject.com/ticket/24690#comment:2>

Django

unread,
May 1, 2015, 8:56:12 AM5/1/15
to django-...@googlegroups.com
#24690: Warn about mutable defaults with ArrayField
--------------------------------------+------------------------------------
Reporter: redbeard0x0a | Owner: nobody
Type: Cleanup/optimization | Status: new
Component: Documentation | Version: 1.8
Severity: Normal | Resolution:

Keywords: ArrayField postgres | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------
Changes (by timgraham):

* status: closed => new
* severity: Release blocker => Normal
* resolution: worksforme =>
* component: contrib.postgres => Documentation
* owner: => nobody
* type: Bug => Cleanup/optimization


Comment:

Could we add a warning about mutable defaults to the `ArrayField` docs? I
guess this also applies to `JSONField`.

--
Ticket URL: <https://code.djangoproject.com/ticket/24690#comment:3>

Django

unread,
Jun 5, 2015, 6:52:10 AM6/5/15
to django-...@googlegroups.com
#24690: Warn about mutable defaults with ArrayField
-------------------------------------+-------------------------------------
Reporter: redbeard0x0a | Owner:
Type: | marissazhou
Cleanup/optimization | Status: assigned

Component: Documentation | Version: 1.8
Severity: Normal | Resolution:
Keywords: ArrayField postgres | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by marissazhou):

* owner: nobody => marissazhou
* status: new => assigned


--
Ticket URL: <https://code.djangoproject.com/ticket/24690#comment:4>

Django

unread,
Jun 5, 2015, 9:59:00 AM6/5/15
to django-...@googlegroups.com
#24690: Warn about mutable defaults with ArrayField
-------------------------------------+-------------------------------------
Reporter: redbeard0x0a | Owner:
Type: | marissazhou
Cleanup/optimization | Status: assigned
Component: Documentation | Version: 1.8
Severity: Normal | Resolution:
Keywords: ArrayField postgres | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by marissazhou):

* has_patch: 0 => 1


Comment:

Pull Request Submitted

https://github.com/django/django/pull/4806

--
Ticket URL: <https://code.djangoproject.com/ticket/24690#comment:5>

Django

unread,
Jun 6, 2015, 10:13:44 AM6/6/15
to django-...@googlegroups.com
#24690: Warn about mutable defaults with ArrayField
-------------------------------------+-------------------------------------
Reporter: redbeard0x0a | Owner:
Type: | marissazhou
Cleanup/optimization | Status: assigned
Component: Documentation | Version: 1.8
Severity: Normal | Resolution:
Keywords: ArrayField postgres | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by timgraham):

* needs_better_patch: 0 => 1


--
Ticket URL: <https://code.djangoproject.com/ticket/24690#comment:6>

Django

unread,
Jun 20, 2015, 2:31:20 PM6/20/15
to django-...@googlegroups.com
#24690: Warn about mutable defaults with ArrayField
-------------------------------------+-------------------------------------
Reporter: redbeard0x0a | Owner:
Type: | marissazhou
Cleanup/optimization | Status: assigned
Component: Documentation | Version: 1.8
Severity: Normal | Resolution:
Keywords: ArrayField postgres | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by timgraham):

* needs_better_patch: 1 => 0


--
Ticket URL: <https://code.djangoproject.com/ticket/24690#comment:7>

Django

unread,
Jun 20, 2015, 7:12:35 PM6/20/15
to django-...@googlegroups.com
#24690: Warn about mutable defaults with ArrayField
-------------------------------------+-------------------------------------
Reporter: redbeard0x0a | Owner:
Type: | marissazhou
Cleanup/optimization | Status: assigned
Component: Documentation | Version: 1.8
Severity: Normal | Resolution:
Keywords: ArrayField postgres | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by timgraham):

* needs_better_patch: 0 => 1


--
Ticket URL: <https://code.djangoproject.com/ticket/24690#comment:8>

Django

unread,
Jul 31, 2015, 1:44:23 PM7/31/15
to django-...@googlegroups.com
#24690: Warn about mutable defaults with ArrayField
-------------------------------------+-------------------------------------
Reporter: redbeard0x0a | Owner:
Type: | marissazhou
Cleanup/optimization | Status: assigned
Component: Documentation | Version: 1.8
Severity: Normal | Resolution:
Keywords: ArrayField postgres | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by timgraham):

* needs_better_patch: 1 => 0


Comment:

[https://github.com/django/django/pull/5078 PR]

--
Ticket URL: <https://code.djangoproject.com/ticket/24690#comment:9>

Django

unread,
Aug 1, 2015, 7:52:23 AM8/1/15
to django-...@googlegroups.com
#24690: Warn about mutable defaults with ArrayField
-------------------------------------+-------------------------------------
Reporter: redbeard0x0a | Owner:
Type: | marissazhou
Cleanup/optimization | Status: closed
Component: Documentation | Version: 1.8
Severity: Normal | Resolution: fixed

Keywords: ArrayField postgres | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Tim Graham <timograham@…>):

* status: assigned => closed
* resolution: => fixed


Comment:

In [changeset:"f93e7f5674436b230e6b4023570939a20c0c6055" f93e7f5]:
{{{
#!CommitTicketReference repository=""
revision="f93e7f5674436b230e6b4023570939a20c0c6055"
Fixed #24690 -- Added a warning about mutable defaults for
ArrayField/JSONField.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/24690#comment:10>

Django

unread,
Aug 1, 2015, 7:54:08 AM8/1/15
to django-...@googlegroups.com
#24690: Warn about mutable defaults with ArrayField
-------------------------------------+-------------------------------------
Reporter: redbeard0x0a | Owner:
Type: | marissazhou
Cleanup/optimization | Status: closed
Component: Documentation | Version: 1.8
Severity: Normal | Resolution: fixed
Keywords: ArrayField postgres | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Tim Graham <timograham@…>):

In [changeset:"ef5cf564bff695049b3b51024d05c570be29e4cf" ef5cf564]:
{{{
#!CommitTicketReference repository=""
revision="ef5cf564bff695049b3b51024d05c570be29e4cf"
[1.8.x] Fixed #24690 -- Added a warning about mutable defaults for
ArrayField.

Backport of f93e7f5674436b230e6b4023570939a20c0c6055 from master
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/24690#comment:11>

Reply all
Reply to author
Forward
0 new messages