[Python-Dev] Avoiding error from repr() of recursive dictview

2013-07-22 Thread Ben North
Hi,

A friend of mine, Ruadhan O'Flanagan, came across a bug which turned out
to be the one noted in [http://bugs.python.org/issue18019], i.e.:

>>> d={}
>>> d[42]=d.viewvalues()
>>> d


This issue has been fixed in hg; the behaviour now is that a
RuntimeError is produced for a recursive dictionary view:

>>> d={}
>>> d[42]=d.viewvalues()
>>> d # (output line-broken:)
{42: Traceback (most recent call last):
  File "", line 1, in 
RuntimeError: maximum recursion depth exceeded
  while getting the repr of a list

Before finding this, though, I'd investigated and made a patch which
produces a similar "..." output to a recursive dictionary.  Reworking
against current 2.7, the behaviour would be:

>>> x={}
>>> x[42]=x
>>> x # existing behaviour for dictionaries:
{42: {...}}

>>> d={}
>>> d[42]=d.viewvalues()
>>> d # new behaviour:
{42: dict_values([...])}
>>> d[43]=d.viewitems()
>>> d # (output line-broken:)
{42: dict_values([..., dict_items([(42, ...), (43, ...)])]),
 43: dict_items([(42, dict_values([..., ...])), (43, ...)])}

Attached is the patch, against current 2.7 branch.  If there is interest
in applying this, I will create a proper patch (changelog entry, fix to
Lib/test/test_dictviews.py, etc.).

Thanks,

Ben.


non-error-recursive-dictview.patch
Description: Binary data
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Avoiding error from repr() of recursive dictview

2013-07-22 Thread Ben North
Hi Greg,

Thanks for the feedback.

On 22 July 2013 23:01, Gregory P. Smith  wrote:
> On Mon, Jul 22, 2013 at 2:44 PM, Ben North  wrote:
>> [... proposed change of behaviour such that a recursive
>> dictview gives a repr() with "..." rather than a RuntimeError ...]
>
> [...] Post it on an issue on bugs.python.org.

http://bugs.python.org/issue18533

Ben.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Partial function application 'from the right'

2009-02-09 Thread Ben North
Hi,

As suggested, I've created

   http://bugs.python.org/issue5191

to hold the patches for this feature, and the relation to the
'partial.skip' feature request.  Could somebody with appropriate
privileges close the issue as rejected, if indeed that is the decision?

Thanks,

Ben.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Suggested doc patch for tarfile

2009-04-23 Thread Ben North
Hi,

The current documentation for tarfile.TarFile.extractfile() does not
mention that the returned 'file-like object' supports close() and also
iteration.  The attached patch (against svn trunk) fixes this.

(Background: I was wondering whether I could write

   def process_and_close_file(f_in):
   with closing(f_in) as f:
   # Do stuff with f.

and have it work whether f_in was a true file or the return value of
extractfile(), and thought from the documentation that I couldn't.  Of
course, I could have just tried it, but I think fixing the documentation
wouldn't hurt.)

Alternative: enhance the tarfile.ExFileObject class to support use as a
context manager?

Thanks,

Ben.


tarfile.rst.patch
Description: Binary data
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Suggested doc patch for tarfile

2009-04-23 Thread Ben North
>> The current documentation for tarfile.TarFile.extractfile() does not
>> mention that the returned 'file-like object' supports close() and also
>> iteration.  The attached patch (against svn trunk) fixes this.
>
> Please post the patch to bugs.python.org

Done:

   http://bugs.python.org/issue5821

Thanks,

Ben.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] New syntax for 'dynamic' attribute access

2007-02-11 Thread Ben North
Hi,

A few days ago I posted to python-ideas with a suggestion for some new
Python syntax, which would allow easier access to object attributes
where the attribute name is known only at run-time.  For example:

   setattr(self, method_name, getattr(self.metadata, method_name))

from Lib/distutils/dist.py could be rewritten

   self.(method_name) = self.metadata.(method_name)

The new syntax would also be usable in augmented assignments, as in

   obj.(attr_name) += 1

There was some discussion on python-ideas, which I've linked to in the
draft PEP below.  In particular, Guido van Rossum wrote:

 > I've thought of the same syntax. I think you should submit this to the
 > PEP editor and argue on Python-dev for its inclusion in Python 2.6 --
 > there's no benefit that I see of waiting until 3.0.

so here I am.  Does anybody have any opinions/suggestions, particularly
on the "open questions" referred to in the draft PEP?  To summarise
these open questions:

* The draft currently allows a two-argument form, to supply a default
  value if the object has no attribute of that name.  This mimics the
  behaviour of the three-argument form of getattr, but looks a bit wrong:

 s = obj.(attr_name, 'default string')

  I agree that it looks odd, but perhaps the extra expressive power
  gained might be worth the oddness.

* The draft implementation (a sourceforge patch, linked to in the draft
  PEP) may have a general performance penalty of around 1%, although my
  initial measurements were quite noisy.  Josiah Carlson thought this
  would not be too substantial, but he did suggest a couple of other
  implementation routes which could be explored.  The general
  performance hit is offset by a speed gain of around 40% for attribute
  access using the new syntax over getattr etc.  Is 1% "too much" for
  this feature?

Ben.

- - - - 8< - - - -
PEP: 363 [PROVISIONAL NUMBER]
Title: Syntax For Dynamic Attribute Access
Version: $Revision$
Last-Modified: $Date$
Author: Ben North 
Status: Draft
Type: Standards Track
Content-Type: text/plain
Created: 29-Jan-2007
Post-History:


Abstract

Dynamic attribute access is currently possible using the "getattr"
and "setattr" builtins.  The present PEP suggests a new syntax to
make such access easier, allowing the coder for example to write

x.('foo_%d' % n) += 1

z = y.('foo_%d' % n).('bar_%s' % s)

instead of

attr_name = 'foo_%d' % n
setattr(x, attr_name, getattr(x, attr_name) + 1)

z = getattr(getattr(y, 'foo_%d' % n), 'bar_%s' % s)


Note

(I wrote this patch mostly to advance my own understanding of and
experiment with the python language, but I've written it up in the
style of a PEP in case it might be a useful idea.)


Rationale

Dictionary access and indexing both have a friendly invocation
syntax: instead of x.__getitem__(12) the coder can write x[12].
This also allows the use of subscripted elements in an augmented
assignment, as in "x[12] += 1".  The present proposal brings this
ease-of-use to dynamic attribute access too.

Attribute access is currently possible in two ways:

* When the attribute name is known at code-writing time, the
  ".NAME" trailer can be used, as in

  x.foo = 42
  y.bar += 100

* When the attribute name is computed dynamically at run-time, the
  "getattr" and "setattr" builtins must be used:

  x = getattr(y, 'foo_%d' % n)
  setattr(z, 'bar_%s' % s, 99)

  The "getattr" builtin also allows the coder to specify a default
  value to be returned in the event that the object does not have
  an attribute of the given name:

  x = getattr(y, 'foo_%d' % n, 0)

This PEP describes a new syntax for dynamic attribute access ---
"x.(expr)" --- with examples given in the Abstract above.  The new
syntax also allows the provision of a default value in the "get"
case, as in:

x = y.('foo_%d' % n, None)

This 2-argument form of dynamic attribute access is not permitted as
the target of an (augmented or normal) assignment.  Also, this part
of the new syntax was not as well received [6] in initial
discussions on python-ideas, and I agree that it does not fit so
cleanly.  I'm happy to prepare a revised PEP/patch without the
2-argument form if the consensus is that this would be preferred.

Finally, the new syntax can be used with the "del" statement, as in

del x.(attr_name)


Impact On Existing Code

The proposed new syntax is not currently valid, so no existing
well-formed programs have their meaning altered by this proposal.

Across all "*.py" files in the 2.5 distr

[Python-Dev] New syntax for 'dynamic' attribute access

2007-02-12 Thread Ben North
Thanks for the comments so far on this.  First, on the general idea:

Neil Toronto:
> I like it.
> [...]
> >   obj.(attr_name) += 1
> Even nicer; much, much better than the current spelling.

Brett Cannon:
> +0 on the one-item version.

Anthony Baxter:
> -1 from me.

Collin Winter:
> I like the general idea [...] I'm +0 on the idea

Jack Jansen:
> I like the functionality,

Raymond Hettinger:
> I also like the functionality.

Generally gently positive, with the exception of Anthony Baxter's
"-1", which I understand to be motivated by concerns about newcomers to
the syntax:

> Someone coming across this syntax for the first time will not have any
> hints as to what it means - and worse, it looks like a syntax error to
> me.

This was echoed by Collin Winter:

> Also, like Anthony Baxter said, someone coming across this for the
> first time will think it's a syntax error, allusions to MATLAB and
> assembly indirection syntax not withstanding. [...] -1 on the means.

I think the argument "someone who hasn't come across it before won't
know what it is" could be applied to any new syntax, for instance the
new "with" statement, or going further back in time, the introduction of
Booleans, semantics of "__slots__", the "extended print" syntax, the
"list comprehension" syntax, the "augmented assignment" syntax, etc.
Some of these were perhaps more transparent than others, but for
instance "with" needs a bit of study to fully understand what's going
on.  I would argue that the newness itself is not sufficient reason to
reject this.

Also, I think it's a good thing that it looks like a syntax error --- it
*is* currently a syntax error.  A newcomer will be alerted to the fact
that something new is going on and will know to go and find out about
it.  I am happy to write a paragraph for the "what's new" release notes,
and/or new section(s) for the documentation describing the new syntax.


On the two-argument form, feeling was generally pretty negative, with a
few "-1"s thrown in.  I propose to cut this piece out of the PEP,
leaving just the one-argument form.  If a default value is required, the
coder can still use the three-argument form of "getattr".  To be clear
(and I'll put this in the PEP), I'm *not* suggesting that python loses
"getattr", "setattr", or "delattr".


On the syntax:

Brett Cannon:
> It just makes it look like too much of a function call at that point
> to me

Collin Winter:
> the syntax looks like dirt on my monitor.  The period is too easy to
> lose visually and without it, there's nothing to distinguish this from
> a function call.

Jack Jansen:
> I don't like the syntax, to me it looks too much like a method call.

(Some of the initial comments in python-ideas were along these lines
too.)  My personal opinion is that "obj.(foo)" is distinct enough from
"obj(foo)" to not cause confusion, but perhaps in a proportional font it
is less clear.

Some people made concrete suggestions as to what syntax could be used
instead:

Jack Jansen:
> To me self.[method_name] = self.metadata.[method_name] looks better:
> what we're doing here is more like dictionary lookup than calling
> functions.

In the same way, though, would this be viewed as too similar to normal
dictionary/list indexing?

Raymond Hettinger:
> Rather than munge existing syntaxes, an altogether new one would be
> more clear:
>
>self->name = self.metadata->name

One thing which comes to mind about this one is that, for C/C++
programmers, the difference between

   obj.memberand obj->member

is the interpretation of the thing on the *left* of the dot or arrow,
whereas the PEP is discussing a new interpretation of the thing on the
*right* of the dot.

One idea mentioned in the PEP is to bring {}s into service here, but I
think the dot should be kept to keep it looking like an attribute
access.  What would the reaction be to

   obj.{member}

instead?  Braces are already used to construct dictionaries, so this has
some of the right connotations.  It could not be confused with either a
function call or a dictionary lookup/list indexing.

(Nobody had any comments on the potential 1% performance hit --- is this
because it's too early to worry about implementation details?)

Thanks,

Ben.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] New syntax for 'dynamic' attribute access

2007-02-12 Thread Ben North
Apologies: I overlooked a couple of replies in my summary earlier.  Tim
Delaney and Terry Reedy both responded in positive terms to the
one-argument form and its syntax, and in negative terms to the
two-argument form.

Also, I missed the fact that Neil Toronto had made the same point as me
when he said:
> I'm not sure the "looks like a syntax error" argument holds much weight,
> because any new syntax is likely to be a syntax error until the syntax
> is changed. :)

he also suggested:
>obj.*str_expression

but I'm a bit uneasy about this, although the similarity with C's
dereferencing is in its favour.  Also, '*' in python is already used for
"and the rest" arguments in function calls.

Anthony Baxter cooled off a bit on the idea too:
> after thinking about it a bit, I'm still not convinced this is
> something that needs shorthand syntax

Maybe not, but for the cases where you do want to do dynamic attribute
access, I think there is a win in readability from nested getattr and/or
setattr calls.

Georg Brandl:
> -1 here too. I fear that this gets too indistinguishable from normal
> calling syntax,

I think, from the context, that this is "-1" on the syntax rather than
the idea as a whole, but I could have misread Georg's message.  Possibly
a "-0" on the idea?

Greg Ewing:
> In my experience, the amount of code which truly needs
> to use getattr is extremely small.

Another "-0"?

Gustavo Carneiro:
> -1 from me.  It does not solve a common problem, therefore it does not
> deserve a special syntax.

It's not *that* uncommon, judging by the c.600 uses in the existing
library code.

> Moreover, the existing syntax may be longer
> to type but is far more readable.

I disagree, although I can see that there might be a small time during
which one is getting familiar with the new syntax.  Others have voiced
the opinion that it's a readability win.

Tim Delaney asked in particular:
> Have you checked if [the existing uses of getattr, where "getattr" in
> that scope is a function argument with default value the built-in
> "getattr"] are intended to bring the "getattr" name into local scope
> for fast lookup, or to force a binding to the builtin "gettattr" at
> compile time (two common (ab)uses of default arguments)?  If they are,
> they would be better served by the new syntax.

They're all in Lib/codecs.py, and are of the form:

class StreamRecoder:
def __getattr__(self, name,
getattr=getattr):

""" Inherit all other methods from the underlying stream.
"""
return getattr(self.stream, name)

Without digging deeper into that code I'm afraid I can't say precisely
what is going on.

Ben.


___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] New syntax for 'dynamic' attribute access

2007-02-12 Thread Ben North
Guido van Rossum wrote:
 > - There's near-universal dislike for the two-arg form, so let's drop
 > that part of the proposal.

This is a strong consensus, definitely, so we can conclude that this
point has been decided.  I will remove it from the PEP.

Guido also wrote:
 > - There's a lot of support for the basic idea, and only a few
 > naysayers, so let's keep looking for a syntax that works.

If we can take that as a decision, then the various proposals for the
syntax break down as follows.


By raw numbers, the most popular choice is

   self.(method_name) = self.metadata.(method_name)

but many of the "I like that" messages were in the context of the idea
as a whole, so can't really be counted as explicit votes for "obj.(foo)"
as such.

Next, and Guido's preferred choice, is

   self.[method_name] = self.metadata.[method_name]

(I haven't been following long enough to know whether "Guido likes it"
overrides everything else (the "D" of BDFL), or is more of a casting
vote in the event of a tie.)

With regard to the potential overlookability of the dot, Guido says:
 > I recommend that you do some experiments with the readability of the
 > .[...] notation, e.g. write a program that randomly generates x.[foo]
 > and x[foo], and see how fast you can spot the difference. I bet that
 > you won't have any trouble.

I agree --- just as it's important to have a font that makes it easy to
distinguish "I" from "l" and "1", "0" from "O", "(" from "{", etc., I
would say it's important to program using a font which makes it easy to
tell whether there's a "." in your code.  I can imagine that a
proportional font where "." might be a single pixel wouldn't help,
though.  (Gently wandering off-topic, but: do people use proportional
fonts for coding?  Doesn't it cause general awkwardness for
indentation, especially relevant for python?)

Also mentioned was

   self.{method_name} = self.metadata.{method_name}

which could not be confused either with function call or indexing but
perhaps would preclude braces from any potential future use.

Exploring other ideas, the "arrow" notation

   self->method_name = self.metadata->method_name

has support, and is clearly different, but I personally would be misled
to think, from the meaning in C, that it ought to be the left-hand
operand which is dereferenced somehow.  Guido has the same opinion, and
is "strongly -1" on this.

The "star" form has the "dereference" meaning from C, and is certainly
visually distinctive:

   self.*method_name = self.metadata.*method_name

and explicit parentheses could be put in as a syntax requirement, or by
individual coder preference, or for more complex attribute calculations:

   self.*(method_name) = self.metadata.*(method_name)
   self.*('foo_%d' % n) = self.metadata.*('foo_%d' % n)

The downside is that it could be considered "visually distinctive" to
the point of being line noise.


Could we cut down the choice to

   self.[method_name] = self.metadata.[method_name]

if the danger of overlooking the dot were deemed small enough, or

   self.*(method_name) = self.metadata.*(method_name)

if the consensus was that something more noticeable was needed?


(Or there's always the late arrival

 > > In C, "x->y" dereferences x, while in Python, "x->y" would 
dereference y.
 >
 > Then the syntax should obviously be "x<-y".
 > [insert in-Soviet-Russia-variables-dereference-you joke here]

from Benji York.)


Ben.

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Summary of "dynamic attribute access" discussion

2007-02-13 Thread Ben North
The support for the including the feature at all is still not unanimous.
Perhaps the way forward is to try to reach consensus on the favourite
(or least-unfavourite) syntax, and I'll revise the PEP and sample
implementation.

I think the "obj.[attr_name]" syntax has the most support.  To stop this
going round in circles for ages, then, I will take this as the winner.
I'll mention the other contenders in the PEP, including the new
"visually distinctive" suggestions

   [EMAIL PROTECTED]
   obj.[[foo]]

and the "wrapper class" idea of Nick Coghlan:

   attrview(obj)[foo]

(I personally think the "attrview" idea results in slightly
cluttered-looking code, and prefer the visual simplicity of
"obj.[foo]".)


One of the new opinions against the feature at all was Steve Holden's:
> This seems to me to take Python further away from the "Computer
> Programming for Everyone" arena and closer to the "Systems Programming
> for Clever Individuals" camp.

I don't agree.  People who find it clearer to write

   x = getattr(obj, attr_name)

can continue to do so.  Now, of course, a person with such a preference
has no control over what other people write, so everybody will have to
understand what the new syntax means, but I think it's quite mnemonic.
It's a combination of the "." attribute look-up and the "[]" dictionary
look-up.

Steve, further down his message, continues:
> It threatens to reduce Python's readability substantially

I find

   obj.[attr_name] = other_obj.[attr_name]

a much clearer expression of the "assignment" intent of this statement
than

   setattr(obj, attr_name, getattr(other_obj, attr_name))

in the same way that I find

   my_dict[new_key] = new_value

clearer than a hypothetical

   setvalue(my_dict, new_key, new_value)

would be.

Opinion is divided on whether it's a readability win, but I think it
*is* a win.  (Well, I would, I suppose).  My experience in Matlab was
that code became much more readable when they introduced "dynamic
fields", especially in code which sets "fields" in one variable from
"fields" in others.  I don't know whether others on this list have
worked in Matlab and have any opinions from their experience.

Turning now to the performance question, Steve also writes:
> > Is 1% "too much" for this feature?
>
> Yes. I believe it would decrease the sum total of Python's efficiency
> for a very marginal return in performance on a very marginal feature.

The performance question is important, certainly.  Initial reaction on
python-ideas was that a 1% cost would not count as substantial, but of
course quicker would be better, and there were a couple of suggestions
as to how the implementation could be improved.  I agree that
"readability is more important than efficiency", and I think a 1%
efficiency loss would be "small" compared to what I think is a
readability win, especially in cases like the example above.

Thanks very much for all the interest in this idea.  I think I've got
enough of a sense of the list's reaction to update the PEP, and will do
so over the next couple of days.  I'll then re-post it so that everyone
can check I haven't misrepresented their opinion, and take it from
there.

Ben.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Summary: rejection of 'dynamic attribute' syntax

2007-02-14 Thread Ben North
Guido van Rossum wrote:
> This seems to be the overwhelming feedback at this point, so I'm
> withdrawing my support for the proposal. I hope that Ben can write up
> a PEP and mark it rejected, to summarize the discussion; it's been a
> useful lesson.

The feedback is clear, yes.  The "new syntax seems like overkill" camp
has become dominant, and I certainly think these are very valid
arguments.  Gentle support remains scattered here and there, but the
consensus has emerged.  I will summarise all this into the PEP and mark
it as rejected.  Still, the discussion was useful, I thought.  Thanks
for the interest.

To respond, for the record, to some of the specific points recently
raised:

[EMAIL PROTECTED]:
> I really, really wish that every feature proposal for Python had to meet
> some burden of proof [...].  I suspect this would kill 90% of "hey
> wouldn't this syntax be neat" proposals on day zero [...]

This is what I understood the initial posting to python-ideas to be
about.  If the feedback from there had been "that's a stupid idea", then
that would have been the end of it.  I think it's a good thing that
there's the python-ideas mechanism for speculative suggestions.

I like the "attrview" or "attrs" wrapper idea, with the example given by
Larry Hastings:
> setattr(self, method_name, getattr(self.metadata, method_name))
> [...] would be:
> attrview(self)[method_name] = attrview(self.metadata)[method_name]

As others point out, it's very clean, captures the intended uses well,
and has the great advantage of having easily-added backwards
compatibility.  I might start using it :-)  If the people who suggested
and refined this were to put it in a PEP, I'd be in favour.

