[Django] #28575: Model.DoesNotExist classes are not pickleable

58 views
Skip to first unread message

Django

unread,
Sep 7, 2017, 2:38:33 PM9/7/17
to django-...@googlegroups.com
#28575: Model.DoesNotExist classes are not pickleable
-------------------------------------+-------------------------------------
Reporter: Rachel | Owner: nobody
Tobin |
Type: | Status: new
Uncategorized |
Component: Database | Version: 1.11
layer (models, ORM) |
Severity: Normal | Keywords:
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
Example:
{{{
>>> import django
>>> import pickle
>>> pickle.dumps(django.contrib.auth.models.User.DoesNotExist)
>>> PicklingError: Can't pickle <class
'django.contrib.auth.models.DoesNotExist'>: it's not found as
django.contrib.auth.models.DoesNotExist
}}}

Note that *instances* of `Model.DoesNotExist` are pickleable as fixed
here: https://code.djangoproject.com/ticket/17776. However the class
itself is not. This is particularly problematic when using the Django
test runner with the `--parallel` option enabled when a
`Model.DoesNotExist` exception is raised. The result of this is the test
runner bailing with a `pickle.PicklingError`, making it exceptionally
difficult to debug the cause of the `Model.DoesNotExist`.

This could be fixed by changing the metaclass that is used here:
https://github.com/django/django/blob/1.11.5/django/db/models/base.py#L76
to use a custom metaclass with a `__reduce__` method. A patch is in
progress for this.

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

Django

unread,
Sep 7, 2017, 2:38:47 PM9/7/17
to django-...@googlegroups.com
#28575: Model.DoesNotExist classes are not pickleable
-------------------------------------+-------------------------------------
Reporter: Rachel Tobin | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.11
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Rachel Tobin):

* type: Uncategorized => Bug


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

Django

unread,
Sep 7, 2017, 7:56:03 PM9/7/17
to django-...@googlegroups.com
#28575: Model.DoesNotExist classes are not pickleable
-------------------------------------+-------------------------------------
Reporter: Rachel Tobin | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.11
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Description changed by Rachel Tobin:

Old description:

> Example:
> {{{
> >>> import django
> >>> import pickle
> >>> pickle.dumps(django.contrib.auth.models.User.DoesNotExist)
> >>> PicklingError: Can't pickle <class
> 'django.contrib.auth.models.DoesNotExist'>: it's not found as
> django.contrib.auth.models.DoesNotExist
> }}}
>
> Note that *instances* of `Model.DoesNotExist` are pickleable as fixed
> here: https://code.djangoproject.com/ticket/17776. However the class
> itself is not. This is particularly problematic when using the Django
> test runner with the `--parallel` option enabled when a
> `Model.DoesNotExist` exception is raised. The result of this is the test
> runner bailing with a `pickle.PicklingError`, making it exceptionally
> difficult to debug the cause of the `Model.DoesNotExist`.
>
> This could be fixed by changing the metaclass that is used here:
> https://github.com/django/django/blob/1.11.5/django/db/models/base.py#L76
> to use a custom metaclass with a `__reduce__` method. A patch is in
> progress for this.

New description:

Example:
{{{
>>> import django
>>> import pickle
>>> pickle.dumps(django.contrib.auth.models.User.DoesNotExist)
>>> PicklingError: Can't pickle <class
'django.contrib.auth.models.DoesNotExist'>: it's not found as
django.contrib.auth.models.DoesNotExist
}}}

Note that *instances* of `Model.DoesNotExist` are pickleable as fixed
here: https://code.djangoproject.com/ticket/17776. However the class
itself is not. This is particularly problematic when using the Django
test runner with the `--parallel` option enabled when a
`Model.DoesNotExist` exception is raised. The result of this is the test
runner bailing with a `pickle.PicklingError`, making it exceptionally
difficult to debug the cause of the `Model.DoesNotExist`.

--

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

Django

unread,
Sep 11, 2017, 10:53:51 AM9/11/17
to django-...@googlegroups.com
#28575: Model.DoesNotExist classes are not pickleable
-------------------------------------+-------------------------------------
Reporter: Rachel Tobin | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.11
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Tim Graham):

* stage: Unreviewed => Accepted


Old description:

> Example:
> {{{
> >>> import django
> >>> import pickle
> >>> pickle.dumps(django.contrib.auth.models.User.DoesNotExist)
> >>> PicklingError: Can't pickle <class
> 'django.contrib.auth.models.DoesNotExist'>: it's not found as
> django.contrib.auth.models.DoesNotExist
> }}}
>
> Note that *instances* of `Model.DoesNotExist` are pickleable as fixed
> here: https://code.djangoproject.com/ticket/17776. However the class
> itself is not. This is particularly problematic when using the Django
> test runner with the `--parallel` option enabled when a
> `Model.DoesNotExist` exception is raised. The result of this is the test
> runner bailing with a `pickle.PicklingError`, making it exceptionally
> difficult to debug the cause of the `Model.DoesNotExist`.

New description:

Example:
{{{
>>> import django
>>> import pickle
>>> pickle.dumps(django.contrib.auth.models.User.DoesNotExist)
>>> PicklingError: Can't pickle <class
'django.contrib.auth.models.DoesNotExist'>: it's not found as
django.contrib.auth.models.DoesNotExist
}}}

*Instances* of `Model.DoesNotExist` are pickleable as fixed in #17776,
however, the class itself is not. This is particularly problematic when


