You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cloudstack.apache.org by "Tutkowski, Mike" <Mi...@netapp.com> on 2016/05/01 00:03:47 UTC

Re: Python Question (with regards to Marvin)

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 <wi...@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" <Mi...@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 <wi...@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" <Mi...@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
> >>
> >>
> >>
>

Re: Python Question (with regards to Marvin)

Posted by "Tutkowski, Mike" <Mi...@netapp.com>.
If a couple people could review this (it should be fast), I opened the following PR:

https://github.com/apache/cloudstack/pull/1528

Thanks!
Mike
________________________________________
From: Tutkowski, Mike
Sent: Sunday, May 1, 2016 7:16 PM
To: dev@cloudstack.apache.org
Subject: Re: Python Question (with regards to Marvin)

"A bunch of UI scripts use those class methods (I didn't see us trying to use the instance methods anywhere)."

I meant that a bunch of test scripts use those methods (not UI scripts).

> On May 1, 2016, at 5:24 PM, Tutkowski, Mike <Mi...@netapp.com> wrote:
>
> So, the problem exists with both enableMaintenance and cancelMaintenance for hosts and with enableMaintenance for storage (not with cancelMaintenance for storage).
>
> A bunch of UI scripts use those class methods (I didn't see us trying to use the instance methods anywhere).
>
> I believe those class methods exist because the test scripts already have the UUIDs of the host or storage and those class methods provide a faster means of performing the action in question (when compared to having to retrieve a host or storage object from the applicable UUID and then invoke the method on it).
>
> That being the case, I think we should just keep the class methods.
> ________________________________________
> From: Will Stevens <wi...@gmail.com>
> Sent: Sunday, May 1, 2016 12:15 PM
> To: dev@cloudstack.apache.org
> Subject: Re: Python Question (with regards to Marvin)
>
> Ya. Let's see how prevalent the class method is to start with and we will
> cross that bridge after.
>> On May 1, 2016 2:07 PM, "Tutkowski, Mike" <Mi...@netapp.com> wrote:
>>
>> 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 <wi...@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" <Mi...@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 <Mi...@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 <wi...@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" <Mi...@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 <williamstevens@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.Tutkowski@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 <wi...@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.Tutkowski@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 <
>>> williamstevens@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.Tutkowski@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
>>

Re: Python Question (with regards to Marvin)

Posted by "Tutkowski, Mike" <Mi...@netapp.com>.
"A bunch of UI scripts use those class methods (I didn't see us trying to use the instance methods anywhere)."

I meant that a bunch of test scripts use those methods (not UI scripts).

> On May 1, 2016, at 5:24 PM, Tutkowski, Mike <Mi...@netapp.com> wrote:
> 
> So, the problem exists with both enableMaintenance and cancelMaintenance for hosts and with enableMaintenance for storage (not with cancelMaintenance for storage).
> 
> A bunch of UI scripts use those class methods (I didn't see us trying to use the instance methods anywhere).
> 
> I believe those class methods exist because the test scripts already have the UUIDs of the host or storage and those class methods provide a faster means of performing the action in question (when compared to having to retrieve a host or storage object from the applicable UUID and then invoke the method on it).
> 
> That being the case, I think we should just keep the class methods.
> ________________________________________
> From: Will Stevens <wi...@gmail.com>
> Sent: Sunday, May 1, 2016 12:15 PM
> To: dev@cloudstack.apache.org
> Subject: Re: Python Question (with regards to Marvin)
> 
> Ya. Let's see how prevalent the class method is to start with and we will
> cross that bridge after.
>> On May 1, 2016 2:07 PM, "Tutkowski, Mike" <Mi...@netapp.com> wrote:
>> 
>> 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 <wi...@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" <Mi...@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 <Mi...@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 <wi...@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" <Mi...@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 <williamstevens@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.Tutkowski@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 <wi...@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.Tutkowski@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 <
>>> williamstevens@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.Tutkowski@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
>> 

Re: Python Question (with regards to Marvin)

Posted by "Tutkowski, Mike" <Mi...@netapp.com>.
So, the problem exists with both enableMaintenance and cancelMaintenance for hosts and with enableMaintenance for storage (not with cancelMaintenance for storage).

A bunch of UI scripts use those class methods (I didn't see us trying to use the instance methods anywhere).

I believe those class methods exist because the test scripts already have the UUIDs of the host or storage and those class methods provide a faster means of performing the action in question (when compared to having to retrieve a host or storage object from the applicable UUID and then invoke the method on it).

That being the case, I think we should just keep the class methods.
________________________________________
From: Will Stevens <wi...@gmail.com>
Sent: Sunday, May 1, 2016 12:15 PM
To: dev@cloudstack.apache.org
Subject: Re: Python Question (with regards to Marvin)

Ya. Let's see how prevalent the class method is to start with and we will
cross that bridge after.
On May 1, 2016 2:07 PM, "Tutkowski, Mike" <Mi...@netapp.com> wrote:

> 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 <wi...@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" <Mi...@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 <Mi...@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 <wi...@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" <Mi...@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 <williamstevens@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.Tutkowski@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 <wi...@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.Tutkowski@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 <
> > williamstevens@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.Tutkowski@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
> > >>
> >
>

Re: Python Question (with regards to Marvin)

Posted by Will Stevens <wi...@gmail.com>.
Ya. Let's see how prevalent the class method is to start with and we will
cross that bridge after.
On May 1, 2016 2:07 PM, "Tutkowski, Mike" <Mi...@netapp.com> wrote:

> 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 <wi...@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" <Mi...@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 <Mi...@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 <wi...@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" <Mi...@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 <williamstevens@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.Tutkowski@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 <wi...@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.Tutkowski@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 <
> > williamstevens@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.Tutkowski@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
> > >>
> >
>

Re: Python Question (with regards to Marvin)

Posted by "Tutkowski, Mike" <Mi...@netapp.com>.
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 <wi...@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" <Mi...@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 <Mi...@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 <wi...@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" <Mi...@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 <wi...@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" <Mi...@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 <wi...@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.Tutkowski@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 <
> williamstevens@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.Tutkowski@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
> >>
>

Re: Python Question (with regards to Marvin)

Posted by Will Stevens <wi...@gmail.com>.
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" <Mi...@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 <Mi...@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 <wi...@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" <Mi...@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 <wi...@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" <Mi...@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 <wi...@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.Tutkowski@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 <
> williamstevens@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.Tutkowski@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
> >>
>

Re: Python Question (with regards to Marvin)

Posted by "Tutkowski, Mike" <Mi...@netapp.com>.
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 <Mi...@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 <wi...@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" <Mi...@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 <wi...@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" <Mi...@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 <wi...@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" <Mi...@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 <wi...@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.Tutkowski@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
>>

Re: Python Question (with regards to Marvin)

Posted by "Tutkowski, Mike" <Mi...@netapp.com>.
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 <wi...@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" <Mi...@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 <wi...@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" <Mi...@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 <wi...@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" <Mi...@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 <wi...@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.Tutkowski@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
>> 

Re: Python Question (with regards to Marvin)

Posted by Will Stevens <wi...@gmail.com>.
Yep. Looking like there is a bug in that file. Thanks for testing. :)
On May 1, 2016 1:40 AM, "Tutkowski, Mike" <Mi...@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 <wi...@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" <Mi...@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 <wi...@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" <Mi...@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 <wi...@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.Tutkowski@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
> >>>
>

Re: Python Question (with regards to Marvin)

Posted by "Tutkowski, Mike" <Mi...@netapp.com>.
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 <wi...@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" <Mi...@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 <wi...@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" <Mi...@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 <wi...@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" <Mi...@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
>>>

Re: Python Question (with regards to Marvin)

Posted by "Tutkowski, Mike" <Mi...@netapp.com>.
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 <wi...@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" <Mi...@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 <wi...@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" <Mi...@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 <wi...@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" <Mi...@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
>>> 

Re: Python Question (with regards to Marvin)

Posted by Will Stevens <wi...@gmail.com>.
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" <Mi...@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 <wi...@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" <Mi...@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 <wi...@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" <Mi...@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
> > >>
> > >>
> > >>
> >