Guido van Rossum wrote:
> I missed discussion of the source of the 1%. Does it slow down pystone
> or other benchmarks by 1%? That would be really odd, since I can't
> imagine that the code path changes in any way for code that doesn't
> use the feature. Is it that the ceval main loop slows down by having
> two more cases?

That seems to be it, yes.  I tested this by leaving the grammar,
compilation, and AST changes in, and conditionally compiling just the
three extra cases in the ceval main loop.  Measurements were noisy
though, as Josiah Carlson has also experienced:

> I've found variations of up to 3% in benchark times that seemed to be
> based on whether I was drinking juice or eating a scone while working.

I'm afraid I can't remember what I was eating or drinking at the time I
did my tests.

(Thanks also for the kind words regarding my summaries etc.  Having
caused all the fuss in the first place I felt obliged to try to make
myself a bit useful :-)

Ben.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Wrapping up 'dynamic attribute' discussion

2007-02-15 Thread Ben North
I've sent an updated version of PEP 363 to the editors, which
includes the following summary of the discussion.  I hope I've
captured the important points, but please let me know if there's
something important I've left out or misrepresented.

- - - - 8< - - - -

Mailing Lists Discussion

Initial posting of this PEP in draft form was to python-ideas on
20070209 [2], and the response was generally positive.  The PEP was
then posted to python-dev on 20070212 [3], and an interesting
discussion ensued.  A brief summary:

