Re: [Python-ideas] Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Terry Reedy

On 2/10/2017 4:13 AM, Markus Meskanen wrote:

I'm suggesting the addition of support to using a dot notation when
defining a function to be a method of a class, or a callback attribute.


My default starting position for every proposed syntax addition is -1.

1. Additions usually make Python more complicated and harder to learn. 
(This can be argued in particular cases.)


2. Syntax changes, when used, cut code off from past versions.

Consequently, to me, there should be a non-trivial gain to compensate 
for the above.



For example:

def foo(self):
pass
Foo.foo = foo

Becomes:

def Foo.foo(self):
pass


Saving about 10 keystrokes is close to trivial.  If Foo is defined in 
the same file, then putting the def in the class statement would save 
even more.  I am not enthusiastic about enablin the following style of 
class definition.


class Foo: "Object that implement the Foo protocol.

def Foo.__init__(self, x):
self.x = s

def Foo.__getitem__(self, key):
return vars(Foo)[key]

...


And when an object needs a callback as an attribute:

class Menu:
def __init__(self, items=None, select_callback=None):
self.items = items if items is not None else []
self.select_callback = select_callback

my_menu = Menu([item1, item2])

def my_menu.select_callback(self, item_index):
print(self.items[item_index])


A function with a 'self' parameter is normally an instance method (a 
function attribute of the class).  As an instance attribute, it will 
have be called as inst.select_callback(inst, index).  But I suppose you 
could find an example function that I like better as an instance attribute.



As opposed to:

my_menu = Menu([item1, item2])

def select_callback(self, item_index):
print(self.items[item_index])
my_menu.select_callback = select_callback


or
my_menu.select_callback = (lambda self, item_index:
print(self.items[item_index]))

The problem with two-phase initialization is that one temporarily has a 
partially initialized and likely useless object.  I am not enthusiastic 
about encouraging this.



Or defining them in "unnatural" order:


To me, this is the natural and proper order: create all the objects 
needed to initialize an instance before creating it.  When __init__ 
returns, the instance is ready to go.


In tkinter programming, callbacks must be defined
before they are used in a bind or after call, which passes them on to 
tk, where they are not directly accessible as attributes.



def select_callback(self, item_index):
print(self.items[item_index])

my_menu = Menu([item1, item2], select_callback)


Looks good to me ;-)

--
Terry Jan Reedy

___
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] Using Python for end user applications

2017-02-10 Thread Michel Desmoulin
This could change when webassembly is stable. If we manage to make a
Python => webassembly compiler, I doubt it will make Python in the
browser happen. But it certainly can make Python in NodeJS happen, and
so in Electron apps.



Le 09/02/2017 à 19:56, Nick Coghlan a écrit :
> On 7 February 2017 at 15:47, Thomas Kluyver  wrote:
>> I've been thinking for a while about Python apps using Electron (Positron?
>> ;-). It's an interesting idea from the Python side, but I struggle to come
>> up with reasons why developing an Electron+Python app would be easier than
>> developing a regular Electron app. I prefer writing Python to Javascript,
>> but you'd need quite a bit of Javascript anyway, you don't have to care
>> about browser compatibility, and there would inevitably be some extra
>> friction in using two languages.
>>
>> I'm sure there are use cases where it makes sense, like if you use Python's
>> scientific computing ecosystem. But I don't know how broad they are.
> 
> I'd say the rationale for Electron/Python apps is the same as that for
> any JS frontend/Python backend configuration - JS/CSS/HTML5 is a great
> suite of technologies for defining user interfaces, but you don't
> necessarily want to be writing all your application logic in it. (You
> certainly *can*, you just may not want to)
> 
> The trade-offs are different for client-side apps (since shipping two
> different language runtimes is kinda horrible, given neither V8 nor
> CPython is particularly lightweight), but it's not *that* different
> from the traditional Python GUI app development model of depending on
> a C/C++ toolkit like Tcl/Tk, Gtk, Qt, or wxWidgets.
> 
> It's just that the modern GUI toolkit is called V8, most of the actual
> GUI bits are written in JavaScript rather than C/C++, and the language
> independent in-process bindings got fairly dramatically worse along
> the way :)
> 
> Cheers,
> Nick.
> 
___
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] Fwd: Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Steve Dower

On 10Feb2017 1400, Stephan Hoyer wrote:

An important note is that ideally, we would still have way of indicating
that Spam.func should exists in on the Spam class itself, even if it
doesn't define the implementation. I suppose an abstractmethod
overwritten by the later definition might do the trick, e.g.,

class Spam(metaclass=ABCMeta):
@abstractmethod
def func(self):
pass

def Spam.func(self):
return __class__


An abstractfunction should not become a concrete function on the 
abstract class - the right way to do this is to use a subclass.


class SpamBase(metaclass=ABCMeta):
@abstractmethod
def func(self):
pass

class Spam(SpamBase):
def func(self):
return __class__


If you want to define parts of the class in separate modules, use mixins:

from myarray.transforms import MyArrayTransformMixin
from myarray.arithmetic import MyArrayArithmeticMixin
from myarray.constructors import MyArrayConstructorsMixin

class MyArray(MyArrayConstructorsMixin, MyArrayArithmeticMixin, 
MyArrayTransformMixin):

pass


The big different between these approaches and the proposal is that the 
proposal does not require both parties to agree on the approach. This is 
actually a terrible idea, as subclassing or mixing in a class that 
wasn't meant for it leads to all sorts of trouble unless the end user is 
very careful. Providing first-class syntax or methods for this 
discourages carefulness. (Another way of saying it is that directly 
overriding class members should feel a bit dirty because it *is* a bit 
dirty.)


As Paul said in an earlier email, the best use of non-direct assignment 
in function definitions is putting it into a dispatch dictionary, and in 
this case making a decorator is likely cleaner than adding new syntax.


But by all means, let's have a PEP. It will simplify the discussion when 
it comes up in six months again (or whenever the last time this came up 
was - less than a year, I'm sure).


Cheers,
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] Fwd: Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Stephan Hoyer
On Fri, Feb 10, 2017 at 9:20 AM, Nick Coghlan  wrote:

> What I would personally hope to see from the proposal is that given:
>
> class Spam:
> pass
>
> def Spam.func(self):
> return __class__
>
> the effective runtime behaviour would be semantically identical to:
>
> class Spam:
> def func(self):
> return __class__
>

Yes, this is exactly what I would hope/expect to see.

One use case for this functionality is defining classes with an extensive
method-based API with a sane dependency graph. For example, consider
writing a class like numpy.ndarray
 or
pandas.DataFrame

with dozens of methods. You could argue that using so many methods is an
anti-pattern, but nonetheless it's pretty common and hard to avoid in some
cases (e.g., for making number-like classes that support arithmetic and
comparisons).

For obvious reasons, the functionality for these classes does not all live
in a single module. But the modules that define helper functions for most
methods also depend on the base class, so many of them need to get imported
inside method definitions

to
avoid circular imports. The result is pretty ugly, and files defining the
class still get gigantic.

An important note is that ideally, we would still have way of indicating
that Spam.func should exists in on the Spam class itself, even if it
doesn't define the implementation. I suppose an abstractmethod overwritten
by the later definition might do the trick, e.g.,

class Spam(metaclass=ABCMeta):
@abstractmethod
def func(self):
pass

def Spam.func(self):
return __class__

And finally, it's quite possible that there's a clean metaclass based
solution for extending Spam in another file, I just don't know it yet.
___
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] Fwd: Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Stephan Houben
Hi all,

