Repository: mjs/imapclient

Issue:
Avoid TypeError when using `str` on Address tuple
Some emails have no mailbox or host (e.g. `undisclosed-recipients` case), so when parsing the ENVELOPE of the message using imapclient, we can get something like this:

```
In [8]: from imapclient.response_types import *
In [9]: addr = Address('Anonymous', None, None, 'undisclosed-recipients')
In [10]: str(addr)
---------------------------------------------------------------------------
.../lib/python3.5/site-packages/imapclient/response_types.py in __str__(self)
     57         return formataddr((
     58             to_unicode(self.name),
---> 59             to_unicode(self.mailbox) + '@' + to_unicode(self.host)))
     60 
     61 

TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'
```

I think the `__str__` method should handle this and just returning `self.mailbox` or `self.host` if the other part is missing. I could write the PR but I prefer to have thoughs about this before.

Discussion:
mjs: OAUTH1 support was removed in #218 . Would you mind rebasing so this PR just has the `Address` fix?

Patch:
diff --git a/imapclient/response_types.py b/imapclient/response_types.py
index ea5d71d..c35dd00 100644
--- a/imapclient/response_types.py
+++ b/imapclient/response_types.py
@@ -80,9 +80,12 @@ class Address(namedtuple("Address", "name route mailbox host")):
     """
 
     def __str__(self):
-        return formataddr((
-            to_unicode(self.name),
-            to_unicode(self.mailbox) + '@' + to_unicode(self.host)))
+        if self.mailbox and self.host:
+            address = to_unicode(self.mailbox) + '@' + to_unicode(self.host)
+        else:
+            address = to_unicode(self.mailbox or self.host)
+
+        return formataddr((to_unicode(self.name), address))
 
 
 class SearchIds(list):


Test patch:
diff --git a/imapclient/test/test_response_parser.py b/imapclient/test/test_response_parser.py
index 3c13534..111188b 100644
--- a/imapclient/test/test_response_parser.py
+++ b/imapclient/test/test_response_parser.py
@@ -491,6 +491,12 @@ class TestParseFetchResponse(unittest.TestCase):
         self.assertEqual(str(Address("Mary Jane", None, "mary", "jane.org")),
                          "Mary Jane <mary@jane.org>")
 
+        self.assertEqual(str(Address("Anonymous", None, "undisclosed-recipients", None)),
+                         "Anonymous <undisclosed-recipients>")
+
+        self.assertEqual(str(Address(None, None, None, "undisclosed-recipients")),
+                         "undisclosed-recipients")
+
 
 
 def add_crlf(text):