Initially, there was reasonable (but not unanimous) support for the
idea, although the precise choice of syntax had a more mixed
reception.  Several people thought the "." would be too easily
overlooked, with the result that the syntax could be confused with a
method/function call.  A few alternative syntaxes were suggested:

obj.(foo)
obj.[foo]
obj.{foo}
obj{foo}
obj.*foo
obj->foo
obj<-foo
[EMAIL PROTECTED]
obj.[[foo]]

with "obj.[foo]" emerging as the preferred one.  In this initial
discussion, the two-argument form was universally disliked, so it
was to be taken out of the PEP.

Discussion then took a step back to whether this particular feature
provided enough benefit to justify new syntax.  As well as requiring
coders to become familiar with the new syntax, there would also be
the problem of backward compatibility --- code using the new syntax
would not run on older pythons.

Instead of new syntax, a new "wrapper class" was proposed, with the
following specification / conceptual implementation suggested by
Martin Loewis:

class attrs:
   def __init__(self, obj):
 self.obj = obj
   def __getitem__(self, name):
 return getattr(self.obj, name)
   def __setitem__(self, name, value):
 return setattr(self.obj, name, value)
   def __delitem__(self, name):
 return delattr(self, name)
   def __contains__(self, name):
 return hasattr(self, name)

This was considered a cleaner and more elegant solution to the
original problem.  The decision was made that the present PEP did
not meet the burden of proof for the introduction of new syntax, a
view which had been put forward by some from the beginning of the
discussion.  The wrapper class idea was left open as a possibility
for a future PEP.

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Summary: rejection of 'dynamic attribute' syntax

