Django backend and gettext wrapper problem
If I send message with subject wrapped into ugettext_lazy, PostMark backend falls down with the following error:
...
File "/usr/local/lib/python2.7/site-packages/postmark/core.py", line 44, in default
return super(PMJSONEncoder, self).default(o)
File "/usr/local/lib/python2.7/site-packages/simplejson/encoder.py", line 252, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: <django.utils.functional.__proxy__ object at 0x7f35c0e1fa10> is not JSON serializable
I've solved this bug locally with subject=str(subject).
I think the best solution may be wrap subject and message body into str.
I'm on the fence on this one. I don't think using ugettext_lazy in code that calls the postmark package is correct. I'd expect in view code that you would not be using the lazy version. But I understand that some people may be doing this, and we might want to handle it.
I think it depends on if you want to enforce some type expectations in the package, or try to coerce any input that comes in. I'd lean towards expecting a string (unicode or otherwise) vs. accepting an object in any of the fields and calling str(...) on every input prior to sending, just because it will be redundant 99% of the time, and possibly unexpected (if it falls back to repr it may not be what the dev expects) another part of the time.
Although, would you then type-check, or just expect that it gets a string?
I'd assume we'd just cast everything to a string before sending. But I agree that it should be assumed that the input for subject is a string. I don't think using lazy translations in view code is correct in general, so this may be a non issue.
I bumped into this.
Use-case: several views that send an e-mail, and have the "subject" of such a mail in a class-level attribute instead of inside a function.
Also, it's clear that it was intended to be supported.
- In https://github.com/themartorana/python-postmark/commit/f9f3d618fa7619ed60a326683f8e9b938e048eaa a change was made to only support "lazy" objects that provided for unicode. (March 2012).
- Then, a bit later in https://github.com/django/django/commit/fe8484efda257e151d9c1ca5151e546c9262bf0f#diff-31c53995d28395e13d586859808522f6 Django made a change in how lazy objects are implemented (August 2012), breaking the change above.
- Now, this package has a custom encoder specifically for this use-case (see https://github.com/themartorana/python-postmark/blob/master/postmark/core.py#L36 ), but it doesn't work since Django 1.5.
Solution would be I think to either remove the custom encoder and explicitly not support it, or to patch the encoder to fully support the latest version of Django, by checking __text_cast.
Thanks @sjoerdjob! If or when we fix this i'll be referencing your details here.