Re: [Python-ideas] PEP proposal: unifying function/method classes

On 2018-03-23 00:36, Antoine Pitrou wrote:
It does make sense, since the proposal sounds ambitious (and perhaps impossible without breaking compatibility).
Well, *some* breakage of backwards compatibility will be unavoidable. My plan (just a plan for now!) is to preserve backwards compatibility in the following ways: * Existing Python attributes of functions/methods should continue to exist and behave the same * The inspect module should give the same results as now (by changing the implementation of some of the functions in inspect to match the new classes) * Everything from the documented Python/C API. This means that I might break compatibility in the following ways: * Changing the classes of functions/methods (this is the whole point of this PEP). So anything involving isinstance() checks might break. * The undocumented parts of the Python/C API, in particular the C structure.

On Fri, 23 Mar 2018 07:25:33 +0100 Jeroen Demeyer <J.Demeyer@UGent.be> wrote:
One breaking change would be to add __get__ to C functions. This means e.g. the following: class MyClass: my_open = open would make my_open a MyClass method, therefore you would need to spell it: class MyClass: my_open = staticmethod(open) ... if you wanted MyClass().my_open('some file') to continue to work. Of course that might be considered a minor annoyance. Regards Antoine.

On Fri, Mar 23, 2018 at 11:25 AM, Antoine Pitrou <solipsis@pitrou.net> wrote:
I don't really see your point in this example. For one: why would anyone do this? Is this based on a real example? 2) That's how any function works. If you put some arbitrary function in a class body, and it's not able to accept an instance of that class as its first argument, then it will always be broken unless you make it a staticmethod. I don't see how there should be any difference there if the function were implemented in Python or in C. Thanks, E

On Wed, 28 Mar 2018 19:22:50 +0200 Erik Bray <erik.m.bray@gmail.com> wrote:
I don't really see your point in this example. For one: why would anyone do this? Is this based on a real example?
Yes, I remember doing that when writing unit tests for open() and open()-like functions. You would write a base test case: class TestBase: open_func = None def test_something(self): self.open_func(...) # etc. and then instantiate concrete subclasses: class BuiltinOpenTest(TestBase, unittest.TestCase): open_func = open class PyOpenTest(TestBase, unittest.TestCase): open_func = staticmethod(_pyio.open)
I agree that there *should* be no difference. The point is, there is currently a difference and suppressing it may break compatibility. I don't think the breakage is important enough to stop us from streamlining things here. Just pointing out the risk exists. Regards Antoine.

28.03.18 20:22, Erik Bray пише:
Yes, there are real examples. Good or bad, it is well known behavior of builtin functions, and real code depends on it. For sure changing it will break a lot of user code (and also the Python stdlib and tests). Just try to implements the support of the descriptor protocol in builtin functions and you will see how much code this will break.

On Fri, 23 Mar 2018 07:25:33 +0100 Jeroen Demeyer <J.Demeyer@UGent.be> wrote:
One breaking change would be to add __get__ to C functions. This means e.g. the following: class MyClass: my_open = open would make my_open a MyClass method, therefore you would need to spell it: class MyClass: my_open = staticmethod(open) ... if you wanted MyClass().my_open('some file') to continue to work. Of course that might be considered a minor annoyance. Regards Antoine.

On Fri, Mar 23, 2018 at 11:25 AM, Antoine Pitrou <solipsis@pitrou.net> wrote:
I don't really see your point in this example. For one: why would anyone do this? Is this based on a real example? 2) That's how any function works. If you put some arbitrary function in a class body, and it's not able to accept an instance of that class as its first argument, then it will always be broken unless you make it a staticmethod. I don't see how there should be any difference there if the function were implemented in Python or in C. Thanks, E

On Wed, 28 Mar 2018 19:22:50 +0200 Erik Bray <erik.m.bray@gmail.com> wrote:
I don't really see your point in this example. For one: why would anyone do this? Is this based on a real example?
Yes, I remember doing that when writing unit tests for open() and open()-like functions. You would write a base test case: class TestBase: open_func = None def test_something(self): self.open_func(...) # etc. and then instantiate concrete subclasses: class BuiltinOpenTest(TestBase, unittest.TestCase): open_func = open class PyOpenTest(TestBase, unittest.TestCase): open_func = staticmethod(_pyio.open)
I agree that there *should* be no difference. The point is, there is currently a difference and suppressing it may break compatibility. I don't think the breakage is important enough to stop us from streamlining things here. Just pointing out the risk exists. Regards Antoine.

28.03.18 20:22, Erik Bray пише:
Yes, there are real examples. Good or bad, it is well known behavior of builtin functions, and real code depends on it. For sure changing it will break a lot of user code (and also the Python stdlib and tests). Just try to implements the support of the descriptor protocol in builtin functions and you will see how much code this will break.
participants (4)
-
Antoine Pitrou
-
Erik Bray
-
Jeroen Demeyer
-
Serhiy Storchaka