using the Django test runner with the `--parallel` option enabled when a
`Model.DoesNotExist` exception is raised. The result of this is the test
runner bailing with a `pickle.PicklingError`, making it exceptionally
difficult to debug the cause of the `Model.DoesNotExist`.

--

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

Django

unread,
Sep 13, 2017, 9:08:07 PM9/13/17
to django-...@googlegroups.com
#28575: Model.DoesNotExist classes are not pickleable
-------------------------------------+-------------------------------------
Reporter: Rachel Tobin | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.11
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Rachel Tobin):

* has_patch: 0 => 1


Comment:

I've created a patch for this: https://github.com/django/django/pull/9076

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

Django

unread,
Oct 2, 2017, 1:56:28 PM10/2/17
to django-...@googlegroups.com
#28575: Model.DoesNotExist classes are not pickleable
-------------------------------------+-------------------------------------
Reporter: Rachel Tobin | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.11
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1

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

* needs_better_patch: 0 => 1


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

Django

unread,
Oct 13, 2017, 9:16:32 AM10/13/17
to django-...@googlegroups.com
#28575: Model.DoesNotExist classes are not pickleable
-------------------------------------+-------------------------------------
Reporter: Rachel Tobin | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.11
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1

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

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

In [changeset:"6c92f711eaf382113e811e43900f4fabd0f95c26" 6c92f711]:
{{{
#!CommitTicketReference repository=""
revision="6c92f711eaf382113e811e43900f4fabd0f95c26"
Refs #28575 -- Allowed pickling Model.DoesNotExist and
MultipleObjectsReturned classes.
}}}

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

Django

unread,
Oct 13, 2017, 9:17:32 AM10/13/17
to django-...@googlegroups.com
#28575: Allow pickling dynamically created Model exception classes (DoesNotExist,
MultipleObjectsReturned, RelatedObjectDoesNotExist)

-------------------------------------+-------------------------------------
Reporter: Rachel Tobin | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.11
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Tim Graham):

* needs_better_patch: 1 => 0
* has_patch: 1 => 0


Comment:

The ticket remains open to allow pickling `RelatedObjectDoesNotExist`
which according to Simon, "will require a lot more work."

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

Django

unread,
Oct 13, 2017, 2:14:44 PM10/13/17
to django-...@googlegroups.com
#28575: Allow pickling dynamically created Model exception classes (DoesNotExist,
MultipleObjectsReturned, RelatedObjectDoesNotExist)
-------------------------------------+-------------------------------------
Reporter: Rachel Tobin | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.11
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Simon Charette):

* has_patch: 0 => 1


Comment:

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

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

Django

unread,
Oct 13, 2017, 3:58:57 PM10/13/17
to django-...@googlegroups.com
#28575: Allow pickling dynamically created Model exception classes (DoesNotExist,
MultipleObjectsReturned, RelatedObjectDoesNotExist)
-------------------------------------+-------------------------------------
Reporter: Rachel Tobin | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.11
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | 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:"216eda103bee71725b26421e578705f24e17dae0" 216eda1]:
{{{
#!CommitTicketReference repository=""
revision="216eda103bee71725b26421e578705f24e17dae0"
Refs #28575 -- Removed unnecessary code for model exception pickling.

Setting __qualname__ is sufficient for pickling of DoesNotExist and
and MultipleObjectsReturned to work correctly.
}}}

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

Django

unread,
Oct 18, 2017, 9:44:10 PM10/18/17
to django-...@googlegroups.com
#28575: Allow pickling dynamically created Model exception classes (DoesNotExist,
MultipleObjectsReturned, RelatedObjectDoesNotExist)
-------------------------------------+-------------------------------------
Reporter: Rachel Tobin | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.11
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | 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:"d4fb742094dba99cb0db17f3aa9d9f5159af676f" d4fb7420]:
{{{
#!CommitTicketReference repository=""
revision="d4fb742094dba99cb0db17f3aa9d9f5159af676f"
Refs #28575 -- Made RelatedObjectDoesNotExist classes pickable.

Thanks to Rachel Tobin for the initial __qualname__ work and tests.
}}}

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

Django

unread,
Oct 18, 2017, 9:45:06 PM10/18/17
to django-...@googlegroups.com
#28575: Allow pickling dynamically created Model exception classes (DoesNotExist,
MultipleObjectsReturned, RelatedObjectDoesNotExist)
-------------------------------------+-------------------------------------
Reporter: Rachel Tobin | Owner: nobody
Type: Bug | Status: closed

Component: Database layer | Version: 1.11
(models, ORM) |
Severity: Normal | Resolution: fixed
Keywords: | 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):

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


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

Django

unread,
Aug 9, 2018, 10:30:06 AM8/9/18
to django-...@googlegroups.com
#28575: Allow pickling dynamically created Model exception classes (DoesNotExist,
MultipleObjectsReturned, RelatedObjectDoesNotExist)
-------------------------------------+-------------------------------------
Reporter: Rachel Tobin | Owner: nobody
Type: Bug | Status: closed
Component: Database layer | Version: 1.11
(models, ORM) |
Severity: Normal | Resolution: fixed
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Frankie Dintino):

Are there any plans to backport this patch to Django 1.11?

--
Ticket URL: <https://code.djangoproject.com/ticket/28575#comment:12>

Reply all
Reply to author
Forward
0 new messages