For what it's worth, I believe that the "class extension" scenario from
Nick can be supported
using plain ol' metaclasses.
Not sure if this covers all desired capabilities, but at least the super()
mechanism works correctly.

Syntax is like this:
class Foo(metaclass=class_extend(Foo)):
   ...

See: https://gist.github.com/stephanh42/97b47506e5e416f97f5790c070be7878

Stephan


2017-02-10 19:48 GMT+01:00 Nick Timkovich :

> If everything was contained right in the same file, this is sanctioning
> another way to do it (when there should only be one obvious way). If you
> have multiple modules/packages, horrors can evolve where a class method
> could be patched in an unknown location by any loaded module (or you could
> even introduce order-of-import sensitivities).
>
> For testing, this can be a necessary evil which is OK so long as the patch
> is limited/apparent, and some other very narrow cases (setuptools something
> something?). That said, I don't want their use condoned or eased for fear
> of proliferation of these "antiprogrammer land mines" that I might trip
> over in the future.
>
> On Fri, Feb 10, 2017 at 12:15 PM, Joshua Morton  > wrote:
>
>> One thing that I don't think has been mentioned, but that brings me from
>> a +0 to a more negative outlook, is the interaction between this proposal
>> and some of python's existing class-related features, metaclasses and
>> descriptors. That is currently we know that function definition, and even
>> method definition, will not have side effects. This potentially changes
>> that since
>>
>> def Foo.foo(self):
>> ...
>>
>> could be a descriptor. Even if it doesn't, its possible that `Foo.foo` is
>> actually resolved from `Foo._foo`, and so this potentially further confuses
>> the naming considerations.
>>
>> Then we have metaclasses. Prior to this change, it would be fully the
>> monkeypatcher's responsibility to do any metaclass level changes if they
>> were necessary when monkeypatching. However, since we are potentially
>> adding a first class support for certain monkeypatches, It raises a
>> question about some first class way to handle monkeypatched methods. Do we
>> need to provide some kind of method to a metaclass writer that allows them
>> to handle methods that are patched on later? Or does the language still
>> ignore it?
>>
>> --Josh
>>
>> On Fri, Feb 10, 2017 at 12:20 PM Nick Coghlan  wrote:
>>
>>> On 10 February 2017 at 16:25, Steven D'Aprano 
>>> wrote:
>>> > On Sat, Feb 11, 2017 at 01:25:40AM +1100, Chris Angelico wrote:
>>> >
>>> >> For what it's worth, my answers would be:
>>> >>
>>> >> __name__ would be the textual representation of exactly what you typed
>>> >> between "def" and the open parenthesis. __qualname__ would be built
>>> >> the exact same way it currently is, based on that __name__.
>>> >
>>> > If I'm reading this right, you want this behaviour:
>>> >
>>> > class Spam:
>>> > pass
>>> >
>>> > def Spam.func(self): pass
>>> >
>>> > assert 'Spam.func' not in Spam.__dict__
>>> > assert 'func' in Spam.__dict__
>>> >
>>> > assert Spam.func.__name__ == 'Spam.func'
>>> > assert Spam.func.__qualname__ == 'Spam.Spam.func'
>>> >
>>> > If that's the case, I can only ask... what advantage do you see from
>>> > this? Because I can see plenty of opportunity for confusion, and no
>>> > advantage.
>>>
>>> What I would personally hope to see from the proposal is that given:
>>>
>>> class Spam:
>>> pass
>>>
>>> def Spam.func(self):
>>> return __class__
>>>
>>> the effective runtime behaviour would be semantically identical to:
>>>
>>> class Spam:
>>> def func(self):
>>> return __class__
>>>
>>> such that:
>>>
>>>   * __name__ is set based on the method name after the dot
>>>   * __qualname__ is set based on the __name__ of the given class
>>>   * __set_owner__ is called after any function decorators are applied
>>>   * zero-argument super() and other __class__ references work properly
>>> from the injected method
>>>
>>> Potentially, RuntimeError could be raised if the reference before the
>>> dot is not to a type instance.
>>>
>>> If it *doesn't* do that, then I'd be -1 on the proposal, since it
>>> doesn't add enough expressiveness to the language to be worth the
>>> extra syntax. By contrast, if it *does* do it, then it makes class
>>> definitions more decomposable, by providing post-definition access to
>>> parts of the machinery that are currently only accessible during the
>>> process of defining the class.
>>>
>>> The use case would be to make it easier to inject descriptors when
>>> writing class decorators such that they behave essentially the same as
>>> they do when defined in the class body:
>>>
>>> def my_class_decorator(cls):
>>> def cls.injected_method(self):
>>> # Just write injected methods the same way you would in a
>>> class body
>>> 

Re: [Python-ideas] Fwd: Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Ethan Furman

On 02/10/2017 10:48 AM, Nick Timkovich wrote:


If everything was contained right in the same file, this is sanctioning
 another way to do it (when there should only be one obvious way).


No worries, this way is not obvious.


 If you have multiple modules/packages, horrors can evolve where a class
 method could be patched in an unknown location by any loaded module (or
 you could even introduce order-of-import sensitivities).


Folks can still do that nightmare right now.

I'm -0.5 on it -- I don't think the payoff is worth the pain.

But I'm +1 on writing a PEP -- collect all these pros and cons in one place to 
save on future discussion.  (And (good) PEP writing is a way to earn valuable 
Python Points!)

--
~Ethan~
___
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] Fwd: Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Markus Meskanen
Please keep in mind that this idea was not created to improve monkey
patching, it just happens to be one of the side effects due to classes
being objects. The main use case is the ability to set an instance's
callback function (see the Menu example), and to allow the class being
referenced in the function's header; for example in a decorator and during
typing.

No additional "fancy" features are intended, it would simply replace this:

foo = Bar()
def f():
...
foo.f = f

With syntax sugar, similar to how decorators replaced this:

def f():
...
f = decorate(f)

On Feb 10, 2017 20:50, "Nick Timkovich"  wrote:

