Re: [Python-ideas] Collection type argument for argparse where nargs != None

2017-08-04 Thread David Mayo
I mean, it's definitely possible, but I'd argue that's actually not any
more explicit - and, in fact, args.stuff = something(args.stuff) is
arguably less explicit because it's just an arbitrary transform, rather
than being called out as "this is the wrapper element for these args."

The places where I see doing transforms after as substantially worse than
this:

1. any case where a single parser is being used in multiple scripts, or
being extended.  Moving this kind of thing out of the parser means the
logic has to be replicated outside the parser everywhere it's called.
2. validation of multiple arguments against each other - once you're out of
the parser, you have to write separate error handling code instead of just
throwing the right exception.

- Dave



On Fri, Aug 4, 2017 at 12:33 PM, Brett Cannon  wrote:

> I'm not a heavy argparse user so take my opinion with a grain of salt (and
> I do appreciate the time you put into proposing this), but I'm not seeing
> the usefulness to classify this as so pragmatic as to outweigh adding one
> more thing to explain about argparse. Since you're proposing just having a
> callable to use after constructing the list couldn't you just do e.g.
> `args.stuff = frozenset(args.stuff)` instead and just be explicit about it?
>
> On Fri, Aug 4, 2017, 06:01 David Mayo,  wrote:
>
>> A friend of mine (@bcjbcjbcj on twitter) came up with an idea for an
>> argparse improvement that I'd like to propose for inclusion.
>>
>> Currently, argparse with nargs= collects arguments
>> into a list (or a list of lists in the case of action="append"). I would
>> like to propose adding a "collection type" argument to the store and append
>> actions and to add_argument, consisting of a callable that would be applied
>> to the list of type-converted args before adding them to the Namespace.
>> This would allow for alternate constructors (e.g. set), for modifying the
>> list (e.g. with sorted), or to do checking of properties expected across
>> all components of the argument at parse time.
>>
>> I've worked up a set of examples in this gist: https://gist.github.com/
>> pobocks/bff0bea494f2b7ec7eba1e8ae281b888
>>
>> And a rough implementation here: https://github.com/python/
>> cpython/compare/master...pobocks:argparse_colltype
>>
>> I think this would be genuinely useful, and would require very little
>> change to argparse, which should be backwards compatible provided that the
>> default for the collection type is list, or None with list specified if
>> None.
>>
>> Thank you all for your time in considering this,
>>
>> - Dave Mayo
>> @pobocks on twitter, github, various others
>> ___
>> Python-ideas mailing list
>> Python-ideas@python.org
>> https://mail.python.org/mailman/listinfo/python-ideas
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Collection type argument for argparse where nargs != None

2017-08-04 Thread Brett Cannon
I'm not a heavy argparse user so take my opinion with a grain of salt (and
I do appreciate the time you put into proposing this), but I'm not seeing
the usefulness to classify this as so pragmatic as to outweigh adding one
more thing to explain about argparse. Since you're proposing just having a
callable to use after constructing the list couldn't you just do e.g.
`args.stuff = frozenset(args.stuff)` instead and just be explicit about it?

On Fri, Aug 4, 2017, 06:01 David Mayo,  wrote:

> A friend of mine (@bcjbcjbcj on twitter) came up with an idea for an
> argparse improvement that I'd like to propose for inclusion.
>
> Currently, argparse with nargs= collects arguments into
> a list (or a list of lists in the case of action="append"). I would like to
> propose adding a "collection type" argument to the store and append actions
> and to add_argument, consisting of a callable that would be applied to the
> list of type-converted args before adding them to the Namespace. This would
> allow for alternate constructors (e.g. set), for modifying the list (e.g.
> with sorted), or to do checking of properties expected across all
> components of the argument at parse time.
>
> I've worked up a set of examples in this gist:
> https://gist.github.com/pobocks/bff0bea494f2b7ec7eba1e8ae281b888
>
> And a rough implementation here:
> https://github.com/python/cpython/compare/master...pobocks:argparse_colltype
>
> I think this would be genuinely useful, and would require very little
> change to argparse, which should be backwards compatible provided that the
> default for the collection type is list, or None with list specified if
> None.
>
> Thank you all for your time in considering this,
>
> - Dave Mayo
> @pobocks on twitter, github, various others
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Pseudo methods

2017-08-04 Thread Steven D'Aprano
On Fri, Aug 04, 2017 at 10:20:55AM -0300, Joao S. O. Bueno wrote:
> Had not this been discussed here earlier this year?
> 
> (And despite there being perceived dangers to readability in the long term,
> was accepted?)
> 
> Here it is on an archive:
> https://mail.python.org/pipermail/python-ideas/2017-February/044551.html

I don't read this as the same proposal. For starters, I don't believe 
that it was intended to allow monkey-patching of builtins.

