[Django] #28752: Django.setup() should be idempotent

41 views
Skip to first unread message

Django

unread,
Oct 30, 2017, 6:03:35 AM10/30/17
to django-...@googlegroups.com
#28752: Django.setup() should be idempotent
------------------------------------------+------------------------
Reporter: pascal chambon | Owner: nobody
Type: Bug | Status: new
Component: Core (Other) | Version: 1.11
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
------------------------------------------+------------------------
I've been bitten numerous times by the impredictable behaviour of django
when django.setup() was called numerous times.

In the old days I had exceptions, now it's mainly subtle breakages of
logging configuration.

I couldn't find, in the issue tracker or the dev mailing list statements
about this subject, others than request from other users encountering the
problem.

For example this ticket concerned script+importable modules :
https://code.djangoproject.com/ticket/26152

The latest case in date for me is pytest-django having troubles with these
multiple setup() calls : https://github.com/pytest-dev/pytest-
django/issues/531 , due to multiple fixtures attempting this auto-setup.

Would it be OK to make django.setup() idempotent, or even expose a
"is_ready" flag for easier introspection ?

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

Django

unread,
Oct 30, 2017, 11:53:29 AM10/30/17
to django-...@googlegroups.com
#28752: django.setup() should be idempotent
--------------------------------+--------------------------------------

Reporter: pascal chambon | Owner: nobody
Type: Bug | Status: closed

Component: Core (Other) | Version: 1.11
Severity: Normal | Resolution: duplicate

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 Tim Graham):

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


Comment:

I believe this is addressed in Django 2.0 by #27176. If not, please reopen
with a minimal project that reproduces the problem you're encountering.

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

Django

unread,
Oct 30, 2017, 1:29:58 PM10/30/17
to django-...@googlegroups.com
#28752: django.setup() should be idempotent
--------------------------------+--------------------------------------
Reporter: pascal chambon | Owner: nobody
Type: Bug | Status: new
Component: Core (Other) | Version: 1.11
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 pascal chambon):

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


Old description:

> I've been bitten numerous times by the impredictable behaviour of django
> when django.setup() was called numerous times.
>
> In the old days I had exceptions, now it's mainly subtle breakages of
> logging configuration.
>
> I couldn't find, in the issue tracker or the dev mailing list statements
> about this subject, others than request from other users encountering the
> problem.
>
> For example this ticket concerned script+importable modules :
> https://code.djangoproject.com/ticket/26152
>
> The latest case in date for me is pytest-django having troubles with
> these multiple setup() calls : https://github.com/pytest-dev/pytest-
> django/issues/531 , due to multiple fixtures attempting this auto-setup.
>
> Would it be OK to make django.setup() idempotent, or even expose a
> "is_ready" flag for easier introspection ?

New description:

Alas the ticket #27176 dealt only with the "apps.populate" part, but the
whole setup() must be protected, else we'll always have weird side effects
on duplicate calls.

Here is a testcase showing the reset of the "django" logger level, for
example, when calling setup() multiple times.

Depending on the exact LOGGING dict (with disable_existing_loggers etc.),
even the shape of the logging tree might be changed.

{{{

def test_duplicated_setup_calls(self):
import django, logging
#from django.conf import settings
#print(settings.LOGGING_CONFIG, settings.LOGGING)

django.setup()
logging.getLogger('django').setLevel(logging.DEBUG)
assert logging.getLogger('django').level == logging.DEBUG

django.setup()
assert logging.getLogger('django').level == logging.DEBUG #
raises

}}}

--

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

Django

unread,
Oct 30, 2017, 3:20:01 PM10/30/17
to django-...@googlegroups.com
#28752: django.setup() should be idempotent
--------------------------------+--------------------------------------
Reporter: pascal chambon | Owner: nobody
Type: Bug | Status: new
Component: Core (Other) | Version: 1.11
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
--------------------------------+--------------------------------------

Comment (by Tim Graham):

Thanks. Can you explain the use case for calling `django.setup()` multiple
times?

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

Django

