[issue45299] SMTP.send_message() does from mangling when it should not

2021-11-25 Thread Grant Edwards


Grant Edwards  added the comment:

Yes, passing the mangle_from value to BytesGenerator seems like the safest fix. 
It's unfortunate that BytesGenerator defaults to doing "the wrong thing" in the 
absence of a policy argument, but there might be code that depends on it.

I've never done a PR before, but I could work on it next week.

--

___
Python tracker 
<https://bugs.python.org/issue45299>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue45299] SMTP.send_message() does from mangling when it should not

2021-09-26 Thread Grant Edwards


New submission from Grant Edwards :

SMTP.send_message() does from mangling even when the message's policy
has that disabled. The problem is in the send_messsage() function
shown below:


   912  def send_message(self, msg, from_addr=None, to_addrs=None,
   913   mail_options=(), rcpt_options=()):
   914  """Converts message to a bytestring and passes it to sendmail.
   ...
   963  # Make a local copy so we can delete the bcc headers.
   964  msg_copy = copy.copy(msg)
   ...
   977  with io.BytesIO() as bytesmsg:
   978  if international:
   979  g = email.generator.BytesGenerator(
   980  bytesmsg, policy=msg.policy.clone(utf8=True))
   981  mail_options = (*mail_options, 'SMTPUTF8', 
'BODY=8BITMIME')
   982  else:
   983  g = email.generator.BytesGenerator(bytesmsg)
   984  g.flatten(msg_copy, linesep='\r\n')
   985  flatmsg = bytesmsg.getvalue()

If 'international' is True, then the BytesGenerator is passed
msg.policy with utf8 added, and from mangling is only done if the
message's policy has from mangling enabled. This is correct behavior.

If 'international' is False, then the generator always does from
mangling regardless of the message'spolicy. From mangling is only used
when writing message to mbox format files. When sending a message via
SMTP It is wrong to do it when the message's policy says not to.

This needs to be fixed by passing the message's policy to BytesGenerator()
in the 'else' clause also.  I would suggest changing

   983  g = email.generator.BytesGenerator(bytesmsg)
to

   983  g = email.generator.BytesGenerator(bytesmsg, 
policy=msg.policy)


The problem is that if neither mangle_from_ nor policy arguments are
passed to email.generator.BytesGenerator(), then mangle_from_ defaults
to True, and the mangle_from_ setting in the message is ignored. This is
not really documented:

  
https://docs.python.org/3/library/email.generator.html#email.generator.BytesGenerator

If optional mangle_from_ is True, put a > character in front of
any line in the body that starts with the exact string "From ",
that is From followed by a space at the beginning of a
line. mangle_from_ defaults to the value of the mangle_from_
setting of the policy.
   
Where "the policy" refers to the one passed to BytesGenerator(). Note
that this section does _not_ state what happens if neither
mangle_from_ nor policy are passed to BytesGenerator(). What actually
happens is that in that case mangle_from_ defaults to True. (Not a
good choice for default, since that's only useful for the one case
where you're writing to an mbox file.)

However, there is also a misleading sentence later in that same
section:

If policy is None (the default), use the policy associated with
the Message or EmailMessage object passed to flatten to control
the message generation.

That's only partially true. If you don't pass a policy to
BytesGenerator(), only _some_ of the settings from the message's
policy will be used. Some policy settings (e.g. mangle_from_) are
obeyed when passed to BytesGenerator(), but ignored in the message's
policy even if there was no policy passed to BytesGenerator().

The documentation needs to be changed to state that mangle_from_
defaults to True if neitehr mangle_from_ nor policy are passed to
BytesGenerator(), and that last sentence needs to be changed to state
that when no policy is passed to BytesGenerator() only _some_ of the
fields in the message's policy are used to control the message
generation. (An actual list of policy fields are obeyed from the
message's policy would be nice.)

--
components: Library (Lib)
messages: 402690
nosy: grant.b.edwards
priority: normal
severity: normal
status: open
title: SMTP.send_message() does from mangling when it should not
versions: Python 3.9

___
Python tracker 
<https://bugs.python.org/issue45299>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue43584] Doc description of str.title() upper case vs. title case.

2021-03-21 Thread Grant Edwards


New submission from Grant Edwards :

The documentation for str.title() states that the first character in each world 
is converted to upper case. That is not correct for recent versions of Python. 
The first character in each word is converted to title case. Title and upper 
may be the same for English/ASCII, but other languages have characters for 
which upper and title case are different.

--
assignee: docs@python
components: Documentation
messages: 389242
nosy: docs@python, grant.b.edwards
priority: normal
severity: normal
status: open
title: Doc description of str.title() upper case vs. title case.
versions: Python 3.8

___
Python tracker 
<https://bugs.python.org/issue43584>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com