A small contribution for the excellent-looking new policy framework: typos and markup glitches. HTH http://bugs.python.org/review/11731/diff/2329/5464 ...
Thanks for the review. http://bugs.python.org/review/11731/diff/2329/5464 File Doc/library/email.generator.rst (right): http://bugs.python.org/review/11731/diff/2329/5464#newcode57 Doc/library/email.generator.rst:57: The *policy* keyword specifies a ...
Thanks for the review.
http://bugs.python.org/review/11731/diff/2329/5464
File Doc/library/email.generator.rst (right):
http://bugs.python.org/review/11731/diff/2329/5464#newcode57
Doc/library/email.generator.rst:57: The *policy* keyword specifies a
:mod:`~email.policy` object that controls a
On 2011/04/06 18:17:05, eric.araujo wrote:
> Using a module ref while referencing an object which is an instance of some
> class is strange to me.
That module (and therefore its documentation) defines what a "policy object" is,
so it seems to make sense to me.
http://bugs.python.org/review/11731/diff/2329/5464#newcode61
Doc/library/email.generator.rst:61: .. versionchanged:: 3.3 Added the *policy*
keyword.
On 2011/04/06 18:17:05, eric.araujo wrote:
> Doesn’t that need to be
>
> .. versionchanged:: 3.3
>
> Blah
>
> ?
Nope, Sphinx oddly enough parses out the first token on the line as the version
number.
http://bugs.python.org/review/11731/diff/2329/5464#newcode83
Doc/library/email.generator.rst:83: specified by the ``Generator``\ 's
``policy``.
On 2011/04/06 18:17:05, eric.araujo wrote:
> Note that you can use ``markup``\'s (i.e. without the space) unless I’m
> mistaken.
Thanks, I didn't know that.
http://bugs.python.org/review/11731/diff/2329/5464#newcode160
Doc/library/email.generator.rst:160: .. XXX: There should be a complimentary
option that just does the RFC
On 2011/04/06 18:17:05, eric.araujo wrote:
> complementary*
Heh. At least it was in a comment.
http://bugs.python.org/review/11731/diff/2329/5466
File Doc/library/email.policy.rst (right):
http://bugs.python.org/review/11731/diff/2329/5466#newcode5
Doc/library/email.policy.rst:5: :synopsis: Controlling the parsing and
generating of messages
On 2011/04/06 18:17:05, eric.araujo wrote:
> generation* maybe
It sounds odd to my ear to put generation there. I think 'generating' is
slightly more correct, in that saying it controls the 'generation' would imply
(I think) that it controls *whether or not* the generation is done, where it is
actually controlling *how* the generation is done.
http://bugs.python.org/review/11731/diff/2329/5466#newcode13
Doc/library/email.policy.rst:13: email. Some of these uses hew closely to the
main RFCs, some do not. And even
On 2011/04/06 18:17:05, eric.araujo wrote:
> I don’t understand “hew” here, and my dict doesn’t help.
OK, replaced with the less colloquial 'conform fairly closely'. (FYI, 'hew' is
an old woodworking term; a woodworker of great skill could 'hew' a log into a
desired shape while wasting only a very small portion of the wood, using only an
axe.)
http://bugs.python.org/review/11731/diff/2329/5466#newcode17
Doc/library/email.policy.rst:17: Policy Objects are the mechanism used to
provide the email package with the
On 2011/04/06 18:17:05, eric.araujo wrote:
> objects*
Fixed.
http://bugs.python.org/review/11731/diff/2329/5466#newcode18
Doc/library/email.policy.rst:18: flexibility to handle all these disparate use
cases,
On 2011/04/06 18:17:05, eric.araujo wrote:
> the flexibility needed to* (maybe)
Mmm. Why use more words when fewer mean the same thing? I think I'll leave
this as is unless someone else objects.
http://bugs.python.org/review/11731/diff/2329/5466#newcode49
Doc/library/email.policy.rst:49: >>> msg =
msg_from_binary_file(open('mymsg.txt', 'b'), policy=email.policy.mbox)
On 2011/04/06 18:17:05, eric.araujo wrote:
> You probably want to keep the example as simple as possible, but I’d use a
with
> statement anyway.
Good point. The with actually makes it more readable.
http://bugs.python.org/review/11731/diff/2329/5466#newcode50
Doc/library/email.policy.rst:50: >>> p = Popen(['sendmail',
msg['To][0].address], stdin=PIPE)
On 2011/04/06 18:17:05, eric.araujo wrote:
> 'To' *
I should add the infrastructure to run this as a doctest.
http://bugs.python.org/review/11731/diff/2329/5466#newcode65
Doc/library/email.policy.rst:65: >>> f.write(msg.as_string(policy=mypolicy))
On 2011/04/06 18:17:05, eric.araujo wrote:
> ... *
I don't understand your comment here.
http://bugs.python.org/review/11731/diff/2329/5464
File Doc/library/email.generator.rst (right):
http://bugs.python.org/review/11731/diff/2329/5464#newcode61
Doc/library/email.generator.rst:61: .. versionchanged:: 3.3 Added the *policy*
keyword.
On 2011/04/08 17:42:27, eric.araujo wrote:
> I should check whether this is a documented feature, an undocumented one or a
> bug to report. It looks very non-intuitive and ugly to me.
Well, it's documented in the sense that the version number is the 'first
argument' and the description is the second, and the second argument in rest can
follow on the same line or be on the next line. I've seen it used elsewhere in
the docs, and I prefer it (one less line of text, especially when the
explanation is short...as it should be ;)
http://bugs.python.org/review/11731/diff/2329/5465
File Doc/library/email.parser.rst (right):
http://bugs.python.org/review/11731/diff/2329/5465#newcode123
Doc/library/email.parser.rst:123: .. versionchanged:: 3.3
On 2011/04/08 17:42:27, eric.araujo wrote:
> This compiles without needing a blank line?
There is no blank line between the versionchanged and the description. See the
sphinx docs.
http://bugs.python.org/review/11731/diff/2329/5466
File Doc/library/email.policy.rst (right):
http://bugs.python.org/review/11731/diff/2329/5466#newcode50
Doc/library/email.policy.rst:50: >>> p = Popen(['sendmail',
msg['To][0].address], stdin=PIPE)
> The directives you’ll need are described at
> http://sphinx.pocoo.org/ext/doctest.html
Thanks, but yes, that was the infrastructure of which I was speaking.
http://bugs.python.org/review/11731/diff/2329/5466#newcode65
Doc/library/email.policy.rst:65: >>> f.write(msg.as_string(policy=mypolicy))
On 2011/04/08 17:42:27, eric.araujo wrote:
> That was indeed cryptic :) s/>>>/.../ should be better. IOW, use the
> continuation prompt on continued lines.
Ah, yes, another place were running the doctest would be nice.
http://bugs.python.org/review/11731/diff/2329/5466#newcode73
Doc/library/email.policy.rst:73: >>> strict_SMTP =
email.policy.SMTP(raise_on_defect=True)
On 2011/04/08 17:42:27, eric.araujo wrote:
> I thought you were using lowercase names for shipped-with policies? default,
> smtp, strict (a good naming IMO).
I stuck with upper case for those things that are actually acronyms, which feels
more natural to me. Open for discussion on that, though.
http://bugs.python.org/review/11731/diff/2418/5678 File Lib/email/feedparser.py (right): http://bugs.python.org/review/11731/diff/2418/5678#newcode183 Lib/email/feedparser.py:183: self.policy.handle_defect(root, defect) This looks like a common pattern. I ...
Thanks for the reviews.
http://bugs.python.org/review/11731/diff/2418/5678
File Lib/email/feedparser.py (right):
http://bugs.python.org/review/11731/diff/2418/5678#newcode183
Lib/email/feedparser.py:183: self.policy.handle_defect(root, defect)
On 2011/04/15 14:46:31, barry wrote:
> This looks like a common pattern. I wonder if .handle_defect() shouldn't
(also)
> accept a defect class, which it could no-arg instantiate. Then you'd end up
> with a common case of:
>
> self.policy.handle_defect(root, errors.MultipartInvariantViolationsDefect)
>
> yeah, maybe that's not a great improvement. Just throwing it out there.
Well, you are only saving two characters at the expense of complexifying
handle_defect (it has to do an argument type check). So I'd vote no.
http://bugs.python.org/review/11731/diff/2418/5681
File Lib/email/policy.py (right):
http://bugs.python.org/review/11731/diff/2418/5681#newcode57
Lib/email/policy.py:57: def __call__(self, **kw):
On 2011/04/15 16:40:05, eric.araujo wrote:
> Agreed.
Well, copy won't work because to be consistent with other uses of copy in python
it should produce an exact copy. You could say the same thing about clone, but
then why two different names...so I guess
new_policy = old_policy.clone(linesep='\000')
would be OK. I think the call form reads better, but I'm not attached to it.
http://bugs.python.org/review/11731/diff/2418/5681#newcode101
Lib/email/policy.py:101: with keyword arguments. Policy objects can also be
added,
On 2011/04/15 14:46:31, barry wrote:
> s/added/combined using the addition operator/
Yes, that's better. Fixed.
http://bugs.python.org/review/11731/diff/2418/5681#newcode124
Lib/email/policy.py:124: defect is a Defect subclass. The default
implementation appends defect
On 2011/04/15 14:46:31, barry wrote:
> With the current semantics, I think `defect` actually must be an instance of a
> Defect subclass. But see my comment in the other file.
Good point. And given my response, I've fixed this wording.
http://bugs.python.org/review/11731/diff/2418/5681#newcode140
Lib/email/policy.py:140: """Based on policy, either raise defect or all
register_defect.
On 2011/04/15 14:46:31, barry wrote:
> s/all/call/
fixed
http://bugs.python.org/review/11731/diff/2418/5685
File Lib/test/test_email/test_policy.py (right):
http://bugs.python.org/review/11731/diff/2418/5685#newcode34
Lib/test/test_email/test_policy.py:34: ("change {} docs/docstrins if defaults
have "
On 2011/04/15 14:46:31, barry wrote:
> s/docstrins/docstrings/
fixed
http://bugs.python.org/review/11731/diff/2418/5685#newcode48
Lib/test/test_email/test_policy.py:48: for policy in self.policies.keys():
On 2011/04/15 14:46:31, barry wrote:
> .keys() is so retro! :)
These days I think it's called "old school" :)
Fixed.
http://bugs.python.org/review/11731/diff/2329/5466
File Doc/library/email.policy.rst (right):
http://bugs.python.org/review/11731/diff/2329/5466#newcode73
Doc/library/email.policy.rst:73: >>> strict_SMTP =
email.policy.SMTP(raise_on_defect=True)
On 2011/04/15 16:45:16, eric.araujo wrote:
> Here I believe that internal module consistency is the main concern. Having
> some policies lower-case and some other upper-case brings IMO no benefit and
> could cause confusion.
Got this set of comments after my last response. I guess I'm
willing to be convinced by this argument, though apparently
my fingers have a hard time with it :)
http://bugs.python.org/review/11731/diff/2418/5678
File Lib/email/feedparser.py (right):
http://bugs.python.org/review/11731/diff/2418/5678#newcode183
Lib/email/feedparser.py:183: self.policy.handle_defect(root, defect)
On 2011/04/15 17:23:01, r.david.murray wrote:
> On 2011/04/15 14:46:31, barry wrote:
> > This looks like a common pattern. I wonder if .handle_defect() shouldn't
> (also)
> > accept a defect class, which it could no-arg instantiate. Then you'd end up
> > with a common case of:
> >
> > self.policy.handle_defect(root, errors.MultipartInvariantViolationsDefect)
> >
> > yeah, maybe that's not a great improvement. Just throwing it out there.
>
> Well, you are only saving two characters at the expense of complexifying
> handle_defect (it has to do an argument type check). So I'd vote no.
Yeah, you're right.
http://bugs.python.org/review/11731/diff/2418/5681
File Lib/email/policy.py (right):
http://bugs.python.org/review/11731/diff/2418/5681#newcode57
Lib/email/policy.py:57: def __call__(self, **kw):
On 2011/04/15 17:23:01, r.david.murray wrote:
> On 2011/04/15 16:40:05, eric.araujo wrote:
> > Agreed.
>
> Well, copy won't work because to be consistent with other uses of copy in
python
> it should produce an exact copy. You could say the same thing about clone,
but
> then why two different names...so I guess
>
> new_policy = old_policy.clone(linesep='\000')
>
> would be OK. I think the call form reads better, but I'm not attached to it.
Call syntax just seems anti-discoverable, but I agree that .clone() and .copy()
aren't perfect fits either. Maybe .derive() ? Anyway, I'm just babbling so you
decide. :)
> Call syntax just seems anti-discoverable,
Thanks for wording so clearly this reason for not using __call__.
> but I agree that .clone() and .copy() aren't perfect fits either.
> Maybe .derive() ? Anyway, I'm just babbling so you decide. :)
Named tuples support prototype-like programming with a method called _make.
(See Raymond’s talk about Python’s newer tools). Bikeshedding-ly yours.
http://bugs.python.org/review/11731/diff/2329/5466
File Doc/library/email.policy.rst (right):
http://bugs.python.org/review/11731/diff/2329/5466#newcode73
Doc/library/email.policy.rst:73: >>> strict_SMTP =
email.policy.SMTP(raise_on_defect=True)
Barry says:
> I dunno, SMTP and HTTP don't bother me or seem
> inconsistent.
I meant that the whole collection of provided policies would be inconsistent:
SMTP, default, HTTP, strict, etc. If some of them are all caps and other
lowercase, does that mean that they’re of two kinds? Can I do “policy1 +
policy2” will all kinds or is it “(HTTP|SMTP) + (strict|other)”? It’s this kind
of questions that I’d like to prevent by using only one capitalization style.
On 2011/04/15 18:30:35, eric.araujo wrote:
> > Call syntax just seems anti-discoverable,
> Thanks for wording so clearly this reason for not using __call__.
>
> > but I agree that .clone() and .copy() aren't perfect fits either.
> > Maybe .derive() ? Anyway, I'm just babbling so you decide. :)
>
> Named tuples support prototype-like programming with a method called _make.
> (See Raymond’s talk about Python’s newer tools). Bikeshedding-ly yours.
I replied via email but I guess that doesn't show up here. I've gone with
'clone', though 'derive' would be OK too. make in namedtuple takes an argument
that completely defines the contents of the returned object, which makes sense
for the word 'make'. The policy function copies the existing content and then
modifies it, so 'make' doesn't really work.
http://bugs.python.org/review/11731/diff/2329/5466
File Doc/library/email.policy.rst (right):
http://bugs.python.org/review/11731/diff/2329/5466#newcode73
Doc/library/email.policy.rst:73: >>> strict_SMTP =
email.policy.SMTP(raise_on_defect=True)
On 2011/04/15 18:35:30, eric.araujo wrote:
> Barry says:
> > I dunno, SMTP and HTTP don't bother me or seem
> > inconsistent.
>
> I meant that the whole collection of provided policies would be inconsistent:
> SMTP, default, HTTP, strict, etc. If some of them are all caps and other
> lowercase, does that mean that they’re of two kinds? Can I do “policy1 +
> policy2” will all kinds or is it “(HTTP|SMTP) + (strict|other)”? It’s this
kind
> of questions that I’d like to prevent by using only one capitalization style.
Because SMTP and HTTP are usually written as acronyms I think that's what people
will "expect", so I'm going to leave them as is. However, if it turns out that
it does cause confusion when people try out the code when we get to the point of
wider testing, we can always change it.
On 2011/04/15 19:14:23, r.david.murray wrote:
> I replied via email but I guess that doesn't show up here. I've gone with
> 'clone', though 'derive' would be OK too. make in namedtuple takes an
argument
> that completely defines the contents of the returned object, which makes sense
> for the word 'make'. The policy function copies the existing content and then
> modifies it, so 'make' doesn't really work.
Barry replied to my email that didn't get reported here pointing out that
policy.default.clone() is an unmodified clone, which I think cinches the
decision in favor of the name 'clone'.
So, I think the patch is ready for commit.
Issue 11731: Simplify email API via 'policy' objects
Created 2 years, 1 month ago by r.david.murray
Modified 2 years, 1 month ago
Reviewers: eric.araujo, barry
Base URL: None
Comments: 61