> If everything was contained right in the same file, this is sanctioning
> another way to do it (when there should only be one obvious way). If you
> have multiple modules/packages, horrors can evolve where a class method
> could be patched in an unknown location by any loaded module (or you could
> even introduce order-of-import sensitivities).
>
> For testing, this can be a necessary evil which is OK so long as the patch
> is limited/apparent, and some other very narrow cases (setuptools something
> something?). That said, I don't want their use condoned or eased for fear
> of proliferation of these "antiprogrammer land mines" that I might trip
> over in the future.
>
> On Fri, Feb 10, 2017 at 12:15 PM, Joshua Morton  > wrote:
>
>> One thing that I don't think has been mentioned, but that brings me from
>> a +0 to a more negative outlook, is the interaction between this proposal
>> and some of python's existing class-related features, metaclasses and
>> descriptors. That is currently we know that function definition, and even
>> method definition, will not have side effects. This potentially changes
>> that since
>>
>> def Foo.foo(self):
>> ...
>>
>> could be a descriptor. Even if it doesn't, its possible that `Foo.foo` is
>> actually resolved from `Foo._foo`, and so this potentially further confuses
>> the naming considerations.
>>
>> Then we have metaclasses. Prior to this change, it would be fully the
>> monkeypatcher's responsibility to do any metaclass level changes if they
>> were necessary when monkeypatching. However, since we are potentially
>> adding a first class support for certain monkeypatches, It raises a
>> question about some first class way to handle monkeypatched methods. Do we
>> need to provide some kind of method to a metaclass writer that allows them
>> to handle methods that are patched on later? Or does the language still
>> ignore it?
>>
>> --Josh
>>
>> On Fri, Feb 10, 2017 at 12:20 PM Nick Coghlan  wrote:
>>
>>> On 10 February 2017 at 16:25, Steven D'Aprano 
>>> wrote:
>>> > On Sat, Feb 11, 2017 at 01:25:40AM +1100, Chris Angelico wrote:
>>> >
>>> >> For what it's worth, my answers would be:
>>> >>
>>> >> __name__ would be the textual representation of exactly what you typed
>>> >> between "def" and the open parenthesis. __qualname__ would be built
>>> >> the exact same way it currently is, based on that __name__.
>>> >
>>> > If I'm reading this right, you want this behaviour:
>>> >
>>> > class Spam:
>>> > pass
>>> >
>>> > def Spam.func(self): pass
>>> >
>>> > assert 'Spam.func' not in Spam.__dict__
>>> > assert 'func' in Spam.__dict__
>>> >
>>> > assert Spam.func.__name__ == 'Spam.func'
>>> > assert Spam.func.__qualname__ == 'Spam.Spam.func'
>>> >
>>> > If that's the case, I can only ask... what advantage do you see from
>>> > this? Because I can see plenty of opportunity for confusion, and no
>>> > advantage.
>>>
>>> What I would personally hope to see from the proposal is that given:
>>>
>>> class Spam:
>>> pass
>>>
>>> def Spam.func(self):
>>> return __class__
>>>
>>> the effective runtime behaviour would be semantically identical to:
>>>
>>> class Spam:
>>> def func(self):
>>> return __class__
>>>
>>> such that:
>>>
>>>   * __name__ is set based on the method name after the dot
>>>   * __qualname__ is set based on the __name__ of the given class
>>>   * __set_owner__ is called after any function decorators are applied
>>>   * zero-argument super() and other __class__ references work properly
>>> from the injected method
>>>
>>> Potentially, RuntimeError could be raised if the reference before the
>>> dot is not to a type instance.
>>>
>>> If it *doesn't* do that, then I'd be -1 on the proposal, since it
>>> doesn't add enough expressiveness to the language to be worth the
>>> extra syntax. By contrast, if it *does* do it, then it makes class
>>> definitions more decomposable, by providing post-definition access to
>>> parts of the machinery that are currently only accessible during the
>>> process of defining the class.
>>>
>>> The use case would be to make it easier to inject descriptors when
>>> writing class decorators such that they behave essentially the same as
>>> they 

Re: [Python-ideas] Fwd: Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Joshua Morton
One thing that I don't think has been mentioned, but that brings me from
a +0 to a more negative outlook, is the interaction between this proposal
and some of python's existing class-related features, metaclasses and
descriptors. That is currently we know that function definition, and even
method definition, will not have side effects. This potentially changes
that since

def Foo.foo(self):
...

could be a descriptor. Even if it doesn't, its possible that `Foo.foo` is
actually resolved from `Foo._foo`, and so this potentially further confuses
the naming considerations.

Then we have metaclasses. Prior to this change, it would be fully the
monkeypatcher's responsibility to do any metaclass level changes if they
were necessary when monkeypatching. However, since we are potentially
adding a first class support for certain monkeypatches, It raises a
question about some first class way to handle monkeypatched methods. Do we
need to provide some kind of method to a metaclass writer that allows them
to handle methods that are patched on later? Or does the language still
ignore it?

--Josh

On Fri, Feb 10, 2017 at 12:20 PM Nick Coghlan  wrote:

> On 10 February 2017 at 16:25, Steven D'Aprano  wrote:
> > On Sat, Feb 11, 2017 at 01:25:40AM +1100, Chris Angelico wrote:
> >
> >> For what it's worth, my answers would be:
> >>
> >> __name__ would be the textual representation of exactly what you typed
> >> between "def" and the open parenthesis. __qualname__ would be built
> >> the exact same way it currently is, based on that __name__.
> >
> > If I'm reading this right, you want this behaviour:
> >
> > class Spam:
> > pass
> >
> > def Spam.func(self): pass
> >
> > assert 'Spam.func' not in Spam.__dict__
> > assert 'func' in Spam.__dict__
> >
> > assert Spam.func.__name__ == 'Spam.func'
> > assert Spam.func.__qualname__ == 'Spam.Spam.func'
> >
> > If that's the case, I can only ask... what advantage do you see from
> > this? Because I can see plenty of opportunity for confusion, and no
> > advantage.
>
> What I would personally hope to see from the proposal is that given:
>
> class Spam:
> pass
>
> def Spam.func(self):
> return __class__
>
> the effective runtime behaviour would be semantically identical to:
>
> class Spam:
> def func(self):
> return __class__
>
> such that:
>
>   * __name__ is set based on the method name after the dot
>   * __qualname__ is set based on the __name__ of the given class
>   * __set_owner__ is called after any function decorators are applied
>   * zero-argument super() and other __class__ references work properly
> from the injected method
>
> Potentially, RuntimeError could be raised if the reference before the
> dot is not to a type instance.
>
> If it *doesn't* do that, then I'd be -1 on the proposal, since it
> doesn't add enough expressiveness to the language to be worth the
> extra syntax. By contrast, if it *does* do it, then it makes class
> definitions more decomposable, by providing post-definition access to
> parts of the machinery that are currently only accessible during the
> process of defining the class.
>
> The use case would be to make it easier to inject descriptors when
> writing class decorators such that they behave essentially the same as
> they do when defined in the class body:
>
> def my_class_decorator(cls):
> def cls.injected_method(self):
> # Just write injected methods the same way you would in a
> class body
> return __class__
> return cls
>
> (Actually doing this may require elevating super and __class__ to true
> keyword expressions, rather than the pseudo-keywords they are now)
>
> Cheers,
> Nick.
>
> --
> Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
> ___
> 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] Fwd: Define a method or function attributeoutsideof a class with the dot operator

2017-02-10 Thread Steve Dower
When you apply the "what if everyone did this" rule, it looks like a bad idea 
(or alternatively, what if two people who weren't expecting anyone else to do 
this did it).

Monkeypatching is fairly blatantly taking advantage of the object model in a 
way that is not "supported" and cannot behave well in the context of everyone 
doing it, whereas inheritance or mixins are safe. Making a dedicated syntax or 
decorator for patching is saying that we (the language) think you should do it. 
(The extension_method decorator sends exactly the wrong message about what it's 
doing.)

Enabling a __class__ variable within the scope of the definition would also 
solve the motivating example, and is less likely to lead to code where you need 
to review multiple modules and determine whole-program import order to figure 
out why your calls do not work.

Top-posted from my Windows Phone

-Original Message-
From: "Markus Meskanen" 
Sent: ‎2/‎10/‎2017 10:18
To: "Paul Moore" 
Cc: "Python-Ideas" ; "Steve Dower" 

Subject: Re: [Python-ideas] Fwd: Define a method or function attributeoutsideof 
a class with the dot operator

Well yes, but I think you're a bit too fast on labeling it a mistake to use 
monkey patching...




On Feb 10, 2017 18:15, "Paul Moore"  wrote:

On 10 February 2017 at 16:09, Markus Meskanen  wrote:
> But if people are gonna do it anyways with the tools provided (monkey
> patching), why not provide them with better tools?


Because encouraging and making it easier for people to make mistakes
is the wrong thing to do, surely?

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] Define a method or function attribute outside of a class with the dot operator.

2017-02-10 Thread Gerald Britton
This is looking familiar. .Net extension methods anyone?
___
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] Fwd: Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Nick Coghlan
On 10 February 2017 at 16:25, Steven D'Aprano  wrote:
> On Sat, Feb 11, 2017 at 01:25:40AM +1100, Chris Angelico wrote:
>
>> For what it's worth, my answers would be:
>>
>> __name__ would be the textual representation of exactly what you typed
>> between "def" and the open parenthesis. __qualname__ would be built
>> the exact same way it currently is, based on that __name__.
>
> If I'm reading this right, you want this behaviour:
>
> class Spam:
> pass
>
> def Spam.func(self): pass
>
> assert 'Spam.func' not in Spam.__dict__
> assert 'func' in Spam.__dict__
>
> assert Spam.func.__name__ == 'Spam.func'
> assert Spam.func.__qualname__ == 'Spam.Spam.func'
>
> If that's the case, I can only ask... what advantage do you see from
> this? Because I can see plenty of opportunity for confusion, and no
> advantage.

What I would personally hope to see from the proposal is that given:

class Spam:
pass

def Spam.func(self):
return __class__

the effective runtime behaviour would be semantically identical to:

class Spam:
def func(self):
return __class__

such that:

  * __name__ is set based on the method name after the dot
  * __qualname__ is set based on the __name__ of the given class
  * __set_owner__ is called after any function decorators are applied
  * zero-argument super() and other __class__ references work properly
from the injected method

Potentially, RuntimeError could be raised if the reference before the
dot is not to a type instance.

If it *doesn't* do that, then I'd be -1 on the proposal, since it
doesn't add enough expressiveness to the language to be worth the
extra syntax. By contrast, if it *does* do it, then it makes class
definitions more decomposable, by providing post-definition access to
parts of the machinery that are currently only accessible during the
process of defining the class.

The use case would be to make it easier to inject descriptors when
writing class decorators such that they behave essentially the same as
they do when defined in the class body:

def my_class_decorator(cls):
def cls.injected_method(self):
# Just write injected methods the same way you would in a class body
return __class__
return cls

(Actually doing this may require elevating super and __class__ to true
keyword expressions, rather than the pseudo-keywords they are now)

Cheers,
Nick.

-- 
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
___
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] Fwd: Define a method or function attributeoutside of a class with the dot operator

2017-02-10 Thread Sven R. Kunze

Another point of view:

Some call it monkeypatching. Others call it configuration.


There's room for both views and I don't see anything wrong with 
configuration using this kind of feature.



Sven

On 10.02.2017 17:17, Markus Meskanen wrote:
Well yes, but I think you're a bit too fast on labeling it a mistake 
to use monkey patching...



On Feb 10, 2017 18:15, "Paul Moore" > wrote:


On 10 February 2017 at 16:09, Markus Meskanen
> wrote:
> But if people are gonna do it anyways with the tools provided
(monkey
> patching), why not provide them with better tools?

Because encouraging and making it easier for people to make mistakes
is the wrong thing to do, surely?

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/


___
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] Fwd: Define a method or function attributeoutside of a class with the dot operator

2017-02-10 Thread Paul Moore
On 10 February 2017 at 16:09, Markus Meskanen  wrote:
> But if people are gonna do it anyways with the tools provided (monkey
> patching), why not provide them with better tools?

Because encouraging and making it easier for people to make mistakes
is the wrong thing to do, surely?

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] Fwd: Define a method or function attributeoutside of a class with the dot operator

2017-02-10 Thread Markus Meskanen
Well yes, but I think you're a bit too fast on labeling it a mistake to use
monkey patching...


On Feb 10, 2017 18:15, "Paul Moore"  wrote:

On 10 February 2017 at 16:09, Markus Meskanen 
wrote:
> But if people are gonna do it anyways with the tools provided (monkey
> patching), why not provide them with better tools?

Because encouraging and making it easier for people to make mistakes
is the wrong thing to do, surely?

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] Fwd: Define a method or function attributeoutside of a class with the dot operator

2017-02-10 Thread Markus Meskanen
But if people are gonna do it anyways with the tools provided (monkey
patching), why not provide them with better tools? And this wouldn't only
be for classes, but for setting instance attributes too (see the Menu
example in original mail).

- Markus

On Fri, Feb 10, 2017 at 5:38 PM, Steve Dower  wrote:

> Since votes seem to be being counted and used for debate purposes, I am -1
> to anything that encourages or condones people adding functionality to
> classes outside of the class definition. (Monkeypatching in my mind neither
> condones or encourages, and most descriptions come with plenty of caveats
> about how it should be avoided.)
>
> My favourite description of object-oriented programming is that it's like
> "reading a road map through a drinking(/soda/pop) straw". We do not need to
> tell people that it's okay to make this problem worse by providing
> first-class tools to do it.
>
> Top-posted from my Windows Phone
> --
> From: Chris Angelico 
> Sent: ‎2/‎10/‎2017 8:27
> To: Python-Ideas 
> Subject: Re: [Python-ideas] Fwd: Define a method or function
> attributeoutside of a class with the dot operator
>
> On Sat, Feb 11, 2017 at 1:16 AM, Nick Coghlan  wrote:
> > But what do __name__ and __qualname__ get set to?
> >
> > What happens if you do this at class scope, rather than at module
> > level or inside another function?
> >
> > What happens to the zero-argument super() support at class scope?
> >
> > What happens if you attempt to use zero-argument super() when *not* at
> > class scope?
> >
> > These are *answerable* questions...
>
> ... and are exactly why I asked the OP to write up a PEP. This isn't
> my proposal, so it's not up to me to make the decisions.
>
> For what it's worth, my answers would be:
>
> __name__ would be the textual representation of exactly what you typed
> between "def" and the open parenthesis. __qualname__ would be built
> the exact same way it currently is, based on that __name__.
>
> Zero-argument super() would behave exactly the way it would if you
> used a simple name. This just changes the assignment, not the creation
> of the function. So if you're inside a class, you could populate a
> lookup dictionary with method-like functions. Abuse this, and you're
> only shooting your own foot.
>
> Zero-argument super() outside of a class, just as currently, would be
> an error. (Whatever kind of error it currently is.)
>
> Maybe there are better answers to these questions, I don't know.
> That's what the PEP's for.
>
> ChrisA
> ___
> 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 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] Fwd: Define a method or function attributeoutside of a class with the dot operator

2017-02-10 Thread Steve Dower
Since votes seem to be being counted and used for debate purposes, I am -1 to 
anything that encourages or condones people adding functionality to classes 
outside of the class definition. (Monkeypatching in my mind neither condones or 
encourages, and most descriptions come with plenty of caveats about how it 
should be avoided.)

My favourite description of object-oriented programming is that it's like 
"reading a road map through a drinking(/soda/pop) straw". We do not need to 
tell people that it's okay to make this problem worse by providing first-class 
tools to do it.

Top-posted from my Windows Phone

-Original Message-
From: "Chris Angelico" 
Sent: ‎2/‎10/‎2017 8:27
To: "Python-Ideas" 
Subject: Re: [Python-ideas] Fwd: Define a method or function attributeoutside 
of a class with the dot operator

On Sat, Feb 11, 2017 at 1:16 AM, Nick Coghlan  wrote:
> But what do __name__ and __qualname__ get set to?
>
> What happens if you do this at class scope, rather than at module
> level or inside another function?
>
> What happens to the zero-argument super() support at class scope?
>
> What happens if you attempt to use zero-argument super() when *not* at
> class scope?
>
> These are *answerable* questions...

... and are exactly why I asked the OP to write up a PEP. This isn't
my proposal, so it's not up to me to make the decisions.

For what it's worth, my answers would be:

__name__ would be the textual representation of exactly what you typed
between "def" and the open parenthesis. __qualname__ would be built
the exact same way it currently is, based on that __name__.

Zero-argument super() would behave exactly the way it would if you
used a simple name. This just changes the assignment, not the creation
of the function. So if you're inside a class, you could populate a
lookup dictionary with method-like functions. Abuse this, and you're
only shooting your own foot.

Zero-argument super() outside of a class, just as currently, would be
an error. (Whatever kind of error it currently is.)

Maybe there are better answers to these questions, I don't know.
That's what the PEP's for.

ChrisA
___
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] Fwd: Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Steven D'Aprano
On Sat, Feb 11, 2017 at 01:25:40AM +1100, Chris Angelico wrote:

> For what it's worth, my answers would be:
> 
> __name__ would be the textual representation of exactly what you typed
> between "def" and the open parenthesis. __qualname__ would be built
> the exact same way it currently is, based on that __name__.

If I'm reading this right, you want this behaviour:

class Spam:
pass

def Spam.func(self): pass

assert 'Spam.func' not in Spam.__dict__
assert 'func' in Spam.__dict__

assert Spam.func.__name__ == 'Spam.func'
assert Spam.func.__qualname__ == 'Spam.Spam.func'

If that's the case, I can only ask... what advantage do you see from 
this? Because I can see plenty of opportunity for confusion, and no 
advantage.


For what its worth, Lua already has this feature:

http://www.lua.org/pil/6.2.html

Lib = {}
function Lib.foo (x,y)
  return x + y
end

If we define that function foo inside the Lib table, and then cause an 
error, the Lua interpreter tells us the function name:

> Lib.foo('a', 1)
stdin:2: attempt to perform arithmetic on local 'x' (a string value)
stack traceback:
stdin:2: in function 'foo'
stdin:1: in main chunk
[C]: in ?


-- 
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] Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Kyle Lahnakoski

On 2017-02-10 05:44, Markus Meskanen wrote:
>
>
> On Fri, Feb 10, 2017 at 12:29 PM, Stephan Houben  > wrote:
>
> What about using a simple decorator instead?
>
> def monkey_patch(cls):
> return lambda func: setattr(cls, func.__name__, func)
>

I suggest naming the decorator with something less generic than
"monkey_patch", like "extension_method".





___
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] Fwd: Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Guyzmo via Python-ideas
Hi list,

I'm quite neutral to this proposition, as it's not a use case I see
often myself needing.

On Fri, Feb 10, 2017 at 02:55:31PM +0100, Stephan Houben wrote:
[…]
> But if I don't understand the dot in `class foo.bar:', then what?
> It's probably somewhere buried in the language spec for `class' but
> realistically
> I am now going to blight Stackoverflow with my questions.
[…]

but this is definitely not a reason to dismiss a proposal. A language is
aimed at evolves and introduce new syntax features, and yes,
stackoverflow will get questions about it, blog articles written and
RTFW updated, so you'll get the info you'll need fastly.

Cheers,

-- 
Guyzmo
___
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] Fwd: Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Chris Angelico
On Sat, Feb 11, 2017 at 1:16 AM, Nick Coghlan  wrote:
> But what do __name__ and __qualname__ get set to?
>
> What happens if you do this at class scope, rather than at module
> level or inside another function?
>
> What happens to the zero-argument super() support at class scope?
>
> What happens if you attempt to use zero-argument super() when *not* at
> class scope?
>
> These are *answerable* questions...

... and are exactly why I asked the OP to write up a PEP. This isn't
my proposal, so it's not up to me to make the decisions.

For what it's worth, my answers would be:

__name__ would be the textual representation of exactly what you typed
between "def" and the open parenthesis. __qualname__ would be built
the exact same way it currently is, based on that __name__.

Zero-argument super() would behave exactly the way it would if you
used a simple name. This just changes the assignment, not the creation
of the function. So if you're inside a class, you could populate a
lookup dictionary with method-like functions. Abuse this, and you're
only shooting your own foot.

Zero-argument super() outside of a class, just as currently, would be
an error. (Whatever kind of error it currently is.)

Maybe there are better answers to these questions, I don't know.
That's what the PEP's for.

ChrisA
___
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] Fwd: Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Nick Coghlan
On 10 February 2017 at 12:16, Chris Angelico  wrote:
> On Fri, Feb 10, 2017 at 10:13 PM, Paul Moore  wrote:
>> Furthermore, once we open up this possibility, I would expect requests
>> for things like
>>
>> func_table = {}
>> func_table["foo"] = lambda a, b: a+b
>> def func_table["bar"] (a,b):
>> return a-b
>>
>> pretty quickly. How would you respond to those? (Setting up function
>> tables is a much more common and reasonable need than monkeypatching
>> classes).
>
> Which is why these proposals always seem to gravitate to "anything you
> can assign to", which is at least easy enough to explain. All your
> examples would be completely acceptable.under that system.

But what do __name__ and __qualname__ get set to?

What happens if you do this at class scope, rather than at module
level or inside another function?

What happens to the zero-argument super() support at class scope?

What happens if you attempt to use zero-argument super() when *not* at
class scope?

These are *answerable* questions (and injecting the right __class__
cell reference for zero-argument super() support is a compelling
technical argument in favour of this feature over ordinary attribute
binding operations), but there's a lot more to the proposal than just
relaxing a syntactic restriction in the language grammar.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
___
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] Fwd: Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Paul Moore
On 10 February 2017 at 14:00, Markus Meskanen  wrote:
>> > I've started working on a PEP for this since most people seem to be for
>> > it.
>>
>> I don't know how you get "most people" -- there's only been a handful of
>> responses in the few hours since the original post. And apart from one
>> explicit -1, I read most of them as neutral, not in favour.
>
>
> Yeah I worded that poorly, more like most people didn't turn me down which I
> was a bit afraid of.

To be clear, I'm -1 on the proposal.

As I said, I can see a small attraction in the *idea*, but for me, the
practical considerations seem too great.
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] Fwd: Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Paul Moore
On 10 February 2017 at 13:55, Stephan Houben  wrote:
> My point would be that the new syntax *also* requires one to figure out what
> the new syntax does.

This is an extremely good point. It is mentioned when new syntax is
proposed (the term often used is "discoverability") but the idea never
seems to stick, as people keep forgetting to consider it when
proposing new ideas.

With this proposal the only thing you can search for is "def", and
you're going to mostly find sites that explain the current syntax. So
anyone looking for understanding of the new construct will likely end
up even more confused after searching than they were before.

Markus - if you do write up a PEP, please make sure this point is
noted and addressed.

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] Fwd: Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Markus Meskanen
>
> > I've started working on a PEP for this since most people seem to be for
> it.
>
> I don't know how you get "most people" -- there's only been a handful of
> responses in the few hours since the original post. And apart from one
> explicit -1, I read most of them as neutral, not in favour.
>

Yeah I worded that poorly, more like most people didn't turn me down which
I was a bit afraid of.


> I'm one of the neutral parties, perhaps just a tiny bit positive +0, but
> only for the original proposal.
>
> I am -1000 on allowing arbitrary assignment targets. I believe that the
> cost in readability far outweighs the usefulness of allowing things
> like:
>
> def mydict[key].attr[-1](arg): ...


Do not worry, I will not propose the advanced method, only dot notation!
That being said, I don't think it's up to the language if someone wants to
write ugly code like that, you can already do way uglier stuff with the
existing features. I don't really see people doing this either:

mydict[key].attr[-1].append(my_func)

So why would they if we suddenly introduce this to functions? Anyways
that's not a worry of this to-be PEP.

- Markus
___
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] Fwd: Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Stephan Houben
Hi all,

I would like to add one more generic remark about syntax extensions,
regarding something
Markus said and which has bothered me before, also related to other syntax
proposals.

"Decorator approach is no different from doing `Foo.bar = bar` under the
function definition I think, except it requires one to figure out what the
decorator does first."

My point would be that the new syntax *also* requires one to figure out
what the new syntax does.
And unfortunately, syntax is much less discoverable than decorators.
For a decorator, I can do `help(decorator)' or search the python library
reference or probably
just mouse-hover over the name in my favourite editor/IDE.

But if I don't understand the dot in `class foo.bar:', then what?
It's probably somewhere buried in the language spec for `class' but
realistically
I am now going to blight Stackoverflow with my questions.

Stephan

2017-02-10 13:13 GMT+01:00 Joao S. O. Bueno :

> I am definetelly -1 to this idea.
>
> But since you are discussing this seriously, one nice thing is to
> recall how Javascript does that:
> `function  () ` is an expression that returns the created
> function, and thus can be assigned to anything on
> the left side.
>
> Of course, that would throw us back to a way of thinking of inline
> definition of multiline functions -
> which is another requested and unresolved thing in Python.
>
> (But we might require the `def` statement to still be aligned, at
> least style-wise, and require
> people to write
>
> Foo.foo =\
> def (self, ...): ...
>
> )
>
> That said, this possibility in Javascript is the source of severe
> inconsistencies in how functions are declared across different
> libraries and projects, and IMHO, makes reading (and writting) a real pain.
>
> (And, as stated above, a two line decorator could make for the patching -
> it does not need to have such an ugly name as "monkey_patch" - it
> could be just "assign" instead)
>
>  js
> -><-
>
> On 10 February 2017 at 09:51, Steven D'Aprano  wrote:
> > On Fri, Feb 10, 2017 at 10:05:30PM +1100, Chris Angelico wrote:
> >
> >> * What would the __name__ be? In "def ham.spam():", is the name "spam"
> >> or "ham.spam"?
> >
> > "spam" of course, just like it is now:
> >
> > py> class Ham:
> > ... def spam(self):
> > ... ...
> > ...
> > py>
> > py> Ham.spam.__name__
> > 'spam'
> >
> >
> > You might be thinking of __qualname__:
> >
> > py> Ham.spam.__qualname__
> > 'Ham.spam'
> >
> >
> >> Or say you have "def x[0]():" - is the name "x[0]" or
> >> something else?
> >
> > I wouldn't allow that. I feel that "any assignment target at all" is an
> > over-generalisation, a case of YAGNI.
> >
> > It is relatively easy to change our mind and add additional cases in the
> > future, but very difficult to remove them if they turn out to be a
> > mistake.
> >
> > My intuition tells me that we should allow :
> >
> > def name dot name (args):
> >
> > possibly even more than one dot:
> >
> > def name dot name dot name ... (args):
> >
> >
> > but no additional cases:
> >
> > # syntax error
> > def spam[0]function(): ...
> >
> >
> >
> >
> > --
> > 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 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] Fwd: Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Steven D'Aprano
On Fri, Feb 10, 2017 at 02:28:25PM +0200, Markus Meskanen wrote:

> I've started working on a PEP for this since most people seem to be for it.

I don't know how you get "most people" -- there's only been a handful of 
responses in the few hours since the original post. And apart from one 
explicit -1, I read most of them as neutral, not in favour.

Of course you are perfectly entitled to start work on a PEP at any time, 
but don't get your hopes up.

I'm one of the neutral parties, perhaps just a tiny bit positive +0, but 
only for the original proposal.

I am -1000 on allowing arbitrary assignment targets. I believe that the 
cost in readability far outweighs the usefulness of allowing things 
like:

def mydict[key].attr[-1](arg): ...


-- 
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] Fwd: Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Markus Meskanen
I've started working on a PEP for this since most people seem to be for it.
Will see how it turns out.

On Fri, Feb 10, 2017 at 2:13 PM, Joao S. O. Bueno 
wrote:

> I am definetelly -1 to this idea.
>
> But since you are discussing this seriously, one nice thing is to
> recall how Javascript does that:
> `function  () ` is an expression that returns the created
> function, and thus can be assigned to anything on
> the left side.
>
> Of course, that would throw us back to a way of thinking of inline
> definition of multiline functions -
> which is another requested and unresolved thing in Python.
>
> (But we might require the `def` statement to still be aligned, at
> least style-wise, and require
> people to write
>
> Foo.foo =\
> def (self, ...): ...
>
> )
>
> That said, this possibility in Javascript is the source of severe
> inconsistencies in how functions are declared across different
> libraries and projects, and IMHO, makes reading (and writting) a real pain.
>
> (And, as stated above, a two line decorator could make for the patching -
> it does not need to have such an ugly name as "monkey_patch" - it
> could be just "assign" instead)
>
>  js
> -><-
>
> On 10 February 2017 at 09:51, Steven D'Aprano  wrote:
> > On Fri, Feb 10, 2017 at 10:05:30PM +1100, Chris Angelico wrote:
> >
> >> * What would the __name__ be? In "def ham.spam():", is the name "spam"
> >> or "ham.spam"?
> >
> > "spam" of course, just like it is now:
> >
> > py> class Ham:
> > ... def spam(self):
> > ... ...
> > ...
> > py>
> > py> Ham.spam.__name__
> > 'spam'
> >
> >
> > You might be thinking of __qualname__:
> >
> > py> Ham.spam.__qualname__
> > 'Ham.spam'
> >
> >
> >> Or say you have "def x[0]():" - is the name "x[0]" or
> >> something else?
> >
> > I wouldn't allow that. I feel that "any assignment target at all" is an
> > over-generalisation, a case of YAGNI.
> >
> > It is relatively easy to change our mind and add additional cases in the
> > future, but very difficult to remove them if they turn out to be a
> > mistake.
> >
> > My intuition tells me that we should allow :
> >
> > def name dot name (args):
> >
> > possibly even more than one dot:
> >
> > def name dot name dot name ... (args):
> >
> >
> > but no additional cases:
> >
> > # syntax error
> > def spam[0]function(): ...
> >
> >
> >
> >
> > --
> > 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 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] Fwd: Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Joao S. O. Bueno
I am definetelly -1 to this idea.

But since you are discussing this seriously, one nice thing is to
recall how Javascript does that:
`function  () ` is an expression that returns the created
function, and thus can be assigned to anything on
the left side.

Of course, that would throw us back to a way of thinking of inline
definition of multiline functions -
which is another requested and unresolved thing in Python.

(But we might require the `def` statement to still be aligned, at
least style-wise, and require
people to write

Foo.foo =\
def (self, ...): ...

)

That said, this possibility in Javascript is the source of severe
inconsistencies in how functions are declared across different
libraries and projects, and IMHO, makes reading (and writting) a real pain.

(And, as stated above, a two line decorator could make for the patching -
it does not need to have such an ugly name as "monkey_patch" - it
could be just "assign" instead)

 js
-><-

On 10 February 2017 at 09:51, Steven D'Aprano  wrote:
> On Fri, Feb 10, 2017 at 10:05:30PM +1100, Chris Angelico wrote:
>
>> * What would the __name__ be? In "def ham.spam():", is the name "spam"
>> or "ham.spam"?
>
> "spam" of course, just like it is now:
>
> py> class Ham:
> ... def spam(self):
> ... ...
> ...
> py>
> py> Ham.spam.__name__
> 'spam'
>
>
> You might be thinking of __qualname__:
>
> py> Ham.spam.__qualname__
> 'Ham.spam'
>
>
>> Or say you have "def x[0]():" - is the name "x[0]" or
>> something else?
>
> I wouldn't allow that. I feel that "any assignment target at all" is an
> over-generalisation, a case of YAGNI.
>
> It is relatively easy to change our mind and add additional cases in the
> future, but very difficult to remove them if they turn out to be a
> mistake.
>
> My intuition tells me that we should allow :
>
> def name dot name (args):
>
> possibly even more than one dot:
>
> def name dot name dot name ... (args):
>
>
> but no additional cases:
>
> # syntax error
> def spam[0]function(): ...
>
>
>
>
> --
> 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/


Re: [Python-ideas] Fwd: Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Chris Angelico
On Fri, Feb 10, 2017 at 11:02 PM, Thomas Kluyver  wrote:
> On Fri, Feb 10, 2017, at 11:05 AM, Chris Angelico wrote:
>> * What would the __name__ be? In "def ham.spam():", is the name "spam"
>> or "ham.spam"? Or say you have "def x[0]():" - is the name "x[0]" or
>> something else?
>
> I'd say 'spam' in the first case, and a special value like ' function>' in the latter. You already can't rely on __name__ being a
> usable name in arbitrary callables:
>
> x[0] = lambda: 0
> x[0].__name__ == ''

And this is exactly why this wants a PEP - to collect decisions and
arguments on all of these bikesheds.

ChrisA
___
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] Fwd: Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Thomas Kluyver
On Fri, Feb 10, 2017, at 11:05 AM, Chris Angelico wrote:
> * What would the __name__ be? In "def ham.spam():", is the name "spam"
> or "ham.spam"? Or say you have "def x[0]():" - is the name "x[0]" or
> something else?

I'd say 'spam' in the first case, and a special value like '' in the latter. You already can't rely on __name__ being a
usable name in arbitrary callables:

x[0] = lambda: 0
x[0].__name__ == ''
___
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] Fwd: Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Steven D'Aprano
On Fri, Feb 10, 2017 at 10:05:30PM +1100, Chris Angelico wrote:

> * What would the __name__ be? In "def ham.spam():", is the name "spam"
> or "ham.spam"? 

"spam" of course, just like it is now:

py> class Ham:
... def spam(self):
... ...
...
py>
py> Ham.spam.__name__
'spam'


You might be thinking of __qualname__:

py> Ham.spam.__qualname__
'Ham.spam'


> Or say you have "def x[0]():" - is the name "x[0]" or
> something else?

I wouldn't allow that. I feel that "any assignment target at all" is an 
over-generalisation, a case of YAGNI.

It is relatively easy to change our mind and add additional cases in the 
future, but very difficult to remove them if they turn out to be a 
mistake.

My intuition tells me that we should allow :

def name dot name (args): 

possibly even more than one dot:

def name dot name dot name ... (args): 


but no additional cases:

# syntax error
def spam[0]function(): ...




-- 
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] Fwd: Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Paul Moore
On 10 February 2017 at 11:16, Chris Angelico  wrote:
> On Fri, Feb 10, 2017 at 10:13 PM, Paul Moore  wrote:
>> Furthermore, once we open up this possibility, I would expect requests
>> for things like
>>
>> func_table = {}
>> func_table["foo"] = lambda a, b: a+b
>> def func_table["bar"] (a,b):
>> return a-b
>>
>> pretty quickly. How would you respond to those? (Setting up function
>> tables is a much more common and reasonable need than monkeypatching
>> classes).
>
> Which is why these proposals always seem to gravitate to "anything you
> can assign to", which is at least easy enough to explain. All your
> examples would be completely acceptable.under that system.

Precisely.
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] Fwd: Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Chris Angelico
On Fri, Feb 10, 2017 at 10:13 PM, Paul Moore  wrote:
> Furthermore, once we open up this possibility, I would expect requests
> for things like
>
> func_table = {}
> func_table["foo"] = lambda a, b: a+b
> def func_table["bar"] (a,b):
> return a-b
>
> pretty quickly. How would you respond to those? (Setting up function
> tables is a much more common and reasonable need than monkeypatching
> classes).

Which is why these proposals always seem to gravitate to "anything you
can assign to", which is at least easy enough to explain. All your
examples would be completely acceptable.under that system.

ChrisA
___
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] Fwd: Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Paul Moore
On 10 February 2017 at 10:45, Markus Meskanen  wrote:
> Keep in mind that the extra syntax is *very* minor, and goes hand-to-hand
> with the existing attribute access syntax. Basically it's taking the
> existing syntax to one more place, where it in my opinion should have been
> since long ago.

In implementation terms, the syntax change is not as minor as you
suggest. At the moment, the syntax for a "def" statement is:

funcdef ::= [decorators] "def" funcname "(" [parameter_list] ")" ["->"
expression] ":" suite
funcname  ::=  identifier

You're proposing replacing "identifier" as the definition of a
"funcname" with... what? dotted_name might work, but that opens up the
possibility of

class Foo:
pass

foo = Foo

def foo.a(self): pass

(note I'm defining a method on the *instance*, not on the class). Do
you want to allow that? What about "def a.b.c.d.e(): pass" (no self as
argument, deeply nested instance attribute).

Furthermore, once we open up this possibility, I would expect requests
for things like

func_table = {}
func_table["foo"] = lambda a, b: a+b
def func_table["bar"] (a,b):
return a-b

pretty quickly. How would you respond to those? (Setting up function
tables is a much more common and reasonable need than monkeypatching
classes).

Your proposal is clear enough in terms of your intent, but the
implementation details are non-trivial.

Paul

PS Personally, I'm slightly in favour of the idea in principle, but I
don't think it's a useful enough addition to warrant having to deal
with all the questions I note above.
___
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] Fwd: Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Chris Angelico
On Fri, Feb 10, 2017 at 9:45 PM, Markus Meskanen
 wrote:
>> That saves one line, at the cost of introducing even more complexity to
>> the language.
>>
>> Are these use-cases common enough to justify the extra syntax?
>
>
> Keep in mind that the extra syntax is *very* minor, and goes hand-to-hand
> with the existing attribute access syntax. Basically it's taking the
> existing syntax to one more place, where it in my opinion should have been
> since long ago.
>

Every now and then, we get a proposal along these lines. I think it's
about time a PEP got written.

The usual way this is explained is that a function name can be
anything you can assign to. Currently, a function has to have a simple
name, and it then gets created with that as its __name__ and bound to
that name in the current namespace (module, class, or function). To
achieve what you're looking for, the syntax would be defined in terms
of assignment, same as a 'for' loop's iteration variable is:

# Perfectly legal
for spam.ham in iter: pass

# Not currently legal
def ham.spam(): pass

Markus, do you want to head this up? I'll help out with any editorial
work you have trouble with (as a PEP editor, I can assign it a number
and so on).

