Opened 44 minutes ago

Last modified 41 minutes ago

#37494 new Cleanup/optimization

Document that RunPython callables receive a StateApps instance

Reported by: Thibaut Decombe Owned by:
Component: Documentation Version: dev
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

The ​`RunPython` docs say the first argument passed to code / reverse_code is "an instance of django.apps.registry.Apps containing historical models".
At runtime it is a django.db.migrations.state.StateApps (see django/db/migrations/operations/special.py, ​RunPython.database_forwards().

This difference matters to users who follow the docs literally, especially when annotating migration functions:

def forwards(apps: Apps, schema_editor: BaseDatabaseSchemaEditor) -> None:
    Person = apps.get_model("myapp", "Person")

Apps is also the type of the global registry (django.apps.apps), whose get_model() returns the current models from models.py.

With the documented annotation, tools such as the django-stubs mypy plugin can't tell this historical registry apart from the global one. They resolve get_model() to the current model class, which may have different fields than the historical model (​https://github.com/typeddjango/django-stubs/issues/3584).

Proposal: mention django.db.migrations.state.StateApps (as a subclass of Apps) in the RunPython docs.

Change History (1)

comment:1 by Thibaut Decombe, 41 minutes ago

Has patch: set
Note: See TracTickets for help on using tickets.
Back to Top