2007-02-15 Thread Ben North
[EMAIL PROTECTED] wrote:
 > > > I really, really wish that every feature proposal for Python had 
to meet
 > > > some burden of proof

Ben North wrote:
 > > This is what I understood the initial posting to python-ideas to be
 > > about.

[EMAIL PROTECTED] wrote:
 > I'm suggesting that the standards of the community in _evaluating_ to
 > the proposals should be clearer

Perhaps I didn't need to take your initial comments personally then,
sorry :-)

I do see what you're pointing out: the later part of the "dynamic
attribute" discussion was where the question of whether python really
needs new syntax for this was addressed, and the outcome made the
earlier discussion of "x.[y]" vs "x.(y)" vs "x.{y}" vs "x->y"
etc. irrelevant.

Ben.

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Wrapping up 'dynamic attribute' discussion

2007-02-19 Thread Ben North
I wrote:
> I've sent an updated version of PEP 363 to the editors, which
> includes the following summary of the discussion.  I hope I've
> captured the important points, but please let me know if there's
> something important I've left out or misrepresented.

There were a couple of points made off-list, which I've incorporated.
The final version of the PEP is now with the editors.

Ben.


___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Partial function application 'from the right'

2009-01-29 Thread Ben North
Hi,

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
   been suggested.

'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
real use.

