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/