I find 'functools.partial' useful, but occasionally I'm unable to use it
because it lacks a 'from the right' version. E.g., to create a function
which splits a string on commas, you can't say
# Won't work when called:
split_comma = partial(str.split, sep = ',')
and to create a 'log to base 10' function, you can't say
# Won't work when called:
log_10 = partial(math.log, base = 10.0)
because str.split and math.log don't take keyword arguments.
PEP-309, which introduces functools.partial, mentions
For completeness, another object that appends partial arguments after
those supplied in the function call (maybe called rightcurry) has
'Completeness' by itself doesn't seem to have been a compelling reason
to introduce this feature, but the above cases show that it would be of
I've created a patch which adds a 'partial_right' function. The two
>>> import functools, math
>>> split_comma = functools.partial_right(str.split, ',')
['a', 'b', 'c']
>>> log_10 = functools.partial_right(math.log, 10.0)
and a general illustrative one:
>>> def all_args(*args): return args
>>> functools.partial_right(all_args, 1, 2)(3, 4)
(3, 4, 1, 2)
I was prompted to look at this by a recent message on python-dev:
Xavier Morel <catch-all(a)masklinn.net>, Thu, 22 Jan 2009 14:44:41 +0100:
> [...] drop(iterable, n) has to be written islice(iterable, n, None)
> (and of course the naming isn't ideal), and you can't really use
> functools.partial since the iterator is the first argument (unless
> there's a way to partially apply only the tail args without kwargs).
Xavier's case becomes:
>>> import functools, itertools
>>> drop = functools.partial_right(itertools.islice, None, None)
>>> list(drop(range(10), 5))
[5, 6, 7, 8, 9]
The patch adds a 'from_right' member to partial objects, which can be
True for the new from-the-right behaviour, or False for the existing
from-the-left behaviour. It's quite small, only c.40 lines, plus a
c.70-line change to test_functools.py. I imagine a documention patch
would be c.20 lines.
Would there be any interest in this?
Here's a question (actually, three questions) for python-dev that
came up in the issue 1717 (removing cmp) discussion.
Once the cmp removal is complete, the type object's tp_compare
slot will no longer be used. The current plan is to rename it to
tp_reserved, change its type to (void *), and raise TypeError when
initializing any type that attempts to put something nonzero into
that slot. But another possibility would be to remove it entirely.
(1) Is it desirable to remove tp_compare entirely, instead of
just renaming it?
(2) If so, for which Python version should that removal take place?
3.0.1? 3.1.0? 4.0?
and the all-important bikeshed question:
(3) In the meantime, what should the renamed slot be called?
tp_reserved? In the issue 1717 discussion, Raymond suggested
Any thoughts? My own opinion is that it really doesn't matter
that much if the slot is left in; it's just a little annoying to have
such backwards-compatibility baggage already present in
the shiny new 3.0 series. A little like finding a big scratch
on your brand-new bright yellow Hummer H3. Or not.
N.B. The same questions apply to nb_reserved (which used
to be nb_long) in the PyNumberMethods structure.
This is my attempt to summarize what everyone has been saying so we
can get this resolved.
>From what I can tell, most people like the idea of doing a 3.0.1
release ASAP (like "in a week or so" fast) with the stuff that should
have been removed from 3.0.0 in the first place removed.
People also seem to support doing a 3.1 release April/May where new
stuff (e.g. io in C, new shelve back-end for sqlite3) is introduced to
the rest of the world. This timeline has the benefit of allowing us to
do an alpha release at PyCon and puts us at a six month release cycle
which does not portray 3.0 or 3.1 as rushed releases.
The sticky points I see are:
1. Barry, who is the release manager for 3.0.1, does not like the idea
of the cruft that is being proposed removed from 3.0.1. Personally I
say we continue to peer pressure him as I think a new major release is
not like our typical minor release, but I am not about to force Barry
to go against what he thinks is reasonable unless I am willing to step
up as release manager (and I am not since I simply don't have the time
to learn the process fast enough along with just a lack of time with
other Python stuff).
2. Do we label 3.0.x as experimental? I say no since it isn't
experimental; we basically had some bugs slip through that happen to
be compatibility problems that were overlooked. I for one never viewed
3.0.x as experimental, just not the best we could necessarily do
without more input from the community and our own experience with 3.x
Let's see if we can get these two points squared away so we can get
3.0.1 in whatever state it is meant to be in out the door quickly.
It is becoming the norm in 3.x for functions to return iterators, generators, or views whereever possible.
I had a thought that pprint() ought to be taught to print iterators:
Currently, all four of those will print something like:
<dict_items object at 0x00FA4470>
<enumerate object at 0x00FC2878>
If pprint() is to give a more useful result, the question is how best to represent the iterators.
In the examples for itertools, I adopted the convention of displaying results
like a collection with no commas or enclosing delimiters:
# chain('ABC', 'DEF') --> A B C D E F
The equivalent for pprint would be the same for items, using space for items on one row or using linefeeds for output too long for
Another idea is to make-up an angle-bracket style to provide a visual cue for iterator output:
<'A' 'B' 'C' 'D' 'E' 'F'>
Perhaps with commas:
<'A', 'B', 'C', 'D', 'E', 'F'>
None of those ideas can be run through eval, nor do they identify the type of iterator. Perhaps these would be better:
<enumerate object: 'A', 'B', 'C', 'D', 'E', 'F'>
iter(['A', 'B', 'C', 'D', 'E', 'F'])
Do you guys have any thoughts on the subject?
Begin forwarded message:
> From: Ludvig Ericson <ludvig(a)lericson.se>
> Date: January 31, 2009 16:43:50 GMT+01:00
> To: Alexander Belopolsky <alexander.belopolsky(a)gmail.com>
> Subject: Re: [Python-Dev] Partial function application 'from the
> On Jan 31, 2009, at 04:02, Alexander Belopolsky wrote:
>> On Fri, Jan 30, 2009 at 7:42 PM, Antoine Pitrou
>> <solipsis(a)pitrou.net> wrote:
>>> If one writes X = partial.skip, it looks quite nice:
>>> split_one = partial(str.split, X, 1)
>> Or even
>> _ = partial.skip
>> split_one = partial(str.split, _, 1)
> Or even
> … = partial.skip
> split_one = partial(str.split, …, 1)
-----BEGIN PGP SIGNED MESSAGE-----
On Jan 29, 2009, at 6:31 AM, A.M. Kuchling wrote:
> If we intend for 3.0 to be a 'beta release', or to weaken the 'no
> features in micro releases' rule, then fine; but we have to be *really
> clear about it*. Are we? (The 3.0 release page calls it
I think it sets bad precedence to downgrade our confidence in the
release. Again, my position is that it's better to stick to the same
development processes we've always used, fix the most egregious
problems in 3.0.1 with no API changes, but spend most of our energy on
a 3.1 release in 6 months.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Darwin)
-----END PGP SIGNATURE-----
I have now converted PEP 374
(http://www.python.org/dev/peps/pep-0374/) from Google Docs to reST
and checked it in. I am not going to paste it into an email as it is
nearly 1500 lines in reST form.
Because there are four authors handling corrections it is a little
different than normal on who you contact to suggest changes. For each
specific VCS there is a primary author as listed in the PEP in the
intro to the Scenarios section. Email the proper author if you find an
issue with a specific VCS. Otherwise email me for general PEP issues.
Core developers can make changes on their own while taking into
account they should let the author in charge of the PEP know if they
make a big change.
Since I will be the author making the final recommendation I am
documenting my thought processes on my decision making for this whole
thing as I go along in the PEP so as to be as transparent as possible.
I am not even close to being done, so please don't email me about the
And I would like to thank my co-authors for their time and effort thus
far in filling in the PEP on behalf of their favorite DVCS. Everyone
has put in a lot of time already with I am sure more time in the
With the extensive changes in the works, Python 3.0.1 is shaping-up to be a complete rerelease of 3.0 with API changes and major
usability fixes. It will fully supplant the original 3.0 release which was hobbled by poor IO performance.
I propose to make the new release more attractive by backporting several module improvements already in 3.1, including two new
itertools and one collections class. These are already fully documented, tested, and checked-in to 3.1 and it would be ashamed to
let them sit idle for a year or so, when the module updates are already ready-to-ship.
Benjamin Peterson wrote:
> On Wed, Jan 28, 2009 at 10:37 PM, brett. cannon
> <python-checkins(a)python.org> wrote:
>> Author: brett.cannon
>> Date: Thu Jan 29 05:37:06 2009
>> New Revision: 69093
>> Backport r69092 by hand since svnmerge keeps saying there is a conflict on '.'.
> Just do "svn resolved ."
There are potential problems with doing it that way . The safer
option is to do:
svn revert .
svnmerge merge -M -F <py3k-rev>
Perhaps we should add a "maintmerge" script (along with "maintmerge.bat"
batch file) to the root development directory that automates this:
svnmerge merge -r $1
svn revert .
svnmerge -M -F $1
(Note that my shell scripting is a little rusty and I haven't actually
executed that example...)
Then the advice will just be to use svnmerge directly most of the time,
and maintmerge when merging a revision that was itself created with
 How to clobber svnmerge's revision tracking 101:
Nick Coghlan | ncoghlan(a)gmail.com | Brisbane, Australia