[Django] #32314: Allow autoreloading of `python -m pkg_other_than_django runserver`

26 views
Skip to first unread message

Django

unread,
Jan 4, 2021, 12:33:09 PM1/4/21
to django-...@googlegroups.com
#32314: Allow autoreloading of `python -m pkg_other_than_django runserver`
-------------------------------------+-------------------------------------
Reporter: William | Owner: nobody
Schwartz |
Type: New | Status: assigned
feature |
Component: Core | Version: master
(Management commands) | Keywords: runserver,
Severity: Normal | autoreload, freezers
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
[https://github.com/django/django/blob/b41d38ae26b1da9519a6cd765bc2f2ce7d355007/django/utils/autoreload.py#L213-L246
django.utils.autoreload.get_child_arguments] detects if Python was
launched as `python -m django`. Currently it detects only when
[https://docs.python.org/3/using/cmdline.html#cmdoption-m -m] was passed
specifically `django` (and only in Python environments in which `__file__`
is set on modules, which is
[https://docs.python.org/3/reference/import.html#__file__ not true of all
Python environments]). Like #32177, this ticket aims to remove one
impediment to creating Django-based command-line utilities that have their
own [https://docs.python.org/3/library/__main__.html __main__ sub-module]
while overriding Django's built-in management commands—in this case,
`runserver`.

The fix, which I will submit as a PR shortly, is to use Python's
[https://docs.python.org/3/reference/import.html#main-spec documented] way
of determining if `-m` was used in `get_child_arguments`:
* The top-level `__main__` module is always the entry point of a
[https://docs.python.org/3/reference/toplevel_components.html#complete-
python-programs complete Python program].
* `__main__.__spec__` is not `None`
[https://docs.python.org/3/reference/import.html#main-spec if and only if]
Python was launched with `-m` or the name of a "directory, zipfile or
other `sys.path` entry." In the latter cases, the
[https://docs.python.org/3/using/cmdline.html#cmdarg-script documentation
says]
> If the script name refers to a directory or zipfile, the script name
is added to the start of `sys.path` and the `__main__.py` file in that
location is executed as the `__main__` module.
* Hence `__main__.__spec__.parent` (which is
[https://docs.python.org/3/reference/import.html#__spec__ usually but not
always] `__main__.__package__`) exists and is the empty string when Python
is started with the name of a directory or zip file.
* Therefore Python was started with `-m pkg` if and only if
`__main__.__spec__.parent == "pkg"`.

Following this algorithm is guaranteed to work as long as Python obeys its
own documentation, and has the side benefit of avoiding use of `__file__`.

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

Django

unread,
Jan 4, 2021, 12:45:00 PM1/4/21
to django-...@googlegroups.com
#32314: Allow autoreloading of `python -m pkg_other_than_django runserver`
-------------------------------------+-------------------------------------
Reporter: William Schwartz | Owner: William
| Schwartz
Type: New feature | Status: assigned
Component: Core (Management | Version: master
commands) |
Severity: Normal | Resolution:
Keywords: runserver, | Triage Stage:
autoreload, freezers | Unreviewed
Has patch: 0 | Needs documentation: 0

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

* owner: nobody => William Schwartz


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

Django

unread,
Jan 4, 2021, 12:45:54 PM1/4/21
to django-...@googlegroups.com
#32314: Allow autoreloading of `python -m pkg_other_than_django runserver`
-------------------------------------+-------------------------------------
Reporter: William Schwartz | Owner: William
| Schwartz
Type: New feature | Status: assigned
Component: Core (Management | Version: master
commands) |
Severity: Normal | Resolution:
Keywords: runserver, | Triage Stage:
autoreload, freezers | Unreviewed
Has patch: 0 | Needs documentation: 0

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

Old description:

> [https://github.com/django/django/blob/b41d38ae26b1da9519a6cd765bc2f2ce7d355007/django/utils/autoreload.py#L213-L246
> django.utils.autoreload.get_child_arguments] detects if Python was
> launched as `python -m django`. Currently it detects only when
> [https://docs.python.org/3/using/cmdline.html#cmdoption-m -m] was passed
> specifically `django` (and only in Python environments in which
> `__file__` is set on modules, which is
> [https://docs.python.org/3/reference/import.html#__file__ not true of all
> Python environments]). Like #32177, this ticket aims to remove one
> impediment to creating Django-based command-line utilities that have
> their own [https://docs.python.org/3/library/__main__.html __main__ sub-

> module] while overriding Django's built-in management commands—in this

New description:

[https://github.com/django/django/blob/b41d38ae26b1da9519a6cd765bc2f2ce7d355007/django/utils/autoreload.py#L213-L246
django.utils.autoreload.get_child_arguments] detects if Python was
launched as `python -m django`. Currently it detects only when
[https://docs.python.org/3/using/cmdline.html#cmdoption-m -m] was passed
specifically `django` (and only in Python environments in which `__file__`
is set on modules, which is
[https://docs.python.org/3/reference/import.html#__file__ not true of all
Python environments]). Like #32177, this ticket aims to remove one
impediment to creating Django-based command-line utilities that have their
own [https://docs.python.org/3/library/__main__.html __main__ sub-module]
while overriding Django's built-in management commands—in this case,
`runserver`.

The fix, which I have submitted in the
[https://github.com/django/django/pull/13837 attached PR], is to use


Python's [https://docs.python.org/3/reference/import.html#main-spec
documented] way of determining if `-m` was used in `get_child_arguments`:
* The top-level `__main__` module is always the entry point of a
[https://docs.python.org/3/reference/toplevel_components.html#complete-
python-programs complete Python program].
* `__main__.__spec__` is not `None`
[https://docs.python.org/3/reference/import.html#main-spec if and only if]
Python was launched with `-m` or the name of a "directory, zipfile or
other `sys.path` entry." In the latter cases, the
[https://docs.python.org/3/using/cmdline.html#cmdarg-script documentation
says]
> If the script name refers to a directory or zipfile, the script name
is added to the start of `sys.path` and the `__main__.py` file in that
location is executed as the `__main__` module.
* Hence `__main__.__spec__.parent` (which is
[https://docs.python.org/3/reference/import.html#__spec__ usually but not
always] `__main__.__package__`) exists and is the empty string when Python
is started with the name of a directory or zip file.
* Therefore Python was started with `-m pkg` if and only if
`__main__.__spec__.parent == "pkg"`.

Following this algorithm is guaranteed to work as long as Python obeys its
own documentation, and has the side benefit of avoiding use of `__file__`.

--

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

Django

unread,
Jan 4, 2021, 2:07:58 PM1/4/21
to django-...@googlegroups.com
#32314: Allow autoreloading of `python -m pkg_other_than_django runserver`
-------------------------------------+-------------------------------------
Reporter: William Schwartz | Owner: William
| Schwartz
Type: New feature | Status: assigned
Component: Core (Management | Version: master
commands) |
Severity: Normal | Resolution:
Keywords: runserver, | Triage Stage:
autoreload, freezers | Unreviewed
Has patch: 0 | Needs documentation: 0

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

* cc: Tom Forbes (added)


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

Django

unread,
Jan 4, 2021, 3:39:02 PM1/4/21
to django-...@googlegroups.com
#32314: Allow autoreloading of `python -m pkg_other_than_django runserver`
-------------------------------------+-------------------------------------
Reporter: William Schwartz | Owner: William
| Schwartz
Type: New feature | Status: assigned
Component: Core (Management | Version: master
commands) |
Severity: Normal | Resolution:
Keywords: runserver, | Triage Stage:
autoreload, freezers | Unreviewed
Has patch: 0 | Needs documentation: 0

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

Comment (by Tom Forbes):

Patch looks good to me - some linting failures, but otherwise it's a
simple and concise fix.

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

Django

unread,
Jan 4, 2021, 3:42:48 PM1/4/21
to django-...@googlegroups.com
#32314: Allow autoreloading of `python -m pkg_other_than_django runserver`
-------------------------------------+-------------------------------------
Reporter: William Schwartz | Owner: William
Type: | Schwartz
Cleanup/optimization | Status: assigned

Component: Core (Management | Version: master
commands) |
Severity: Normal | Resolution:
Keywords: runserver, | Triage Stage: Accepted
autoreload, freezers |
Has patch: 0 | Needs documentation: 0

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

* type: New feature => Cleanup/optimization
* stage: Unreviewed => Accepted


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

Django

unread,
Jan 5, 2021, 3:00:34 PM1/5/21
to django-...@googlegroups.com
#32314: Allow autoreloading of `python -m pkg_other_than_django runserver`
-------------------------------------+-------------------------------------
Reporter: William Schwartz | Owner: William
Type: | Schwartz
Cleanup/optimization | Status: assigned
Component: Core (Management | Version: master
commands) |
Severity: Normal | Resolution:
Keywords: runserver, | Triage Stage: Ready for
autoreload, freezers | checkin
Has patch: 1 | Needs documentation: 0

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

* has_patch: 0 => 1
* stage: Accepted => Ready for checkin


Comment:

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

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

Django

unread,
Jan 6, 2021, 1:40:43 AM1/6/21
to django-...@googlegroups.com
#32314: Allow autoreloading of `python -m pkg_other_than_django runserver`
-------------------------------------+-------------------------------------
Reporter: William Schwartz | Owner: William
Type: | Schwartz
Cleanup/optimization | Status: closed

Component: Core (Management | Version: master
commands) |
Severity: Normal | Resolution: fixed

Keywords: runserver, | Triage Stage: Ready for
autoreload, freezers | checkin
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak <felisiak.mariusz@…>):

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


Comment:

In [changeset:"ec6d2531c59466924b645f314ac33f54470d7ac3" ec6d253]:
{{{
#!CommitTicketReference repository=""
revision="ec6d2531c59466924b645f314ac33f54470d7ac3"
Fixed #32314 -- Fixed detection when started non-django modules with
"python -m" in autoreloader.

django.utils.autoreload.get_child_arguments() detected when Python was
started with the `-m` option only for `django` module. This commit
changes the logic to check __spec__, see
https://docs.python.org/3/reference/import.html#main-spec

Now packages can implement their own __main__ with the runserver
command.
}}}

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

Reply all
Reply to author
Forward
0 new messages