email with optional headers error
<p>I'm attempting to send a sample email, but get the following error:</p>

<pre><code>&gt;&gt;&gt; import smtplib
&gt;&gt;&gt; from email.mime.text import MIMEText
&gt;&gt;&gt; def send_email(subj, msg, from_addr, *to, host="localhost", port=1025, **headers):
...   email = MIMEText(msg)
...   email['Subject'] = subj
...   email['From'] = from_addr
...   for h, v in headers.items():
...     print("Headers - {} Value {} ".format(h, v))
...     email[h] = v
...   sender = smtplib.SMTP(host,port)
...   for addr in to:
...     del email['To']
...     email['To'] = addr
...     sender.sendmail(from_addr, addr, email.as_string())
...   sender.quit()
...
&gt;&gt;&gt; headers={'Reply-To': 'me2@example.com'}
&gt;&gt;&gt; send_email("first email", "test", "first@example.com", ("p1@example.com", "p2@example.com"), headers=headers)
Headers - headers Value {'Reply-To': 'me2@example.com'} 
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in &lt;module&gt;
  File "&lt;stdin&gt;", line 12, in send_email
  File "/usr/lib/python3.5/email/message.py", line 159, in as_string
    g.flatten(self, unixfrom=unixfrom)
  File "/usr/lib/python3.5/email/generator.py", line 115, in flatten
    self._write(msg)
  File "/usr/lib/python3.5/email/generator.py", line 195, in _write
    self._write_headers(msg)
  File "/usr/lib/python3.5/email/generator.py", line 222, in _write_headers
    self.write(self.policy.fold(h, v))
  File "/usr/lib/python3.5/email/_policybase.py", line 322, in fold
    return self._fold(name, value, sanitize=True)
  File "/usr/lib/python3.5/email/_policybase.py", line 360, in _fold
    parts.append(h.encode(linesep=self.linesep,
AttributeError: 'dict' object has no attribute 'encode'
</code></pre>

<p>When I omit the optional header dictionary, then the email is successfully sent. The **param requires a dictionary, is that correct?
Can anybody suggest a remedy for the error?</p>

<p>You are misunderstanding how <code>*args</code> and <code>**kwargs</code> work. They capture additional positional and keyword arguments, while you are passing in an extra tuple and an extra dictionary as <code>(...)</code> and <code>headers=headers</code>, respectively.</p>

<p>That means that <code>to</code> is now set to <code>(("p1@example.com", "p2@example.com"),)</code> (a tuple containing a single tuple), and <code>headers</code> is set to <code>{'headers': {'Reply-To': 'me2@example.com'}}</code> (a dictionary containing another dictionary).</p>

<p>You see the latter in your output:</p>

<pre><code>Headers - headers Value {'Reply-To': 'me2@example.com'} 
</code></pre>

<p>That's the <code>headers</code> key, referencing a dictionary.</p>

<p>Pass in the <code>to</code> values <em>as separate arguments</em>, and use the <code>**kwargs</code> <em>call</em> syntax to pass in the headers:</p>

<pre><code>headers={'Reply-To': 'me2@example.com'}
send_email("first email", "test", 
           "first@example.com", "p1@example.com", "p2@example.com", 
           **headers)
</code></pre>

<p><code>**headers</code> applies each key-value pair in that dictionary as a separate keyword argument.</p>

python python-3.x smtplib