I've created a patch which adds a 'partial_right' function.  The two
examples above:

   >>> import functools, math

   >>> split_comma = functools.partial_right(str.split, ',')
   >>> split_comma('a,b,c')
   ['a', 'b', 'c']

   >>> log_10 = functools.partial_right(math.log, 10.0)
   >>> log_10(100.0)
   2.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 , 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?

Ben.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Partial function application 'from the right'

2009-01-30 Thread Ben North
Hi,

> [ Potential new  "functools.partial_right", e.g.,
>
>split_comma = partial_right(str.split, '.')
> ]

Thanks for the feedback.  Apologies if (as was suggested) this should
have gone to python-ideas; I thought as a fairly small extension to
existing functionality it would be OK here.  I'll try to summarise the
responses.

There was some very luke-warm support.

Terry Reedy suggested it would be worth posting a patch to the tracker,
for the record, even if it turns out to be rejected.

Nick Coghlan made more clear than I did the main reason a
'partial_right' would be useful:

> [...] some functions and methods written in C (such as string methods)
> *don't* [support keyword args], so partial's keyword support doesn't
> help.
>
> A functools.rpartial would go some way towards addressing that.

On the other hand, Collin Winter asked for more evidence that real
benefit (beyond mere 'completeness' of the functools module) would
result.  I don't really have to hand anything more than the three cases
mentioned in my original email (str.split, math.log, itertools.islice),
but since the change is so small, I thought the feature worth raising.