unread,
Oct 30, 2017, 3:30:25 PM10/30/17
to django-...@googlegroups.com
#28752: django.setup() should be idempotent
--------------------------------+--------------------------------------
Reporter: pascal chambon | Owner: nobody
Type: Bug | Status: new
Component: Core (Other) | Version: 1.11
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 pascal chambon:

Old description:

> Alas the ticket #27176 dealt only with the "apps.populate" part, but the
> whole setup() must be protected, else we'll always have weird side
> effects on duplicate calls.
>
> Here is a testcase showing the reset of the "django" logger level, for
> example, when calling setup() multiple times.
>
> Depending on the exact LOGGING dict (with disable_existing_loggers etc.),
> even the shape of the logging tree might be changed.
>
> {{{
>
> def test_duplicated_setup_calls(self):
> import django, logging
> #from django.conf import settings
> #print(settings.LOGGING_CONFIG, settings.LOGGING)
>
> django.setup()
> logging.getLogger('django').setLevel(logging.DEBUG)
> assert logging.getLogger('django').level == logging.DEBUG
>
> django.setup()
> assert logging.getLogger('django').level == logging.DEBUG #
> raises
>
> }}}

New description:

Calling django.setup() multiple times is useless, BUT it can happen in
lots of cases, that's why imho this case should be handled by the
framework to avoid nasty side effects.

These "duplicate calls" often involve the collision between manage.py
commands, tests, custom scripts, and external launchers like pytest-
django. Plus maybe some corner cases when unittest-style TestCases and
pytest-style test functions are mixed in the same project.

Users have to do a real gym to call setup() "at some moment" in all these
use cases, yet try to prevent multiple calls of this initialization step
(like the 'if__name__ == "main"' protection). So far my only way out was
often to check for (not really undocumented) states of the framework
before calling setup().

--

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

Django

unread,
Oct 30, 2017, 3:32:39 PM10/30/17
to django-...@googlegroups.com
#28752: django.setup() should be idempotent
--------------------------------+--------------------------------------
Reporter: pascal chambon | Owner: nobody
Type: Bug | Status: new
Component: Core (Other) | Version: 1.11
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 pascal chambon:

Old description:

> Calling django.setup() multiple times is useless, BUT it can happen in


> lots of cases, that's why imho this case should be handled by the
> framework to avoid nasty side effects.
>
> These "duplicate calls" often involve the collision between manage.py
> commands, tests, custom scripts, and external launchers like pytest-
> django. Plus maybe some corner cases when unittest-style TestCases and
> pytest-style test functions are mixed in the same project.
>
> Users have to do a real gym to call setup() "at some moment" in all these
> use cases, yet try to prevent multiple calls of this initialization step
> (like the 'if__name__ == "main"' protection). So far my only way out was
> often to check for (not really undocumented) states of the framework
> before calling setup().

New description:

I've been bitten numerous times by the impredictable behaviour of django
when django.setup() was called numerous times.

In the old days I had exceptions, now it's mainly subtle breakages of
logging configuration.

I couldn't find, in the issue tracker or the dev mailing list statements
about this subject, others than request from other users encountering the
problem.

For example this ticket concerned script+importable modules :
https://code.djangoproject.com/ticket/26152

The latest case in date for me is pytest-django having troubles with
these multiple setup() calls : https://github.com/pytest-dev/pytest-
django/issues/531 , due to multiple fixtures attempting this auto-setup.

Would it be OK to make django.setup() idempotent, or even expose a
"is_ready" flag for easier introspection ?

--

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

Django

unread,
Oct 30, 2017, 3:34:18 PM10/30/17
to django-...@googlegroups.com
#28752: django.setup() should be idempotent
--------------------------------+--------------------------------------
Reporter: pascal chambon | Owner: nobody
Type: Bug | Status: new
Component: Core (Other) | Version: 1.11
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 pascal chambon:

Old description:

> I've been bitten numerous times by the impredictable behaviour of django


