Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id B697D2009C6 for ; Sun, 1 May 2016 20:07:05 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id B51E61609AA; Sun, 1 May 2016 20:07:05 +0200 (CEST) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id B32F916010A for ; Sun, 1 May 2016 20:07:04 +0200 (CEST) Received: (qmail 60335 invoked by uid 500); 1 May 2016 18:07:03 -0000 Mailing-List: contact dev-help@cloudstack.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cloudstack.apache.org Delivered-To: mailing list dev@cloudstack.apache.org Received: (qmail 60324 invoked by uid 99); 1 May 2016 18:07:03 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd1-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 01 May 2016 18:07:03 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd1-us-west.apache.org (ASF Mail Server at spamd1-us-west.apache.org) with ESMTP id 4C760C0D3D for ; Sun, 1 May 2016 18:06:44 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd1-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -5.197 X-Spam-Level: X-Spam-Status: No, score=-5.197 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, RCVD_IN_DNSWL_HI=-5, RP_MATCHES_RCVD=-0.996, SPF_PASS=-0.001] autolearn=disabled Received: from mx2-lw-eu.apache.org ([10.40.0.8]) by localhost (spamd1-us-west.apache.org [10.40.0.7]) (amavisd-new, port 10024) with ESMTP id qP5Qamfxx9Zt for ; Sun, 1 May 2016 18:06:40 +0000 (UTC) Received: from mx144.netapp.com (mx144.netapp.com [216.240.21.25]) by mx2-lw-eu.apache.org (ASF Mail Server at mx2-lw-eu.apache.org) with ESMTPS id 499E75F1B4 for ; Sun, 1 May 2016 18:06:39 +0000 (UTC) X-IronPort-AV: E=Sophos;i="5.24,563,1455004800"; d="scan'208";a="113790399" Received: from hioexcmbx07-prd.hq.netapp.com ([10.122.105.40]) by mx144-out.netapp.com with ESMTP; 01 May 2016 11:06:33 -0700 Received: from HIOEXCMBX05-PRD.hq.netapp.com (10.122.105.38) by hioexcmbx07-prd.hq.netapp.com (10.122.105.40) with Microsoft SMTP Server (TLS) id 15.0.1156.6; Sun, 1 May 2016 11:06:32 -0700 Received: from HIOEXCMBX05-PRD.hq.netapp.com ([::1]) by hioexcmbx05-prd.hq.netapp.com ([fe80::dd75:c5fa:b5a0:23a7%21]) with mapi id 15.00.1156.000; Sun, 1 May 2016 11:06:32 -0700 From: "Tutkowski, Mike" To: "dev@cloudstack.apache.org" Subject: Re: Python Question (with regards to Marvin) Thread-Topic: Python Question (with regards to Marvin) Thread-Index: AQHRop1L0/Y4TEMUkUWj+q7EuNNrI5+i5kcAgAACREmAAHmMAP//r69hgACYwID//5mIQoAATOFrgADciQD//9efnwAAuy8iABGaZwD//4syNg== Date: Sun, 1 May 2016 18:06:31 +0000 Message-ID: <1462125991183.18906@netapp.com> References: <1461992897090.81293@netapp.com> <8FAB73AE-A9F6-4BE2-9912-D3B70B6E7651@netapp.com> <1462053829729.78518@netapp.com> <55CCF01C-BEAB-40C7-A0A0-7AAE37AE9A0A@netapp.com> <1462081223172.93482@netapp.com> <1462120896532.34221@netapp.com>, In-Reply-To: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-transport-fromentityheader: Hosted x-originating-ip: [10.120.60.36] Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 archived-at: Sun, 01 May 2016 18:07:05 -0000 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.=0A= ________________________________________=0A= From: Will Stevens =0A= Sent: Sunday, May 1, 2016 12:03 PM=0A= To: dev@cloudstack.apache.org=0A= Subject: Re: Python Question (with regards to Marvin)=0A= =0A= It will be easy to grep if there class methods, so we should start there.= =0A= If not, then I agree that an instance method is probably the best way to=0A= go.=0A= On May 1, 2016 12:41 PM, "Tutkowski, Mike" =0A= wrote:=0A= =0A= > However, from a design standpoint, I prefer the instance method here as i= t=0A= > would be nice to ask the object itself to place itself in maintenance mod= e.=0A= >=0A= > So, it's really a question of just staying backward compatible (the class= =0A= > method) or a possibly better design (the instance method).=0A= > ________________________________________=0A= > From: Tutkowski, Mike =0A= > Sent: Sunday, May 1, 2016 10:18 AM=0A= > To: dev@cloudstack.apache.org=0A= > Subject: Re: Python Question (with regards to Marvin)=0A= >=0A= > The question then becomes, do we want to keep the instance or the class= =0A= > method?=0A= >=0A= > There exists the same problem for at least one other pair of methods.=0A= >=0A= > Since the class method is listed second in the file currently, it is the= =0A= > only one of the two that can be utilized. That being the case, we might= =0A= > just want to keep the class method and remove the instance method.=0A= >=0A= > > On May 1, 2016, at 5:43 AM, Will Stevens =0A= > wrote:=0A= > >=0A= > > Yep. Looking like there is a bug in that file. Thanks for testing. :)= =0A= > >> On May 1, 2016 1:40 AM, "Tutkowski, Mike" = =0A= > wrote:=0A= > >>=0A= > >> Here are my tests (run from http://ideone.com/).=0A= > >>=0A= > >> The short story is that having multiple methods with the same name (ev= en=0A= > >> if one is an instance method and one is a class method) should probabl= y=0A= > not=0A= > >> be done.=0A= > >>=0A= > >> If you try to invoke the instance method (ex. test.run()), the last=0A= > method=0A= > >> by that name in the source file is invoked (which could be the class= =0A= > >> method). If the number of parameters don't match, that's an error.=0A= > >>=0A= > >> If you try to invoke the class method (ex. Test.run()), the last metho= d=0A= > by=0A= > >> that name in the source file is invoked. If this is not a class method= =0A= > or=0A= > >> if the number of parameters don't match, that's an error.=0A= > >>=0A= > >> class Test:=0A= > >> @classmethod=0A= > >> def run(cls):=0A= > >> print "class hi"=0A= > >>=0A= > >> def run(self):=0A= > >> print "instance hi"=0A= > >>=0A= > >> test =3D Test()=0A= > >>=0A= > >> test.run()=0A= > >>=0A= > >> What gets printed:=0A= > >> instance hi=0A= > >>=0A= > >> class Test:=0A= > >> def run(self):=0A= > >> print "instance hi"=0A= > >>=0A= > >> @classmethod=0A= > >> def run(cls):=0A= > >> print "class hi"=0A= > >>=0A= > >> test =3D Test()=0A= > >>=0A= > >> test.run()=0A= > >>=0A= > >> What gets printed:=0A= > >> class hi=0A= > >>=0A= > >> class Test:=0A= > >> @classmethod=0A= > >> def run(cls):=0A= > >> print "class hi"=0A= > >>=0A= > >> def run(self):=0A= > >> print "instance hi"=0A= > >>=0A= > >> # test =3D Test()=0A= > >>=0A= > >> Test.run()=0A= > >>=0A= > >> Runtime error=0A= > >>=0A= > >> class Test:=0A= > >> @classmethod=0A= > >> def run(cls):=0A= > >> print "class hi"=0A= > >>=0A= > >> # test =3D Test()=0A= > >>=0A= > >> Test.run()=0A= > >>=0A= > >> What gets printed:=0A= > >> class hi=0A= > >>=0A= > >> class Test:=0A= > >> def run(self):=0A= > >> print "instance hi"=0A= > >>=0A= > >> @classmethod=0A= > >> def run(cls):=0A= > >> print "class hi"=0A= > >>=0A= > >> # test =3D Test()=0A= > >>=0A= > >> Test.run()=0A= > >>=0A= > >> What gets printed:=0A= > >> class hi=0A= > >>=0A= > >> class Test:=0A= > >> @classmethod=0A= > >> def run(cls):=0A= > >> print "class hi"=0A= > >>=0A= > >> # test =3D Test()=0A= > >>=0A= > >> Test.run()=0A= > >>=0A= > >> What gets printed:=0A= > >> class hi=0A= > >> ________________________________________=0A= > >> From: Tutkowski, Mike=0A= > >> Sent: Saturday, April 30, 2016 6:58 PM=0A= > >> To: dev@cloudstack.apache.org=0A= > >> Subject: Re: Python Question (with regards to Marvin)=0A= > >>=0A= > >> I can play around with it later tonight. I'm not home at the moment.= =0A= > >>=0A= > >> When I did invoke it as Test.run(), it invoked the class method (the= =0A= > class=0A= > >> method was listed after the instance method for that test, so I wasn't= =0A= > >> surprised that the class method did, in fact, get executed there).=0A= > >>=0A= > >> What I did not try was to list the class method first, then list the= =0A= > >> instance method, and then try to invoke the class method.=0A= > >>=0A= > >> As mentioned in my prior e-mail, when I did try to invoke the instance= =0A= > >> version of run, it was only successful if the instance version was the= =0A= > >> second one declared in the file. If the class method was declared=0A= > second,=0A= > >> then it was invoked even when I was trying to invoke the instance one.= =0A= > >>=0A= > >>>> On Apr 30, 2016, at 6:06 PM, Will Stevens = =0A= > >>> wrote:=0A= > >>>=0A= > >>> That's strange. That means the @classmethod decorator is not working.= =0A= > You=0A= > >>> should have gotten the instance method in both cases.=0A= > >>>=0A= > >>> What if you don't instantiate Test and only do the following.=0A= > >>>=0A= > >>> Test.run()=0A= > >>>=0A= > >>> In both cases.=0A= > >>> On Apr 30, 2016 6:04 PM, "Tutkowski, Mike" =0A= > >>> wrote:=0A= > >>>=0A= > >>>> I ran this with an online Python tool and it calls the class method:= =0A= > >>>>=0A= > >>>> 1 class Test:=0A= > >>>> 2 def run(self):=0A= > >>>> 3 print 'instance hi'=0A= > >>>> 4=0A= > >>>> 5 @classmethod=0A= > >>>> 6 def run(cls):=0A= > >>>> 7 print 'class hi'=0A= > >>>> 8=0A= > >>>> 9 test =3D Test()=0A= > >>>> 10=0A= > >>>> 11 test.run()=0A= > >>>>=0A= > >>>> If I reverse the order of the methods, the instance method is invoke= d:=0A= > >>>>=0A= > >>>> 1 class Test:=0A= > >>>> 2 @classmethod=0A= > >>>> 3 def run(cls):=0A= > >>>> 4 print 'class hi'=0A= > >>>> 5=0A= > >>>> 6 def run(self):=0A= > >>>> 7 print 'instance hi'=0A= > >>>> 8=0A= > >>>> 9 test =3D Test()=0A= > >>>> 10=0A= > >>>> 11 test.run()=0A= > >>>>=0A= > >>>> As I suspected, I think this means we have a problem in base.py.=0A= > >>>> ________________________________________=0A= > >>>> From: Will Stevens =0A= > >>>> Sent: Saturday, April 30, 2016 1:46 PM=0A= > >>>> To: dev@cloudstack.apache.org=0A= > >>>> Subject: Re: Python Question (with regards to Marvin)=0A= > >>>>=0A= > >>>> I am on my phone so I have not been able to research this for you. I= =0A= > >> think=0A= > >>>> you are right for the most part. Instead of multiple methods, pytho= n=0A= > >> kind=0A= > >>>> of fakes overloading by being to have named function arguments which= =0A= > can=0A= > >>>> have default values, so you can call the method with a dynamic numbe= r=0A= > of=0A= > >>>> arguments making it appear like you are overloading, but you are=0A= > >> actually=0A= > >>>> calling the same function.=0A= > >>>>=0A= > >>>> I think in this case the two methods are actually in different scope= s=0A= > >> (even=0A= > >>>> though they are next to each other). The decorator actually wraps t= he=0A= > >>>> method, so I believe in the actual runtime the to methods are in=0A= > >> different=0A= > >>>> scopes.=0A= > >>>>=0A= > >>>> I would have to look into this more to know for sure. I am taking a= =0A= > few=0A= > >>>> minute break from building garden boxes right now. :)=0A= > >>>> On Apr 30, 2016 3:31 PM, "Tutkowski, Mike" >=0A= > >>>> wrote:=0A= > >>>>=0A= > >>>>> Will - You can override a method in Python, but can you overload it= ?=0A= > >>=0A= > http://stackoverflow.com/questions/10202938/how-do-i-use-method-overloadi= ng-in-python=0A= > >>>>>=0A= > >>>>>>> On Apr 30, 2016, at 6:23 AM, Will Stevens <=0A= > williamstevens@gmail.com>=0A= > >>>>>> wrote:=0A= > >>>>>>=0A= > >>>>>> Here is a pretty good explanation.=0A= > >>=0A= > http://stackoverflow.com/questions/136097/what-is-the-difference-between-= staticmethod-and-classmethod-in-python=0A= > >>>>>>=0A= > >>>>>> I am guessing that both exist because the function is called both= =0A= > with=0A= > >>>> a=0A= > >>>>>> host instance and with the class itself.=0A= > >>>>>>=0A= > >>>>>> Class instance example: `h.enableMaintenance(client)`=0A= > >>>>>>=0A= > >>>>>> Class example: `Host.enableMaintenance(client, 1)`=0A= > >>>>>>=0A= > >>>>>> In both cases the first parameter is implicitly `h` and `Host`=0A= > >>>>>> respectively.=0A= > >>>>>>=0A= > >>>>>> I am not sure why we need both (because I am not familiar with how= =0A= > >> this=0A= > >>>>>> code is called), but method overloading is definitely valid in=0A= > python.=0A= > >>>>>>=0A= > >>>>>> On Apr 30, 2016 1:08 AM, "Tutkowski, Mike" <=0A= > Mike.Tutkowski@netapp.com=0A= > >>>=0A= > >>>>>> wrote:=0A= > >>>>>>>=0A= > >>>>>>> Hi everyone,=0A= > >>>>>>>=0A= > >>>>>>>=0A= > >>>>>>> I received an error when trying to invoke the instance version of= =0A= > >>>>>> enableMaintenance (below).=0A= > >>>>>>>=0A= > >>>>>>>=0A= > >>>>>>> 'TypeError: enableMaintenance() takes exactly 3 arguments (2=0A= > >>>> given)\n']=0A= > >>>>>>>=0A= > >>>>>>>=0A= > >>>>>>> I looked at base.py and it has the following with regards to=0A= > >>>> maintenance=0A= > >>>>>> mode for hosts:=0A= > >>>>>>>=0A= > >>>>>>>=0A= > >>>>>>> def enableMaintenance(self, apiclient):=0A= > >>>>>>>=0A= > >>>>>>> """enables maintenance mode Host"""=0A= > >>>>>>>=0A= > >>>>>>>=0A= > >>>>>>> cmd =3D prepareHostForMaintenance.prepareHostForMaintenanceC= md()=0A= > >>>>>>>=0A= > >>>>>>> cmd.id =3D self.id=0A= > >>>>>>>=0A= > >>>>>>> return apiclient.prepareHostForMaintenance(cmd)=0A= > >>>>>>>=0A= > >>>>>>>=0A= > >>>>>>> @classmethod=0A= > >>>>>>>=0A= > >>>>>>> def enableMaintenance(cls, apiclient, id):=0A= > >>>>>>>=0A= > >>>>>>> """enables maintenance mode Host"""=0A= > >>>>>>>=0A= > >>>>>>>=0A= > >>>>>>> cmd =3D prepareHostForMaintenance.prepareHostForMaintenanceC= md()=0A= > >>>>>>>=0A= > >>>>>>> cmd.id =3D id=0A= > >>>>>>>=0A= > >>>>>>> return apiclient.prepareHostForMaintenance(cmd)=0A= > >>>>>>>=0A= > >>>>>>>=0A= > >>>>>>> Now, I definitely have a lot more Java experience than Python, bu= t=0A= > -=0A= > >>>> as=0A= > >>>>>> far as I know - having two methods with the same name such as this= =0A= > >>>> (even=0A= > >>>>> if=0A= > >>>>>> one is an instance method and the other is a class method) is not= =0A= > >>>> really=0A= > >>>>>> "permitted" in Python.=0A= > >>>>>>>=0A= > >>>>>>>=0A= > >>>>>>> I mean, technically it's permitted, but the second one will=0A= > override=0A= > >>>> the=0A= > >>>>>> first one.=0A= > >>>>>>>=0A= > >>>>>>>=0A= > >>>>>>> Can any of our Python people comment on this?=0A= > >>>>>>>=0A= > >>>>>>>=0A= > >>>>>>> I was thinking I'd remove the class method (assuming my knowledge= =0A= > >> here=0A= > >>>>>> regarding this topic is correct).=0A= > >>>>>>>=0A= > >>>>>>>=0A= > >>>>>>> Thanks!=0A= > >>>>>>>=0A= > >>>>>>> Mike=0A= > >>=0A= >=0A=