mjs: OAUTH1 support was removed in #218 . Would you mind rebasing so this PR just has the `Address` fix?
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):

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.
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):

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest pytest-cov
3.5
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs==22.2.0
certifi==2021.5.30
coverage==6.2
-e git+https://github.com/mjs/imapclient.git@9e82aa8e7fe0a8cd3b9b6318579a873c9a1bdde6#egg=IMAPClient
importlib-metadata==4.8.3
iniconfig==1.1.1
packaging==21.3
pluggy==1.0.0
py==1.11.0
pyparsing==3.1.4
pytest==7.0.1
pytest-cov==4.0.0
six==1.17.0
tomli==1.2.3
typing_extensions==4.1.1
zipp==3.6.0

name: imapclient
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - attrs==22.2.0
      - coverage==6.2
      - importlib-metadata==4.8.3
      - iniconfig==1.1.1
      - packaging==21.3
      - pluggy==1.0.0
      - py==1.11.0
      - pyparsing==3.1.4
      - pytest==7.0.1
      - pytest-cov==4.0.0
      - six==1.17.0
      - tomli==1.2.3
      - typing-extensions==4.1.1
      - zipp==3.6.0
prefix: /opt/conda/envs/imapclient

imapclient/test/test_response_parser.py::TestParseFetchResponse::test_Address_str
imapclient/test/test_response_parser.py::TestParseResponse::test_bad_literal imapclient/test/test_response_parser.py::TestParseResponse::test_bad_quoting imapclient/test/test_response_parser.py::TestParseResponse::test_complex_mixed imapclient/test/test_response_parser.py::TestParseResponse::test_deeper_nest_tuple imapclient/test/test_response_parser.py::TestParseResponse::test_empty_tuple imapclient/test/test_response_parser.py::TestParseResponse::test_envelopey imapclient/test/test_response_parser.py::TestParseResponse::test_envelopey_quoted imapclient/test/test_response_parser.py::TestParseResponse::test_incomplete_tuple imapclient/test/test_response_parser.py::TestParseResponse::test_int imapclient/test/test_response_parser.py::TestParseResponse::test_int_and_tuple imapclient/test/test_response_parser.py::TestParseResponse::test_literal imapclient/test/test_response_parser.py::TestParseResponse::test_literal_with_more imapclient/test/test_response_parser.py::TestParseResponse::test_nested_tuple imapclient/test/test_response_parser.py::TestParseResponse::test_nil imapclient/test/test_response_parser.py::TestParseResponse::test_quoted_specials imapclient/test/test_response_parser.py::TestParseResponse::test_square_brackets imapclient/test/test_response_parser.py::TestParseResponse::test_string imapclient/test/test_response_parser.py::TestParseResponse::test_tuple imapclient/test/test_response_parser.py::TestParseResponse::test_unquoted imapclient/test/test_response_parser.py::TestParseMessageList::test_basic imapclient/test/test_response_parser.py::TestParseMessageList::test_modseq imapclient/test/test_response_parser.py::TestParseMessageList::test_modseq_interleaved imapclient/test/test_response_parser.py::TestParseMessageList::test_modseq_no_space imapclient/test/test_response_parser.py::TestParseMessageList::test_one_id imapclient/test/test_response_parser.py::TestParseFetchResponse::test_BODY imapclient/test/test_response_parser.py::TestParseFetchResponse::test_BODYSTRUCTURE imapclient/test/test_response_parser.py::TestParseFetchResponse::test_BODY_HEADER_FIELDS imapclient/test/test_response_parser.py::TestParseFetchResponse::test_ENVELOPE imapclient/test/test_response_parser.py::TestParseFetchResponse::test_ENVELOPE_with_empty_addresses imapclient/test/test_response_parser.py::TestParseFetchResponse::test_ENVELOPE_with_invalid_date imapclient/test/test_response_parser.py::TestParseFetchResponse::test_ENVELOPE_with_no_date imapclient/test/test_response_parser.py::TestParseFetchResponse::test_FLAGS imapclient/test/test_response_parser.py::TestParseFetchResponse::test_INTERNALDATE imapclient/test/test_response_parser.py::TestParseFetchResponse::test_INTERNALDATE_normalised imapclient/test/test_response_parser.py::TestParseFetchResponse::test_UID imapclient/test/test_response_parser.py::TestParseFetchResponse::test_bad_UID imapclient/test/test_response_parser.py::TestParseFetchResponse::test_bad_data imapclient/test/test_response_parser.py::TestParseFetchResponse::test_bad_msgid imapclient/test/test_response_parser.py::TestParseFetchResponse::test_basic imapclient/test/test_response_parser.py::TestParseFetchResponse::test_literals imapclient/test/test_response_parser.py::TestParseFetchResponse::test_literals_and_keys_with_square_brackets imapclient/test/test_response_parser.py::TestParseFetchResponse::test_missing_data imapclient/test/test_response_parser.py::TestParseFetchResponse::test_mixed_types imapclient/test/test_response_parser.py::TestParseFetchResponse::test_multiple_messages imapclient/test/test_response_parser.py::TestParseFetchResponse::test_none_special_case imapclient/test/test_response_parser.py::TestParseFetchResponse::test_not_uid_is_key imapclient/test/test_response_parser.py::TestParseFetchResponse::test_odd_pairs imapclient/test/test_response_parser.py::TestParseFetchResponse::test_partial_fetch imapclient/test/test_response_parser.py::TestParseFetchResponse::test_same_message_appearing_multiple_times imapclient/test/test_response_parser.py::TestParseFetchResponse::test_simple_pairs
imapclient/response_types.py
imapclient/response_types.py