Leif Walsh pointed out that you could achieve the same effect by
defining your own function.  This is true, but functools.partial exists
because it's sometimes useful to create such functions either more
concisely, or anonymously.  A 'partial_right' would allow more such
functions to be so created.

Peter Harris was negative on the idea, pointing out that after

   g = partial_right(f, 7)

you don't know which argument of 'f' the '7' is going to end up as,
because it depends on how many are supplied in the eventual call to 'g'.
This is true, and would require some care in partial_right's use.  Peter
also wondered

> There's probably a reason why Haskell doesn't do this...

I have only written about five lines of Haskell in my life, so take this
with a hefty pinch of salt, but:  Haskell does have a 'flip' function
which reverses the order of a function's arguments, so it looks like you
can very easily build a 'partial_right' in Haskell, especially since
standard functions are in curried form.

There was some discussion (started by Antoine Pitrou) of an idea to
generalise 'partial' further, potentially using the Ellipsis object, to
allow arbitrarily-placed 'holes' in the argument list.  E.g.,

   split_comma = partial(str.split, ..., ',')

In some ways I quite like the even-more-completeness of this idea, but
think that it might be the wrong side of the complexity/benefit
trade-off.  Scott David Daniels pointed out that using Ellipsis would
have the downside of

> [...] preventing any use of partial when an argument could be an the
> Ellipsis instance.

