[issue47141] EmailMessage may lack Mime-Version
New submission from Vlastimil Zíma : When an `EmailMessage` is created without setting its content, it may lack the `MIME-Version` header. I encountered this behavior when creating a S/MIME signed message, but I believe it applies to any `EmailMessage` in general. Example: from email.message import EmailMessage nested_message = EmailMessage() nested_message.set_content("Gazpacho!") env = EmailMessage() env.add_header("Content-Type", "multipart/signed", protocol="application/pkcs7-signature", micalg='sha-256') env.preamble = "This is an S/MIME signed message" env.attach(nested_message) print(str(env)) This results in a message with no `MIME-Version` header Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg="sha-256"; boundary="===4414940364499332856==" This is an S/MIME signed message --===4414940364499332856== Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit MIME-Version: 1.0 Gazpacho! --===4414940364499332856==-- which violates section 4 of RFC 2045, see https://datatracker.ietf.org/doc/html/rfc2045#section-4 > Messages composed in accordance with this document MUST include such a header field, with the following verbatim text: MIME-Version: 1.0 and the section doesn't seem to be obsoleted by newer MIME related RFCs. It's not clear why the `EmailMessage` shouldn't have the `MIME-Version` header defined in all cases, since it should represent the email message. I suggest to set the `MIME-version` header on `__init__` the same way `MIMEBase` does. -- components: email messages: 416163 nosy: Vlastimil.Zíma, barry, r.david.murray priority: normal severity: normal status: open title: EmailMessage may lack Mime-Version type: behavior versions: Python 3.10, Python 3.9 ___ Python tracker <https://bugs.python.org/issue47141> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue20804] Sentinels identity lost when pickled (unittest.mock)
Vlastimil Zíma added the comment: Since the issue was dug up, I've created a patch for documentation. I still think, that it is worth stating the equality is not preserved for sentinels when copied as the message produced by tests is rather confusing: class SentinelTestCase(TestCase): def test_sentinel(self): self.assertEqual(sentinel.foo, copy(sentinel.foo)) # AssertionError: sentinel.foo != sentinel.foo -- Added file: http://bugs.python.org/file46253/sentinel-doc.patch ___ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue20804> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue20804] Sentinels identity lost when pickled (unittest.mock)
Vlastimil Zíma added the comment: David, first part of your comment should be added to docs. Purpose of sentinels isn't much intuitive and in my opinion documentation doesn't quite describe it. An exception in case of pickle or copy would be much easier to understand apart from unexpected inequality. In my experience negative test in general are uncommon, so I expect usage of sentinels to ensure different objects to be rare. -- ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue20804 ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue20804] Sentinels identity lost when pickled (unittest.mock)
New submission from Vlastimil Zíma: Sentinels lose their identity when they are pickled, meaning they are no longer equal to sentinel with the same name. from mock import sentinel import pickle sentinel.foo == sentinel.foo True pickle.loads(pickle.dumps(sentinel.foo)) == sentinel.foo False I found this bug using Python 2.7.3 and python-mock 1.0.1. Since mock 1.0 is part of Python 3.3 and 3.4 it affects these versions (tested in 3.3.3). This behavior is tricky to find out if encountered in tests and sentinels can not be used in tests of code which uses pickle and possibly other serializations. -- components: Tests messages: 212417 nosy: Vlastimil.Zíma priority: normal severity: normal status: open title: Sentinels identity lost when pickled (unittest.mock) type: behavior versions: Python 3.3, Python 3.4 ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue20804 ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue20804] Sentinels identity lost when pickled (unittest.mock)
Vlastimil Zíma added the comment: I don't question pickle, but I'd expect sentinels to keep their equality when they are pickled or copied. -- ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue20804 ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue20804] Sentinels identity lost when pickled (unittest.mock)
Vlastimil Zíma added the comment: I encountered this problem when I tested code with cache, something like def test_foo(self): cache.set('a_key', sentinel.status) # Performs pickle self.assertEqual( cache.get('a_key'), # Performs unpickle sentinel.status) I spent some time searching for reason why the test failed. Since both sentinels represent themselves as 'sentinel.status', I was quite surprised by assertion failure. Only after I looked at the code I realized where is the problem. Two sentinels are equal if and only if they are identical. On my way home I realized this probably is and needs to be a feature of sentinels. Consider testing this function: def foo(value, do_copy): if do_copy: return bar(copy(value)) else: return bar(value) You would like to know whether `bar` was called with value or its copy. Sentinel is in a test for such function a great option to make sure `value` is not copied in process. This is especially usefull is you write tests for wrapper-like function which should only pass arguments (or a subset) to other interface. After reading through comments and thinking about the problem I have following opinions: * Sentinels should not actually survive pickle/unpickle. * Prevent sentinels from being pickled is a good idea, it is a valid way to tell developer he does something he shouldn't. This might also apply to copying, which would result in the same problem. * It should be noted in documentation that sentinels are equal only if identical. Since they represent themselves by their name it is hard to guess the name is only for the representation. Also I find the documentation snippet assert result is sentinel.some_object somewhat misleading as you don't usually use 'is' for comparison and it provides no information about equality. -- ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue20804 ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com