I was just "concerned" that those who have their own Marvin tests that are not checked in might be broken if I don't keep the class method. ________________________________________ From: Will Stevens <williamstev...@gmail.com> Sent: Sunday, May 1, 2016 12:03 PM To: dev@cloudstack.apache.org Subject: Re: Python Question (with regards to Marvin)
It will be easy to grep if there class methods, so we should start there. If not, then I agree that an instance method is probably the best way to go. On May 1, 2016 12:41 PM, "Tutkowski, Mike" <mike.tutkow...@netapp.com> wrote: > However, from a design standpoint, I prefer the instance method here as it > would be nice to ask the object itself to place itself in maintenance mode. > > So, it's really a question of just staying backward compatible (the class > method) or a possibly better design (the instance method). > ________________________________________ > From: Tutkowski, Mike <mike.tutkow...@netapp.com> > Sent: Sunday, May 1, 2016 10:18 AM > To: dev@cloudstack.apache.org > Subject: Re: Python Question (with regards to Marvin) > > The question then becomes, do we want to keep the instance or the class > method? > > There exists the same problem for at least one other pair of methods. > > Since the class method is listed second in the file currently, it is the > only one of the two that can be utilized. That being the case, we might > just want to keep the class method and remove the instance method. > > > On May 1, 2016, at 5:43 AM, Will Stevens <williamstev...@gmail.com> > wrote: > > > > Yep. Looking like there is a bug in that file. Thanks for testing. :) > >> On May 1, 2016 1:40 AM, "Tutkowski, Mike" <mike.tutkow...@netapp.com> > wrote: > >> > >> Here are my tests (run from http://ideone.com/). > >> > >> The short story is that having multiple methods with the same name (even > >> if one is an instance method and one is a class method) should probably > not > >> be done. > >> > >> If you try to invoke the instance method (ex. test.run()), the last > method > >> by that name in the source file is invoked (which could be the class > >> method). If the number of parameters don't match, that's an error. > >> > >> If you try to invoke the class method (ex. Test.run()), the last method > by > >> that name in the source file is invoked. If this is not a class method > or > >> if the number of parameters don't match, that's an error. > >> > >> class Test: > >> @classmethod > >> def run(cls): > >> print "class hi" > >> > >> def run(self): > >> print "instance hi" > >> > >> test = Test() > >> > >> test.run() > >> > >> What gets printed: > >> instance hi > >> > >> class Test: > >> def run(self): > >> print "instance hi" > >> > >> @classmethod > >> def run(cls): > >> print "class hi" > >> > >> test = Test() > >> > >> test.run() > >> > >> What gets printed: > >> class hi > >> > >> class Test: > >> @classmethod > >> def run(cls): > >> print "class hi" > >> > >> def run(self): > >> print "instance hi" > >> > >> # test = Test() > >> > >> Test.run() > >> > >> Runtime error > >> > >> class Test: > >> @classmethod > >> def run(cls): > >> print "class hi" > >> > >> # test = Test() > >> > >> Test.run() > >> > >> What gets printed: > >> class hi > >> > >> class Test: > >> def run(self): > >> print "instance hi" > >> > >> @classmethod > >> def run(cls): > >> print "class hi" > >> > >> # test = Test() > >> > >> Test.run() > >> > >> What gets printed: > >> class hi > >> > >> class Test: > >> @classmethod > >> def run(cls): > >> print "class hi" > >> > >> # test = Test() > >> > >> Test.run() > >> > >> What gets printed: > >> class hi > >> ________________________________________ > >> From: Tutkowski, Mike > >> Sent: Saturday, April 30, 2016 6:58 PM > >> To: dev@cloudstack.apache.org > >> Subject: Re: Python Question (with regards to Marvin) > >> > >> I can play around with it later tonight. I'm not home at the moment. > >> > >> When I did invoke it as Test.run(), it invoked the class method (the > class > >> method was listed after the instance method for that test, so I wasn't > >> surprised that the class method did, in fact, get executed there). > >> > >> What I did not try was to list the class method first, then list the > >> instance method, and then try to invoke the class method. > >> > >> As mentioned in my prior e-mail, when I did try to invoke the instance > >> version of run, it was only successful if the instance version was the > >> second one declared in the file. If the class method was declared > second, > >> then it was invoked even when I was trying to invoke the instance one. > >> > >>>> On Apr 30, 2016, at 6:06 PM, Will Stevens <williamstev...@gmail.com> > >>> wrote: > >>> > >>> That's strange. That means the @classmethod decorator is not working. > You > >>> should have gotten the instance method in both cases. > >>> > >>> What if you don't instantiate Test and only do the following. > >>> > >>> Test.run() > >>> > >>> In both cases. > >>> On Apr 30, 2016 6:04 PM, "Tutkowski, Mike" <mike.tutkow...@netapp.com> > >>> wrote: > >>> > >>>> I ran this with an online Python tool and it calls the class method: > >>>> > >>>> 1 class Test: > >>>> 2 def run(self): > >>>> 3 print 'instance hi' > >>>> 4 > >>>> 5 @classmethod > >>>> 6 def run(cls): > >>>> 7 print 'class hi' > >>>> 8 > >>>> 9 test = Test() > >>>> 10 > >>>> 11 test.run() > >>>> > >>>> If I reverse the order of the methods, the instance method is invoked: > >>>> > >>>> 1 class Test: > >>>> 2 @classmethod > >>>> 3 def run(cls): > >>>> 4 print 'class hi' > >>>> 5 > >>>> 6 def run(self): > >>>> 7 print 'instance hi' > >>>> 8 > >>>> 9 test = Test() > >>>> 10 > >>>> 11 test.run() > >>>> > >>>> As I suspected, I think this means we have a problem in base.py. > >>>> ________________________________________ > >>>> From: Will Stevens <williamstev...@gmail.com> > >>>> Sent: Saturday, April 30, 2016 1:46 PM > >>>> To: dev@cloudstack.apache.org > >>>> Subject: Re: Python Question (with regards to Marvin) > >>>> > >>>> I am on my phone so I have not been able to research this for you. I > >> think > >>>> you are right for the most part. Instead of multiple methods, python > >> kind > >>>> of fakes overloading by being to have named function arguments which > can > >>>> have default values, so you can call the method with a dynamic number > of > >>>> arguments making it appear like you are overloading, but you are > >> actually > >>>> calling the same function. > >>>> > >>>> I think in this case the two methods are actually in different scopes > >> (even > >>>> though they are next to each other). The decorator actually wraps the > >>>> method, so I believe in the actual runtime the to methods are in > >> different > >>>> scopes. > >>>> > >>>> I would have to look into this more to know for sure. I am taking a > few > >>>> minute break from building garden boxes right now. :) > >>>> On Apr 30, 2016 3:31 PM, "Tutkowski, Mike" <mike.tutkow...@netapp.com > > > >>>> wrote: > >>>> > >>>>> Will - You can override a method in Python, but can you overload it? > >> > http://stackoverflow.com/questions/10202938/how-do-i-use-method-overloading-in-python > >>>>> > >>>>>>> On Apr 30, 2016, at 6:23 AM, Will Stevens < > williamstev...@gmail.com> > >>>>>> wrote: > >>>>>> > >>>>>> Here is a pretty good explanation. > >> > http://stackoverflow.com/questions/136097/what-is-the-difference-between-staticmethod-and-classmethod-in-python > >>>>>> > >>>>>> I am guessing that both exist because the function is called both > with > >>>> a > >>>>>> host instance and with the class itself. > >>>>>> > >>>>>> Class instance example: `h.enableMaintenance(client)` > >>>>>> > >>>>>> Class example: `Host.enableMaintenance(client, 1)` > >>>>>> > >>>>>> In both cases the first parameter is implicitly `h` and `Host` > >>>>>> respectively. > >>>>>> > >>>>>> I am not sure why we need both (because I am not familiar with how > >> this > >>>>>> code is called), but method overloading is definitely valid in > python. > >>>>>> > >>>>>> On Apr 30, 2016 1:08 AM, "Tutkowski, Mike" < > mike.tutkow...@netapp.com > >>> > >>>>>> wrote: > >>>>>>> > >>>>>>> Hi everyone, > >>>>>>> > >>>>>>> > >>>>>>> I received an error when trying to invoke the instance version of > >>>>>> enableMaintenance (below). > >>>>>>> > >>>>>>> > >>>>>>> 'TypeError: enableMaintenance() takes exactly 3 arguments (2 > >>>> given)\n'] > >>>>>>> > >>>>>>> > >>>>>>> I looked at base.py and it has the following with regards to > >>>> maintenance > >>>>>> mode for hosts: > >>>>>>> > >>>>>>> > >>>>>>> def enableMaintenance(self, apiclient): > >>>>>>> > >>>>>>> """enables maintenance mode Host""" > >>>>>>> > >>>>>>> > >>>>>>> cmd = prepareHostForMaintenance.prepareHostForMaintenanceCmd() > >>>>>>> > >>>>>>> cmd.id = self.id > >>>>>>> > >>>>>>> return apiclient.prepareHostForMaintenance(cmd) > >>>>>>> > >>>>>>> > >>>>>>> @classmethod > >>>>>>> > >>>>>>> def enableMaintenance(cls, apiclient, id): > >>>>>>> > >>>>>>> """enables maintenance mode Host""" > >>>>>>> > >>>>>>> > >>>>>>> cmd = prepareHostForMaintenance.prepareHostForMaintenanceCmd() > >>>>>>> > >>>>>>> cmd.id = id > >>>>>>> > >>>>>>> return apiclient.prepareHostForMaintenance(cmd) > >>>>>>> > >>>>>>> > >>>>>>> Now, I definitely have a lot more Java experience than Python, but > - > >>>> as > >>>>>> far as I know - having two methods with the same name such as this > >>>> (even > >>>>> if > >>>>>> one is an instance method and the other is a class method) is not > >>>> really > >>>>>> "permitted" in Python. > >>>>>>> > >>>>>>> > >>>>>>> I mean, technically it's permitted, but the second one will > override > >>>> the > >>>>>> first one. > >>>>>>> > >>>>>>> > >>>>>>> Can any of our Python people comment on this? > >>>>>>> > >>>>>>> > >>>>>>> I was thinking I'd remove the class method (assuming my knowledge > >> here > >>>>>> regarding this topic is correct). > >>>>>>> > >>>>>>> > >>>>>>> Thanks! > >>>>>>> > >>>>>>> Mike > >> >