-
-
Notifications
You must be signed in to change notification settings - Fork 62
[fix] Fixed handling of lazy translation objects #438 #439
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
WalkthroughThe handler now performs a targeted runtime coercion: when kwargs contains Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Organization UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
🧰 Additional context used🧬 Code graph analysis (1)openwisp_notifications/tests/test_notifications.py (2)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (14)
🔇 Additional comments (3)
✏️ Tip: You can disable this entire section by setting Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@openwisp_notifications/handlers.py`:
- Around line 46-61: The _coerce_lazy_strings function is over-eagerly
converting all non-str types to strings; change it so it only coerces Django
lazy translation objects (instances of django.utils.functional.Promise) and
leaves other JSON-serializable types (None, bool, int, float, etc.) intact.
Update _coerce_lazy_strings to import Promise, recursively process dicts/lists
as before, return str(value) only when isinstance(value, Promise), return values
unchanged for str and for all other types (including None, bool, int, float),
and keep the recursion logic for nested structures in functions like
_coerce_lazy_strings itself.
🧹 Nitpick comments (1)
openwisp_notifications/tests/test_notifications.py (1)
114-136: Good regression test, but consider adding coverage for mixed data types.The test correctly verifies that lazy translation objects are coerced to plain strings. However, given the implementation in
_coerce_lazy_strings, it would be valuable to add a sub-test verifying that non-string JSON-serializable values (integers, booleans, None) are preserved as their original types, not converted to strings.💡 Suggested additional test coverage
def test_lazy_translation(self): """ Regression test for issue `#438`. Test that notifications with lazy translation objects in data can be saved without raising a TypeError. """ # Using gettext_lazy in notification data should not fail notification_options = dict( sender=self.admin, description="Test Notification", verb="Test Notification", email_subject="Test Email subject", url="https://localhost:8000/admin", message=_("Translated message"), count=42, # numeric value should be preserved enabled=True, # boolean should be preserved ) # Must not raise TypeError: Object of type __proxy__ is not JSON serializable notify.send(**notification_options) self.assertEqual(notification_queryset.count(), 1) n = notification_queryset.first() # Verify the message was stored as a plain string, not a proxy object self.assertEqual(n.data.get("message"), "Translated message") # Verify the stored value is not a lazy proxy object self.assertNotIsInstance(n.data.get("message"), Promise) # Verify non-string types are preserved self.assertEqual(n.data.get("count"), 42) self.assertIsInstance(n.data.get("count"), int) self.assertEqual(n.data.get("enabled"), True) self.assertIsInstance(n.data.get("enabled"), bool)
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
openwisp_notifications/handlers.pyopenwisp_notifications/tests/test_notifications.py
🧰 Additional context used
🧬 Code graph analysis (1)
openwisp_notifications/tests/test_notifications.py (3)
openwisp_notifications/base/notifications.py (1)
timesince(107-114)openwisp_notifications/base/models.py (2)
email_subject(285-302)message(244-246)openwisp_notifications/api/serializers.py (1)
data(51-56)
🔇 Additional comments (2)
openwisp_notifications/tests/test_notifications.py (1)
20-22: LGTM!The imports for
Promiseandgettext_lazyare appropriate for testing the lazy translation coercion functionality.openwisp_notifications/handlers.py (1)
183-183: Usage is correct, but depends on fixing the helper function.The call site is appropriate—processing
kwargsbefore assignment ensures lazy strings are coerced. However, this will only work correctly once_coerce_lazy_stringsis fixed to preserve non-string JSON-serializable types.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
a26828a to
5e0ca2e
Compare
5e0ca2e to
fbf1a9f
Compare
Lazy translation objects are now evaluated properly.
Fixes #438
Checklist