Skip to content

Fix compatibility issues with django-modeltranslation#649

Open
Hopiu wants to merge 2 commits intojazzband:masterfrom
Hopiu:Fix-django-modeltranslation-compatibility
Open

Fix compatibility issues with django-modeltranslation#649
Hopiu wants to merge 2 commits intojazzband:masterfrom
Hopiu:Fix-django-modeltranslation-compatibility

Conversation

@Hopiu
Copy link
Copy Markdown
Contributor

@Hopiu Hopiu commented Dec 15, 2025

Problem

When using django-model-utils together with django-modeltranslation, registering a model that uses SoftDeletableModel (or other models using manager mixins) causes a TypeError during app initialization:

This occurs because django-modeltranslation patches manager classes by reassigning manager.__class__ to a dynamically created subclass. Python's __class__ assignment has strict layout compatibility requirements, and the Generic[ModelT] base class in our manager mixins causes a layout mismatch.

Fixes #636

Solution

Move the Generic[ModelT] inheritance behind TYPE_CHECKING so it's only present during static type analysis, not at runtime. At runtime, a simple placeholder class _GenericMixin is used instead.

Commandments

  • Write PEP8 compliant code.
  • Cover it with tests.
  • Update CHANGES.rst file to describe the changes, and quote according issue with GH-<issue_number>.
  • Pay attention to backward compatibility, or if it breaks it, explain why.

Benedikt Willi and others added 2 commits December 15, 2025 11:38
…nager mixins

- Added a new class `_GenericMixin` to serve as a runtime placeholder for `Generic[ModelT]`. This change prevents `TypeError` during `__class__` assignments, which was an issue when mixins inherited from `Generic[T]` at runtime.
- All manager mixins have been updated to inherit from `_GenericMixin` instead of `Generic[ModelT]`. This ensures compatibility with `django-modeltranslation`.
- Introduced regressions tests to confirm that the manager instances support `__class__` reassignment without issues. Tests were added for `SoftDeletableManager`, `InheritanceManager`, `QueryManager`, and `JoinManager`.

Closes GH-jazzband#636.
Copilot AI review requested due to automatic review settings January 8, 2026 09:28
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes compatibility issues between django-model-utils and django-modeltranslation by addressing a Python runtime limitation with __class__ assignment when Generic[T] is in the class hierarchy. The fix moves Generic[ModelT] inheritance behind TYPE_CHECKING so it's only present during static type analysis, while using a runtime placeholder class _GenericMixin that supports subscripting but avoids layout incompatibility issues.

  • Introduces a _GenericMixin class that replaces Generic[ModelT] at runtime while maintaining type-checking support
  • Updates all manager mixin classes to inherit from _GenericMixin instead of Generic[ModelT]
  • Adds comprehensive tests to verify __class__ reassignment works correctly for all affected managers

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
model_utils/managers.py Implements the _GenericMixin pattern and updates all mixin classes (InheritanceQuerySetMixin, InheritanceManagerMixin, QueryManagerMixin, SoftDeletableQuerySetMixin, SoftDeletableManagerMixin) to use it
tests/test_managers/test_manager_class_assignment.py Adds regression tests that verify __class__ assignment works for SoftDeletableManager, InheritanceManager, QueryManager, and JoinManager
CHANGES.rst Documents the fix with reference to issue #636
AUTHORS.rst Adds contributor credit for Benedikt Willi

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread CHANGES.rst
Comment on lines +10 to +12
- Fix compatibility with django-modeltranslation: manager mixins no longer
inherit from `Generic[T]` at runtime, preventing `TypeError` on `__class__`
assignment (GH-#636)
Copy link

Copilot AI Jan 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The formatting of the issue reference is inconsistent with other entries in this file. Other entries use the format (GH-#636) at the end of the line, but this entry spans multiple lines with the reference at the end. Consider reformatting to match the style of other entries, such as placing it all on one line or breaking it differently to maintain consistency.

Suggested change
- Fix compatibility with django-modeltranslation: manager mixins no longer
inherit from `Generic[T]` at runtime, preventing `TypeError` on `__class__`
assignment (GH-#636)
- Fix compatibility with django-modeltranslation: manager mixins no longer inherit from `Generic[T]` at runtime, preventing `TypeError` on `__class__` assignment (GH-#636)

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TypeError: __class__ assignment: 'NewMultilingualManager' object layout differs from 'SoftDeletableManager'

2 participants