> when django.setup() was called numerous times.
>
> In the old days I had exceptions, now it's mainly subtle breakages of
> logging configuration.
>
> I couldn't find, in the issue tracker or the dev mailing list statements
> about this subject, others than request from other users encountering the
> problem.
>
> For example this ticket concerned script+importable modules :
> https://code.djangoproject.com/ticket/26152
>
> The latest case in date for me is pytest-django having troubles with
> these multiple setup() calls : https://github.com/pytest-dev/pytest-
> django/issues/531 , due to multiple fixtures attempting this auto-setup.
>
> Would it be OK to make django.setup() idempotent, or even expose a
> "is_ready" flag for easier introspection ?

New description:

I've been bitten numerous times by the impredictable behaviour of django
when django.setup() was called numerous times.

In the old days I had exceptions, now it's mainly subtle breakages of
logging configuration.

I couldn't find, in the issue tracker or the dev mailing list statements
about this subject, others than request from other users encountering the
problem.

For example this ticket concerned script+importable modules :
https://code.djangoproject.com/ticket/26152

The latest case in date for me is pytest-django having troubles with
these multiple setup() calls : https://github.com/pytest-dev/pytest-
django/issues/531 , due to multiple fixtures attempting this auto-setup.

Would it be OK to make django.setup() idempotent, or even expose a
"is_ready" flag for easier introspection ?


-- here are some updates, comments get rejected as spam --

Calling django.setup() multiple times is useless, BUT it can happen in
lots of cases, that's why imho this case should be handled by the
framework to avoid nasty side effects.

These "duplicate calls" often involve the collision between manage.py
commands, tests, custom scripts, and external launchers like pytest-
django. Plus maybe some corner cases when unittest-style TestCases and
pytest-style test functions are mixed in the same project.

Users have to do a real gym to call setup() "at some moment" in all these
use cases, yet try to prevent multiple calls of this initialization step
(like the 'if__name__ == "main"' protection). So far my only way out was
often to check for (not really undocumented) states of the framework
before calling setup().

--

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

Django

unread,
Oct 30, 2017, 3:34:44 PM10/30/17
to django-...@googlegroups.com
#28752: django.setup() should be idempotent
--------------------------------+--------------------------------------
Reporter: pascal chambon | Owner: nobody
Type: Bug | Status: new
Component: Core (Other) | Version: 1.11
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
--------------------------------+--------------------------------------

Comment (by pascal chambon):

My comments get marked as spam, I updated the description above.

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

Django

unread,
Nov 1, 2017, 3:36:19 PM11/1/17
to django-...@googlegroups.com
#28752: django.setup() should be idempotent
--------------------------------+--------------------------------------
Reporter: pascal chambon | Owner: nobody
Type: Bug | Status: new
Component: Core (Other) | Version: 1.11
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 Tim Graham):

* cc: Aymeric Augustin (added)


Old description:

> I've been bitten numerous times by the impredictable behaviour of django
> when django.setup() was called numerous times.
>
> In the old days I had exceptions, now it's mainly subtle breakages of
> logging configuration.
>
> I couldn't find, in the issue tracker or the dev mailing list statements
> about this subject, others than request from other users encountering the
> problem.
>
> For example this ticket concerned script+importable modules :
> https://code.djangoproject.com/ticket/26152
>
> The latest case in date for me is pytest-django having troubles with
> these multiple setup() calls : https://github.com/pytest-dev/pytest-
> django/issues/531 , due to multiple fixtures attempting this auto-setup.
>
> Would it be OK to make django.setup() idempotent, or even expose a
> "is_ready" flag for easier introspection ?
>

> -- here are some updates, comments get rejected as spam --
>

>
> Calling django.setup() multiple times is useless, BUT it can happen in
> lots of cases, that's why imho this case should be handled by the
> framework to avoid nasty side effects.
>
> These "duplicate calls" often involve the collision between manage.py
> commands, tests, custom scripts, and external launchers like pytest-
> django. Plus maybe some corner cases when unittest-style TestCases and
> pytest-style test functions are mixed in the same project.
>
> Users have to do a real gym to call setup() "at some moment" in all these
> use cases, yet try to prevent multiple calls of this initialization step
> (like the 'if__name__ == "main"' protection). So far my only way out was
> often to check for (not really undocumented) states of the framework
> before calling setup().

New description:

I've been bitten numerous times by the impredictable behaviour of django
when django.setup() was called numerous times.

In the old days I had exceptions, now it's mainly subtle breakages of
logging configuration.

I couldn't find, in the issue tracker or the dev mailing list statements
about this subject, others than request from other users encountering the
problem.

For example #26152 concerned script+importable modules.

The latest case in date for me is pytest-django having troubles with these
multiple setup() calls : https://github.com/pytest-dev/pytest-
django/issues/531 , due to multiple fixtures attempting this auto-setup.

Would it be OK to make django.setup() idempotent, or even expose an


"is_ready" flag for easier introspection ?

-- here are some updates, comments get rejected as spam --

Calling django.setup() multiple times is useless, BUT it can happen in
lots of cases, that's why imho this case should be handled by the
framework to avoid nasty side effects.

These "duplicate calls" often involve the collision between manage.py
commands, tests, custom scripts, and external launchers like pytest-
django. Plus maybe some corner cases when unittest-style TestCases and
pytest-style test functions are mixed in the same project.

Users have to do a real gym to call setup() "at some moment" in all these
use cases, yet try to prevent multiple calls of this initialization step
(like the 'if__name__ == "main"' protection). So far my only way out was
often to check for (not really undocumented) states of the framework
before calling setup().

--

Comment:

Aymeric, any input?

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

Django

unread,
Nov 1, 2017, 3:42:57 PM11/1/17
to django-...@googlegroups.com
#28752: django.setup() should be idempotent
--------------------------------+--------------------------------------
Reporter: pascal chambon | Owner: nobody
Type: Bug | Status: new
Component: Core (Other) | Version: 1.11
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
--------------------------------+--------------------------------------

Comment (by Aymeric Augustin):

`django.setup()` is already idempotent. However it isn't reentrant — I
believe that's what you're actually asking for — and it cannot be made
reentrant without breaking its invariants. See #27176 for details.

I don't think we should make changes to Django for accomodating pytest
code that does `django.setup = lambda: None`.

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

Django

unread,
Nov 2, 2017, 4:06:31 AM11/2/17
to django-...@googlegroups.com
#28752: django.setup() should not be runnable multiple times
--------------------------------+--------------------------------------

Reporter: pascal chambon | Owner: nobody
Type: Bug | Status: new
Component: Core (Other) | Version: 1.11
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
--------------------------------+--------------------------------------

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

Django

unread,
Nov 2, 2017, 4:26:07 AM11/2/17
to django-...@googlegroups.com
#28752: django.setup() should not be runnable multiple times
--------------------------------+--------------------------------------
Reporter: pascal chambon | Owner: nobody
Type: Bug | Status: new
Component: Core (Other) | Version: 1.11
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
--------------------------------+--------------------------------------

Comment (by pascal chambon):

OK I think my vocabulary was wrong, it's not (really) an idempotence
problem, since django.setup() does more or less the same things on both
calls (just skipping apps population phase on the second).

It's not a reentrancy problem, i.e not a problem with multiple threads (or
signal interrupts) entering django.setup() concurrently.

It's really just a problem of "multiple successive calls of
django.setup()", which are doing silent errors and weird modifications,
simply because only the first call of django.setup() makes sense.

Raising an exception on subsequent calls would be a possibility, but it
would be a useless hassle, since users just want is to ensure that django
was initialized at some point.
That's why I propose we just do a no-op on subsequent calls to
django.setup().

(By teh way I don't understand your statement about the "django.setup =
lambda: None" snippet - it was just a quick and dirty hack to prevent the
multiple runs of django.setup(), which broke the LOGGING config)

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

Django

unread,
Nov 4, 2017, 6:59:12 PM11/4/17
to django-...@googlegroups.com
#28752: django.setup() should not be runnable multiple times
--------------------------------+--------------------------------------
Reporter: pascal chambon | Owner: nobody
Type: Bug | Status: new
Component: Core (Other) | Version: 1.11
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
--------------------------------+--------------------------------------

Old description:

> I've been bitten numerous times by the impredictable behaviour of django
> when django.setup() was called numerous times.
>
> In the old days I had exceptions, now it's mainly subtle breakages of
> logging configuration.
>
> I couldn't find, in the issue tracker or the dev mailing list statements
> about this subject, others than request from other users encountering the
> problem.
>

> For example #26152 concerned script+importable modules.


>
> The latest case in date for me is pytest-django having troubles with
> these multiple setup() calls : https://github.com/pytest-dev/pytest-
> django/issues/531 , due to multiple fixtures attempting this auto-setup.
>

> Would it be OK to make django.setup() idempotent, or even expose an


> "is_ready" flag for easier introspection ?
>

> -- here are some updates, comments get rejected as spam --
>
> Calling django.setup() multiple times is useless, BUT it can happen in
> lots of cases, that's why imho this case should be handled by the
> framework to avoid nasty side effects.
>
> These "duplicate calls" often involve the collision between manage.py
> commands, tests, custom scripts, and external launchers like pytest-
> django. Plus maybe some corner cases when unittest-style TestCases and
> pytest-style test functions are mixed in the same project.
>
> Users have to do a real gym to call setup() "at some moment" in all these
> use cases, yet try to prevent multiple calls of this initialization step
> (like the 'if__name__ == "main"' protection). So far my only way out was
> often to check for (not really undocumented) states of the framework
> before calling setup().

New description:

I've been bitten numerous times by the impredictable behaviour of django


when django.setup() was called numerous times.

In the old days I had exceptions, now it's mainly subtle breakages of
logging configuration.

I couldn't find, in the issue tracker or the dev mailing list statements
about this subject, others than request from other users encountering the
problem.

For example #26152 concerned script+importable modules.

The latest case in date for me is pytest-django having troubles with these
multiple setup() calls : https://github.com/pytest-dev/pytest-
django/issues/531 , due to multiple fixtures attempting this auto-setup.

Would it be OK to make django.setup() idempotent, or even expose an


"is_ready" flag for easier introspection ?

-- here are some updates, comments get rejected as spam --

Calling django.setup() multiple times is useless, BUT it can happen in
lots of cases, that's why imho this case should be handled by the
framework to avoid nasty side effects.

These "duplicate calls" often involve the collision between manage.py
commands, tests, custom scripts, and external launchers like pytest-
django. Plus maybe some corner cases when unittest-style TestCases and
pytest-style test functions are mixed in the same project.

Users have to do a real gym to call setup() "at some moment" in all these
use cases, yet try to prevent multiple calls of this initialization step
(like the `if__name__ == "main"'` protection). So far my only way out was
often to check for (not really undocumented) states of the framework
before calling setup().

--

Comment (by Tim Graham):

I don't know. Does that change risk breaking working code where multiple
calls to `django.setup()` has an intended effect?

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

Django

unread,
Nov 7, 2017, 6:28:19 AM11/7/17
to django-...@googlegroups.com
#28752: django.setup() should not be runnable multiple times
--------------------------------+--------------------------------------
Reporter: pascal chambon | Owner: nobody
Type: Bug | Status: new
Component: Core (Other) | Version: 1.11
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
--------------------------------+--------------------------------------

Comment (by pascal chambon):

Well, I'm usually quite dedicated to retrocompatibility (see django-
compat-patcher package), but for once any breakage would be due to a
strange misuse of django.setup().

In the code below, we see that django.setup() performs 3 steps :

- overridding logging configuration with django settings
- setting the script prefix
- populating the apps registry

The last 2 steps are now idempotent it seems.

Only overridding logging breaks some setups (eg. with pytest fixtures),
and I can't find any use case where it would be a wanted behaviour.
If users want to reset logging several times, they may as well call
configure_logging() by themselves.

Until django.setup() is protected against double executions, we'll have
weird bugs surfacing each time we add new steps to it ''(are these
idempotent, or reentrant, or runnable multiple times...)'', so I'd
advocate fixing this once and for all.

On "how" to do it, I think a threading lock + a boolean guard would be
easy and sufficient, wouldn't they ? With a system to raise an error if
django.setup() ends up being called multiple times by the same thread
(which often smells like missing "if __name__ == '__main'__" conditions in
imported scripts).