This could be fixed by making the general form be something with the
meaning

   partial_explicit(f, hole_sentinel, *args, **kwargs)

where appearances of the exact object 'hole_sentinel' in 'args' would
indicate a hole, to be filled in at the time of the future call.  A user
wanting to have '...' passed in as a true argument could then do

   g = partial_explicit(f, None, 3, ..., 4, axis = 2)

or

   hole = object()
   g = partial_explicit(f, hole, 3, ..., hole, 4, axis = 2)

if they wanted a true '...' argument and a hole.  (I might have the
syntax for this wrong, having not played with Python 3.0, but I hope the
idea is clear.)

There was some concern expressed (by Daniel Stutzbach, Alexander
Belopolsky) that the meaning of '...' would be confusing --- 'one hole'
or 'arbitrary many holes'?

I think the extra complexity vs extra functionality trade-off is worth
considering for 'partial_right', but my personal opinion is that a
'partial_explicit' has that trade-off the wrong way.

I'll try to find time to create the patch in the tracker in the next few
days, by which time perhaps it'll have become clearer whether the idea
is a good one or not.

Thanks,

Ben.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Partial function application 'from the right'

2009-02-03 Thread Ben North
Hi,

Thanks for the further responses.  Again, I'll try to summarise:

Scott David Daniels pointed out an awkward interaction when chaining
partial applications, such that it could become very unclear what was
going to happen when the final function is called:

> If you have:
> def button(root, position, action=None, text='*', color=None):
> ...
> ...
> blue_button = partial(button, my_root, color=(0,0,1))
>
> Should partial_right(blue_button, 'red') change the color or the text?

Calvin Spealman mentioned a previous patch of his which took the 'hole'
approach, i.e.:

> [...] my partial.skip patch, which allows the following usage:
>
>split_one = partial(str.split, partial.skip, 1)

This would solve my original problems, and, continuing Scott's example,

   def on_clicked(...): ...

   _ = partial.skip
   clickable_blue_button = partial(blue_button, _, on_clicked)

has a clear enough meaning I think:

   clickable_blue_button('top-left corner')
   = blue_button('top-left corner', on_clicked)
   = button(my_root, 'top-left corner', on_clicked, color=(0,0,1))

Calvin's idea/patch sounds good to me, then.  Others also liked it.
Could it be re-considered, instead of the partial_right idea?

Ben.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Partial function application 'from the right'

2009-02-05 Thread Ben North
Hi,

My reading of the most recent set of emails on this topic is that the
balance of opinion is against adding a 'partial_right' or 'partial.skip'
feature.  I still think such a feature would be of real use, although I
can see the arguments against adding it.  Is the conclusion 'no thanks',
then?

(I still have not had time to create an issue in the tracker and attach
the patch, but will do so for completeness.)

Thanks for the discussions,

Ben.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com