Another is that the syntax is much more explicit about where the method 
is going:

def MyClass.method(self, arg):
...

is clearly a method of MyClass.

There was, if I recall, some open discussion of whether arbitrary 
assignment targets should be allowed:

def module.func(x or None)[23 + n].attr.__type__.method(self, arg):
...

or if we should intentionally limit the allowed syntax, like we do for 
decorators. My vote is for intentionally limiting it to a single dotted 
name, like MyClass.method.



> And anyway - along that discussion, despite dislikng the general idea, I
> got convinced that
> creating an outside method that makes "super" or "__class__" work was
> rather complicated.

Complicated is an understatement. It's horrid :-)

Here's the problem: we can successfully inject methods into a class:

# -%<-
class Parent:
def spam(self):
return "spam"

class Child(Parent):
def food(self):
return 'yummy ' + self.spam()

c = Child()
c.food()  # returns 'yummy spam' as expected

# inject a new method
def spam(self):
return 'spam spam spam'

Child.spam = spam
c.food()  # returns 'yummy spam spam spam' as expected
# -%<-


But not if you use the zero-argument form of super():


# -%<-
del Child.spam  # revert to original

def spam(self):
s = super().spam()
return ' '.join([s]*3)

Child.spam = spam
c.food()
# -%<-


This raises:

RuntimeError: super(): __class__ cell not found


This is the simplest thing I've found that will fix it:

# -%<-
del Child.spam  # revert to original again
def outer():
__class__ = Child
def spam(self):
s = super().spam()
return ' '.join([s]*3)
return spam

Child.spam = outer()
c.food()  # returns 'yummy spam spam spam' as expected
# -%<-


It's probably possibly to wrap this up in a decorator that takes Child 
as argument, but I expect it will probably require messing about with 
the undocumented FunctionType constructor to build up a new closure from 
the bits and pieces scavenged from the decorated function. 


> Maybe we could just have a decorator for that, that would properly create
> the __class__ cell?

I expect its possible. A challenge to somebody who wants to get their 
hands dirty.


-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Pseudo methods

2017-08-04 Thread Joao S. O. Bueno
On 4 August 2017 at 10:31, Paul Moore  wrote:

> On 4 August 2017 at 14:20, Joao S. O. Bueno  wrote:
> > Had not this been discussed here earlier this year?
> >
> > (And despite there being perceived dangers to readability in the long
> term,
> > was accepted?)
> >
> > Here it is on an archive:
> > https://mail.python.org/pipermail/python-ideas/2017-February/044551.html
>
> From a very brief review of the end of that thread, it looks like it
> was agreed that a PEP might be worthwhile - it was expected to be
> rejected, though, and the PEP would simply document the discussion and
> the fact that the idea was rejected. This agrees with my recollection
> of the discussion, as well. But as far as I'm aware, no-one ever wrote
> that PEP. (Not surprising, I guess, as it's hard to get enthusiastic
> about proposing an idea you know in advance will be rejected).
>
>
Nonetheless, a third party module with some decorators to allow
doing that "the right way"  might be usefull. If one is willing to write,
or retrieve a candidate for that.
(I donĀ“ t think it is possible to inject the __class__ cell in a clean way,
though)

js
  -><-

> Paul
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Pseudo methods

2017-08-04 Thread Paul Moore
On 4 August 2017 at 14:20, Joao S. O. Bueno  wrote:
> Had not this been discussed here earlier this year?
>
> (And despite there being perceived dangers to readability in the long term,
> was accepted?)
>
> Here it is on an archive:
> https://mail.python.org/pipermail/python-ideas/2017-February/044551.html

>From a very brief review of the end of that thread, it looks like it
was agreed that a PEP might be worthwhile - it was expected to be
rejected, though, and the PEP would simply document the discussion and
the fact that the idea was rejected. This agrees with my recollection
of the discussion, as well. But as far as I'm aware, no-one ever wrote
that PEP. (Not surprising, I guess, as it's hard to get enthusiastic
about proposing an idea you know in advance will be rejected).

Paul
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Pseudo methods

2017-08-04 Thread Joao S. O. Bueno
Had not this been discussed here earlier this year?

(And despite there being perceived dangers to readability in the long term,
was accepted?)

Here it is on an archive:
https://mail.python.org/pipermail/python-ideas/2017-February/044551.html

And anyway - along that discussion, despite dislikng the general idea, I
got convinced that
creating an outside method that makes "super" or "__class__" work was
rather complicated.

Maybe we could just have a decorator for that, that would properly create
the __class__ cell?


js
  -><-


On 4 August 2017 at 08:32, Steven D'Aprano  wrote:

> Hi Paul, and welcome!
>
>
> On Fri, Aug 04, 2017 at 07:39:56AM +, Paul Laos wrote:
> > Hi folks
> > I was thinking about how sometimes, a function sometimes acts on
> classes, and
> > behaves very much like a method.
>
> I'm not really sure what you mean by "acts on classes". I can only think
> of a function which takes a class as a parameter, and modifies the
> class. Like a class decorator. Or possibly a classmethod. But that's not
> what you seem to mean below. So I'm not quite certain I understand your
> proposal.
>
>
> > Adding new methods to classes existing classes
> > is currently somewhat difficult,
>
> If the class is written in Python, it isn't difficult at all, it is
> trivially easy. First define your method:
>
> def method(self, arg):
> pass
>
>
> Then inject it onto the class using ordinary attribute assignment:
>
> TheClass.method = method
>
> And we're done!
>
> If the class is a built-in, or otherwise written in C, then "somewhat
> difficult" is an understatement. I think it can't be done at all.
>
>
> > and having pseudo methods would make that easier.
>
> I'm not sure that "easier" in this case would be better.
>
>
> > Code example: (The syntax can most likely be improved upon)
> > def has_vowels(self: str):
> > for vowel in ["a", "e,", "i", "o", "u"]:
> > if vowel in self: return True
>
>
> How does Python, and for that matter the human reader, know which
> class or classes that method is injected into? My guess is it looks at
> the annotation. But that's a big change: annotations are currently
> guaranteed to have no runtime semantics (apart from being stored in the
> function's __annotation__ attribute). I'm not saying that can't be done,
> but there may be consequences we haven't thought of.
>
> If we say dir(str), will "has_vowels" show up?
>
> How about vars(str)?
>
> How does this interact with metaclasses?
>
>
>
> > This allows one to wring `string.has_vowels()` instead of
> `has_vowels(string)`,
> > which would make it easier to read,
>
> Well that's one opinion.
>
>
> > and would make it easier to add
> > functionality to existing classes, without having to extend them. This
> would be
> > useful for builtins or imported libraries, so one can fill in "missing"
> methods.
>
> http://www.virtuouscode.com/2008/02/23/why-monkeypatching-
> is-destroying-ruby/
>
> I think monkeypatching is great, so long as I'm the only one that does
> it. When other people do it, invariably they introduce bugs into my code
> by monkeypatching other things I didn't expect to be monkeypatched.
>
>
> > * Simple way to extend classes
> > * Improves readability
> > * Easy to understand
>
> I'll agree with the first one of those, if by "simple" you mean
> "somebody else did all the work to make this syntax do
> what I want it to do".
>
> The work behind the scenes is not likely to be simple: for starters,
> allowing monkeypatching of built-ins is likely going to require a rather
> big re-design of the Python interpreter.
>
>
> --
> Steve
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Collection type argument for argparse where nargs != None

2017-08-04 Thread David Mayo
A friend of mine (@bcjbcjbcj on twitter) came up with an idea for an
argparse improvement that I'd like to propose for inclusion.

Currently, argparse with nargs= collects arguments into
a list (or a list of lists in the case of action="append"). I would like to
propose adding a "collection type" argument to the store and append actions
and to add_argument, consisting of a callable that would be applied to the
list of type-converted args before adding them to the Namespace. This would
allow for alternate constructors (e.g. set), for modifying the list (e.g.
with sorted), or to do checking of properties expected across all
components of the argument at parse time.

I've worked up a set of examples in this gist: https://gist.github.com/
pobocks/bff0bea494f2b7ec7eba1e8ae281b888

And a rough implementation here: https://github.com/python/
cpython/compare/master...pobocks:argparse_colltype

I think this would be genuinely useful, and would require very little
change to argparse, which should be backwards compatible provided that the
default for the collection type is list, or None with list specified if
None.

Thank you all for your time in considering this,

- Dave Mayo
@pobocks on twitter, github, various others
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Pseudo methods

2017-08-04 Thread Steven D'Aprano
Hi Paul, and welcome!


On Fri, Aug 04, 2017 at 07:39:56AM +, Paul Laos wrote:
> Hi folks
> I was thinking about how sometimes, a function sometimes acts on classes, and
> behaves very much like a method.

I'm not really sure what you mean by "acts on classes". I can only think 
of a function which takes a class as a parameter, and modifies the 
class. Like a class decorator. Or possibly a classmethod. But that's not 
what you seem to mean below. So I'm not quite certain I understand your 
proposal.


> Adding new methods to classes existing classes
> is currently somewhat difficult,

If the class is written in Python, it isn't difficult at all, it is 
trivially easy. First define your method:

def method(self, arg):
pass


Then inject it onto the class using ordinary attribute assignment:

TheClass.method = method

And we're done!

If the class is a built-in, or otherwise written in C, then "somewhat 
difficult" is an understatement. I think it can't be done at all.


> and having pseudo methods would make that easier.

I'm not sure that "easier" in this case would be better.


> Code example: (The syntax can most likely be improved upon)
> def has_vowels(self: str):
> for vowel in ["a", "e,", "i", "o", "u"]:
> if vowel in self: return True


How does Python, and for that matter the human reader, know which 
class or classes that method is injected into? My guess is it looks at 
the annotation. But that's a big change: annotations are currently 
guaranteed to have no runtime semantics (apart from being stored in the 
function's __annotation__ attribute). I'm not saying that can't be done, 
but there may be consequences we haven't thought of.

If we say dir(str), will "has_vowels" show up?

How about vars(str)?

How does this interact with metaclasses?


 
> This allows one to wring `string.has_vowels()` instead of 
> `has_vowels(string)`,
> which would make it easier to read, 

Well that's one opinion.


> and would make it easier to add
> functionality to existing classes, without having to extend them. This would 
> be
> useful for builtins or imported libraries, so one can fill in "missing" 
> methods.

http://www.virtuouscode.com/2008/02/23/why-monkeypatching-is-destroying-ruby/

I think monkeypatching is great, so long as I'm the only one that does 
it. When other people do it, invariably they introduce bugs into my code 
by monkeypatching other things I didn't expect to be monkeypatched.


> * Simple way to extend classes
> * Improves readability
> * Easy to understand

I'll agree with the first one of those, if by "simple" you mean 
"somebody else did all the work to make this syntax do 
what I want it to do".

The work behind the scenes is not likely to be simple: for starters, 
allowing monkeypatching of built-ins is likely going to require a rather 
big re-design of the Python interpreter.


-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Pseudo methods

2017-08-04 Thread Paul Moore
On 4 August 2017 at 08:39, Paul Laos  wrote:
> Hi folks
> I was thinking about how sometimes, a function sometimes acts on classes,
> and behaves very much like a method. Adding new methods to classes existing
> classes is currently somewhat difficult, and having pseudo methods would make 
> that
> easier.

Adding new methods to classes is deliberately (somewhat) difficult, as
it makes it harder to locate the definition of a method. If you need
to see the code for a method, you'd expect to look in the class
definition. Making it common for people to put method definitions
outside the class definition harms supportability by breaking that
assumption.

> Code example: (The syntax can most likely be improved upon)
> def has_vowels(self: str):
> for vowel in ["a", "e,", "i", "o", "u"]:
> if vowel in self: return True
>
> This allows one to wring `string.has_vowels()` instead of
> `has_vowels(string)`,
> which would make it easier to read,

That's very much a subjective view. Personally, I don't see
"string.has_vowels()" as being any easier to read - except in the
sense that it tells me that I can find the definition of has_vowels in
the class definition of str (and I can find its documentation in the
documentation of the str type). And your proposal removes this
advantage!

> and would make it easier to add
> functionality to existing classes, without having to extend them. This would
> be useful for builtins or imported libraries, so one can fill in "missing"
> methods.

This is a common technique in other languages like Ruby, but is
considered specialised and somewhat of an advanced technique
(monkeypatching) in Python. As you say yourself, the syntax will make
it *easier* to do this - it's already possible, so the change doesn't
add any new capabilities. Adding new syntax to the language typically
needs a much stronger justification (either in terms of enabling
fundamentally new techniques, or providing a significantly more
natural spelling of something that's widely used and acknowledged as a
common programming idiom).

Sorry, but I'm -1 on this change. It doesn't let people do anything
they can't do now, on the contrary it makes it simpler to use a
technique which has readability and supportability problems, which as
a result will mean that people will be inclined to use the approach
without properly considering the consequences.

Paul
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Pseudo methods

2017-08-04 Thread Antoine Rozo
Hi,

With this kind of feature, you never know which methods are included in the
class (depending of which modules have been loaded).
I don't think this is a good idea.

2017-08-04 9:39 GMT+02:00 Paul Laos :

> Hi folks
> I was thinking about how sometimes, a function sometimes acts on classes,
> and
> behaves very much like a method. Adding new methods to classes existing
> classes
> is currently somewhat difficult, and having pseudo methods would make that
> easier.
>
> Code example: (The syntax can most likely be improved upon)
> def has_vowels(self: str):
> for vowel in ["a", "e,", "i", "o", "u"]:
> if vowel in self: return True
>
> This allows one to wring `string.has_vowels()` instead of
> `has_vowels(string)`,
> which would make it easier to read, and would make it easier to add
> functionality to existing classes, without having to extend them. This
> would be
> useful for builtins or imported libraries, so one can fill in "missing"
> methods.
>
> * Simple way to extend classes
> * Improves readability
> * Easy to understand
>
> ~Paul
>
>
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
>


-- 
Antoine Rozo
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/