{{{

configure_logging(settings.LOGGING_CONFIG, settings.LOGGING)

if set_prefix:
set_script_prefix(
'/' if settings.FORCE_SCRIPT_NAME is None else
settings.FORCE_SCRIPT_NAME
)

apps.populate(settings.INSTALLED_APPS)
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/28752#comment:13>

Django

unread,
Dec 27, 2017, 1:14:16 PM12/27/17
to django-...@googlegroups.com
#28752: Prevent django.setup() from running multiple times
--------------------------------------+------------------------------------

Reporter: pascal chambon | Owner: nobody
Type: Cleanup/optimization | Status: new

Component: Core (Other) | Version: 1.11
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):

* type: Bug => Cleanup/optimization
* stage: Unreviewed => Accepted


Comment:

I'm not completely sure if a change is feasible but I guess we could
evaluate a patch.

--
Ticket URL: <https://code.djangoproject.com/ticket/28752#comment:14>

Django

unread,
May 30, 2019, 11:34:09 AM5/30/19
to django-...@googlegroups.com
#28752: Prevent django.setup() from running multiple times
--------------------------------------+------------------------------------
Reporter: pascal chambon | Owner: nobody
Type: Cleanup/optimization | Status: new

Component: Core (Other) | Version: 1.11
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
--------------------------------------+------------------------------------

Comment (by Daniel Hahler):

This would be nice to have indeed.

Pascal, do you plan to provide a patch for this?

btw: the following can be used as a workaround (also used by pytest-
django):
{{{
import django.apps

if not django.apps.apps.ready:
django.setup()
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/28752#comment:15>

Django

unread,
Jun 1, 2019, 3:40:46 PM6/1/19
to django-...@googlegroups.com
#28752: Prevent django.setup() from running multiple times
--------------------------------------+------------------------------------
Reporter: pascal chambon | Owner: nobody
Type: Cleanup/optimization | Status: new

Component: Core (Other) | Version: 1.11
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
--------------------------------------+------------------------------------

Comment (by pascal chambon):

Thanks for reminding me of this ticket, my latest struggles with pytest-
django made me think a more global solution to the problem of django setup
and complex environments, and this ticket is for me now superseded by
https://code.djangoproject.com/ticket/30536 - hoping that the new setting
I introduce will be OK too.

--
Ticket URL: <https://code.djangoproject.com/ticket/28752#comment:16>

Django

unread,
Jun 3, 2019, 9:54:55 AM6/3/19
to django-...@googlegroups.com
#28752: Prevent django.setup() from running multiple times
--------------------------------------+------------------------------------
Reporter: pascal chambon | Owner: nobody
Type: Cleanup/optimization | Status: new

Component: Core (Other) | Version: 1.11
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
--------------------------------------+------------------------------------

Comment (by Carlton Gibson):

Let's keep the discussion from #30536 here. (It's ≈the same ticket AFAICS,
and the history here is informative.)

[https://github.com/django/django/pull/11435 PR there is here].

One additional element added there is to make the the `setup()` code
''pluggable''. (i.e. whilst we make `setup()` exit if run multiple times,
allow user code to be run before/after as well.) A setting is proposed for
this. ''MUST it be a setting…?''

--
Ticket URL: <https://code.djangoproject.com/ticket/28752#comment:17>

Django

unread,
Jun 3, 2019, 10:34:05 AM6/3/19
to django-...@googlegroups.com
#28752: Prevent django.setup() from running multiple times
--------------------------------------+------------------------------------
Reporter: pascal chambon | Owner: nobody
Type: Cleanup/optimization | Status: new

Component: Core (Other) | Version: 1.11
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1

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

* needs_better_patch: 0 => 1


Comment:

Looking at the PR, there are two things going on there:

1. Making `setup()` ''idempotent''. Let's handle that part here.
2. Allowing specifying custom logic. Let's handle that on #30536.

(The one looks less controversial than the other...)

Pascal, if you could split the PR into two, targeting the one as `Fixed
#28752 -- ...` that would be great.

--
Ticket URL: <https://code.djangoproject.com/ticket/28752#comment:18>

Django

unread,
Jun 3, 2019, 3:35:00 PM6/3/19
to django-...@googlegroups.com
#28752: Prevent django.setup() from running multiple times
--------------------------------------+------------------------------------
Reporter: pascal chambon | Owner: nobody
Type: Cleanup/optimization | Status: new

Component: Core (Other) | Version: 1.11
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1

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

Comment (by pascal chambon):

OK let's handle 1 feature at a time :)

Here is the PR only for idempotence (and django.is_ready flag) :
https://github.com/django/django/pull/11440

One of the CI checks failed for obscure reasons (package django not
found), any easy way to restart it ?

--
Ticket URL: <https://code.djangoproject.com/ticket/28752#comment:19>

Django

unread,
Jun 10, 2019, 11:44:19 AM6/10/19
to django-...@googlegroups.com
#28752: Prevent django.setup() from running multiple times
--------------------------------------+------------------------------------
Reporter: pascal chambon | Owner: nobody
Type: Cleanup/optimization | Status: new

Component: Core (Other) | Version: 1.11
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1

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

Comment (by pascal chambon):

The latest version protects setup with a threading lock, so that
idempotence gets enforced even in multithreaded lazy-loading contexts.

--
Ticket URL: <https://code.djangoproject.com/ticket/28752#comment:20>

Django

unread,
Jun 13, 2019, 2:50:58 PM6/13/19
to django-...@googlegroups.com
#28752: Prevent django.setup() from running multiple times
-------------------------------------+-------------------------------------
Reporter: pascal chambon | Owner: pascal
Type: | chambon
Cleanup/optimization | Status: assigned

Component: Core (Other) | Version: 1.11
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1

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

* status: new => assigned
* owner: nobody => pascal chambon


Comment:

OK a few tweaks and bugfixes later, this PR seems now ready to me B-) ->
https://github.com/django/django/pull/11440

--
Ticket URL: <https://code.djangoproject.com/ticket/28752#comment:21>

Django

unread,
Aug 17, 2019, 10:40:56 AM8/17/19
to django-...@googlegroups.com
#28752: Prevent django.setup() from running multiple times
-------------------------------------+-------------------------------------
Reporter: pascal chambon | Owner: pascal
Type: | chambon
Cleanup/optimization | Status: assigned
Component: Core (Other) | Version: 1.11
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 pascal chambon):

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


--
Ticket URL: <https://code.djangoproject.com/ticket/28752#comment:22>

Django

unread,
Oct 17, 2019, 5:03:06 AM10/17/19
to django-...@googlegroups.com
#28752: Prevent django.setup() from running multiple times
-------------------------------------+-------------------------------------
Reporter: pascal chambon | Owner: pascal
Type: | chambon
Cleanup/optimization | Status: closed

Component: Core (Other) | Version: 1.11
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 Carlton Gibson):

* status: assigned => closed


Comment:

OK, sorry, having looked again at this, I just can't see that the extra
code in `django.setup()` merits the change.

TBH in 10+ years of using Django I've never seen an actual issue here.
Maybe `py.test` runs into them, but it seems to me that it would be easy
enough to put required locking code outside of the `setup()` in whatever
bootstrap script is in play.

As it is, `setup()` is simple and straight-forward. With the proposed
changes it's anything but. Given that, and the lack of consensus as
whether, and even why, we should address this, I'm going to say `wontfix`.
On assessment I think addressing this is putting the cart before the
horse.

--
Ticket URL: <https://code.djangoproject.com/ticket/28752#comment:23>

Django

unread,
Oct 17, 2019, 5:38:31 AM10/17/19
to django-...@googlegroups.com
#28752: Prevent django.setup() from running multiple times
-------------------------------------+-------------------------------------
Reporter: pascal chambon | Owner: pascal
Type: | chambon
Cleanup/optimization | Status: closed
Component: Core (Other) | Version: 1.11
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 Aymeric Augustin):

Thanks Carlton.

--
Ticket URL: <https://code.djangoproject.com/ticket/28752#comment:24>

Reply all
Reply to author
Forward
0 new messages