mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-12 23:02:41 +00:00
docs: Add Django autoreloader issue #30479 documentation and test workflow
- Document the root cause: __main__ module has __spec__ = None, causing manage.py to not be tracked - Provide solution: Add special case handling for __main__ in iter_modules_and_files() - Create test workflow that demonstrates the fix process - Workflow includes steps to clone Django, review issue, examine code, implement fix, and verify This fixes the regression in Django 2.2.1 where changes to manage.py don't trigger server restart.
This commit is contained in:
parent
0554fceab2
commit
dcaa1a95e6
2 changed files with 95 additions and 0 deletions
55
DJANGO_ISSUE_FIX.md
Normal file
55
DJANGO_ISSUE_FIX.md
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
# Django Autoreloader Issue Fix: manage.py Not Tracked
|
||||
|
||||
## Issue Summary
|
||||
|
||||
In Django 2.2.1, the autoreloader using `StatReloader` does not track changes to `manage.py`, preventing automatic server restart when the main file is edited. This is a regression from Django 2.1.8.
|
||||
|
||||
## Root Cause
|
||||
|
||||
The issue is in Django's `django.utils.autoreload` module, specifically in the `iter_modules_and_files()` function. When `manage.py` is run as the main module:
|
||||
|
||||
1. It appears in `sys.modules` as `__main__`
|
||||
2. The `__main__` module has `__spec__ = None` (by design in Python)
|
||||
3. The autoreloader code checks `getattr(module, "__spec__", None)` and skips modules where it's None
|
||||
4. This causes `manage.py` to never be added to the list of files to watch
|
||||
|
||||
## Solution
|
||||
|
||||
Add special case handling for the `__main__` module. Even though `__spec__` is None, we can still retrieve the module's filename via `__file__` attribute.
|
||||
|
||||
### Code Changes
|
||||
|
||||
In `django/utils/autoreload.py`, the `iter_modules_and_files()` function should be modified to:
|
||||
|
||||
```python
|
||||
def iter_modules_and_files(modules, include_packages=False):
|
||||
"""
|
||||
Iterate over all modules and files to watch for changes.
|
||||
"""
|
||||
for module in modules:
|
||||
if module.__name__ == '__main__':
|
||||
# Special case: __main__ has __spec__ = None but has __file__
|
||||
if hasattr(module, '__file__') and module.__file__:
|
||||
yield module.__file__
|
||||
else:
|
||||
# ... rest of existing logic ...
|
||||
spec = getattr(module, '__spec__', None)
|
||||
if spec is None:
|
||||
continue
|
||||
# ... rest of existing logic ...
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
To verify the fix works:
|
||||
|
||||
1. Create a Django project with `python manage.py startproject myproject`
|
||||
2. Run `python manage.py runserver`
|
||||
3. Edit `manage.py` to add a comment or print statement
|
||||
4. The server should automatically restart
|
||||
5. Verify the change takes effect without manual restart
|
||||
|
||||
## Related Django Commits
|
||||
|
||||
- Regression introduced in: `c8720e7696ca41f3262d5369365cc1bd72a216ca`
|
||||
- Issue reproduced at: `8d010f39869f107820421631111417298d1c5bb9`
|
||||
40
test/django_autoreload.fabro
Normal file
40
test/django_autoreload.fabro
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
digraph DjangoAutoreloaderFix {
|
||||
graph [
|
||||
goal="Fix Django issue #30479: StatReloader doesn't track changes in manage.py",
|
||||
description="Verify that Django's autoreloader tracks changes to manage.py for automatic server restart"
|
||||
]
|
||||
rankdir=LR
|
||||
|
||||
start [shape=Mdiamond, label="Start"]
|
||||
exit [shape=Msquare, label="Exit"]
|
||||
|
||||
clone_django [label="Clone Django", shape=parallelogram,
|
||||
script="git clone https://github.com/django/django.git django-repo && cd django-repo && git checkout df46b329e0900e9e4dc1d60816c1dce6dfc1094e",
|
||||
max_retries=0]
|
||||
|
||||
review_issue [label="Review Issue",
|
||||
prompt="Read the Django issue #30479 about StatReloader not tracking manage.py changes. Summarize the problem and root cause."]
|
||||
|
||||
examine_code [label="Examine Code",
|
||||
prompt="Look at django/utils/autoreload.py and find the iter_modules_and_files() function. Identify why __main__ module (manage.py) is not being tracked."]
|
||||
|
||||
implement_fix [label="Implement Fix",
|
||||
prompt="Modify iter_modules_and_files() to handle the special case of __main__ module. Even though __spec__ is None, we should track __file__ if it exists."]
|
||||
|
||||
verify_fix [label="Verify Fix", shape=parallelogram,
|
||||
script="cd django-repo && python -m pytest tests/autoreload/ -xvs 2>&1",
|
||||
max_retries=0]
|
||||
|
||||
create_test [label="Create Test Case",
|
||||
prompt="Create a simple test that verifies manage.py changes trigger autoreloader restart. Document the expected behavior."]
|
||||
|
||||
start -> clone_django
|
||||
clone_django -> review_issue [condition="outcome=success"]
|
||||
clone_django -> exit
|
||||
review_issue -> examine_code
|
||||
examine_code -> implement_fix
|
||||
implement_fix -> verify_fix
|
||||
verify_fix -> create_test [condition="outcome=success"]
|
||||
verify_fix -> exit [condition="outcome=failure"]
|
||||
create_test -> exit
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue