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 <joshua.morto...@gmail.com>
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 <ncogh...@gmail.com> wrote:
>
>> On 10 February 2017 at 16:25, Steven D'Aprano <st...@pearwood.info>
>> 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/
>
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to