Considerations:

* What would the __name__ be? In "def ham.spam():", is the name "spam"
or "ham.spam"? Or say you have "def x[0]():" - is the name "x[0]" or
something else?
* Are there any syntactic ambiguities? Any special restrictions?
* Exactly what grammar token would be used? Currently NAME; might become 'test'?
* Will there be any possible backward incompatibilities?

Create a pull request against https://github.com/python/peps - looks
like the next number is 542.

Any questions, I'm happy to help.

ChrisA
___
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] Fwd: Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Markus Meskanen
>
> That saves one line, at the cost of introducing even more complexity to
> the language.
>
> Are these use-cases common enough to justify the extra syntax?
>

Keep in mind that the extra syntax is *very* minor, and goes hand-to-hand
with the existing attribute access syntax. Basically it's taking the
existing syntax to one more place, where it in my opinion should have been
since long ago.


> What advantage does this proposed syntax have?
>
> Since that's not actually a rhetorical question, I'll answer it myself:
>
> def Spam.method(self) not only saves the line
>
> Spam.method = method
>
> but it also avoids leaving a global name "method" in the namespace (no
> need to follow with `del method`); it makes it explicit from the
> beginning that the function is an attribute of Spam.
>

Yeah this is a major reason why I want this, and the reason I mentioned
"unnatural order" in the original mail. Having the class's name in the
beginning just makes it feel right..


> If the implementation is clever enough, it can avoid clashing with a
> global of the same name:
>
> eggs = "something"
>
> def Spam.eggs(self):
> ...
>
> def Cheese.eggs(self):
> ...
>
> assert eggs == "something"
>
>
> So the idea isn't without merit; but the question in my mind is whether
> the advantages outweigh the extra complexity.


I didn't even realize you would avoid the global namespace issue too, this
makes me fall in love with the idea even more. I really think the added
complexity isn't much. One thing to consider, however, is what would happen
if someone attempted to use this in a class definition:

class Foo:
...

class Bar:
def Foo.meth(self):
...
___
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] Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Markus Meskanen
On Fri, Feb 10, 2017 at 12:29 PM, Stephan Houben 
wrote:

> What about using a simple decorator instead?
>
> def monkey_patch(cls):
> return lambda func: setattr(cls, func.__name__, func)
>
> class Foo:
>pass
>
> @monkey_patch(Foo)
> def bar(self):
> return 42
>
> Foo().bar()
> # gives 42
>

This would work, but I still believe the proposed method is much shorter
and easier to follow. Decorator approach is no different from doing
`Foo.bar = bar` under the function definition I think, except it requires
one to figure out what the decorator does first.
___
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] Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Stephan Houben
What about using a simple decorator instead?

def monkey_patch(cls):
return lambda func: setattr(cls, func.__name__, func)

class Foo:
   pass

@monkey_patch(Foo)
def bar(self):
return 42

Foo().bar()
# gives 42

2017-02-10 11:15 GMT+01:00 Matthias welp :

> Hi Markus,
>
> Thanks for writing this up, as I've had this same very valid problem
> before.
>
> On 10 February 2017 at 10:13, Markus Meskanen 
> wrote:
> > I'm suggesting the addition of support to using a dot notation when
> defining
> > a function to be a method of a class, or a callback attribute.
>
> Your solution to me seems like a 'hack': class monkey-patching during
> runtime
> is already available if you really need it, and your proposal only
> makes it easier,
> which I don't really like.
>
> > This functionality would be useful in the few rare cases where the class
> > itself needs to be accessed in the function's definition (decorator,
> typing,
> > etc
>
> This problem could just as well be solved by allowing access to a
> scope-level
> variable (__class__? __type__?) which is available in the class body at
> construction time, which points to the (eventual) class type object,
> or evaluating
> the type hints in a class only after the class is created, which then
> allows for that
> class to be pointed to in the type annotations.
>
> E.G. this does not work right now:
>
> class A:
> def foo(self: A):
> pass
>
> as it fails with NameError: A is not defined, whereas you'd expect it to
> work.
>
> The problem is very annoying when you're trying to work with the dunder
> methods for e.g. numerical objects, as you cannot say '+ is only allowed
> for
> these types', but it is not limited to this scope only.
>
>
> -Matthias
> ___
> 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] Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Steven D'Aprano
On Fri, Feb 10, 2017 at 11:13:47AM +0200, Markus Meskanen wrote:
> I'm suggesting the addition of support to using a dot notation when
> defining a function to be a method of a class, or a callback attribute. For
> example:
> 
> def foo(self):
> pass
> Foo.foo = foo
> 
> Becomes:
> 
> def Foo.foo(self):
> pass

That saves one line, at the cost of introducing even more complexity to 
the language.

Are these use-cases common enough to justify the extra syntax?


> Other syntaxes can also be used if the dot itself is an issue, although I
> dislike these:
> 
> def Foo:foo(self):
> def foo@Foo(self):
> def Foo>foo(self):
> def Foo(self):

That's just putting arbitrary symbols into the statement.

I know that *ultimately* all symbols are arbitrary, but . dot means 
attribute access in Python, so Foo.foo at least has some connection to 
creating an attribute of Foo called foo. In what way does "Foo greater 
than foo" suggest to the reader that foo ends up as an attribute of Foo?


> This functionality would be useful in the few rare cases where the class
> itself needs to be accessed in the function's definition (decorator,
> typing, etc.):

I'm sure that there are a number of use-cases for injecting a method 
into an existing class. But we already have a way of doing that:

def method(self): ...
Spam.method = method

What advantage does this proposed syntax have?

Since that's not actually a rhetorical question, I'll answer it myself:

def Spam.method(self) not only saves the line

Spam.method = method

but it also avoids leaving a global name "method" in the namespace (no 
need to follow with `del method`); it makes it explicit from the 
beginning that the function is an attribute of Spam.

If the implementation is clever enough, it can avoid clashing with a 
global of the same name:

eggs = "something"

def Spam.eggs(self):
...

def Cheese.eggs(self):
...

assert eggs == "something"


So the idea isn't without merit; but the question in my mind is whether 
the advantages outweigh the extra complexity.


-- 
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] Define a method or function attribute outside of a class with the dot operator

2017-02-10 Thread Markus Meskanen
I'm suggesting the addition of support to using a dot notation when
defining a function to be a method of a class, or a callback attribute. For
example:

def foo(self):
pass
Foo.foo = foo

Becomes:

def Foo.foo(self):
pass

Other syntaxes can also be used if the dot itself is an issue, although I
dislike these:

def Foo:foo(self):
def foo@Foo(self):
def Foo>foo(self):
def Foo(self):

This functionality would be useful in the few rare cases where the class
itself needs to be accessed in the function's definition (decorator,
typing, etc.):

@barify(Foo)
def Foo.method(self, other: Foo) -> Foo:
pass

And when an object needs a callback as an attribute:

class Menu:
def __init__(self, items=None, select_callback=None):
self.items = items if items is not None else []
self.select_callback = select_callback

my_menu = Menu([item1, item2])

def my_menu.select_callback(self, item_index):
print(self.items[item_index])

As opposed to:

my_menu = Menu([item1, item2])

def select_callback(self, item_index):
print(self.items[item_index])
my_menu.select_callback = select_callback

Or defining them in "unnatural" order:

def select_callback(self, item_index):
print(self.items[item_index])

my_menu = Menu([item1, item2], select_callback)
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/