[ https://issues.apache.org/jira/browse/CLOUDSTACK-9373?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15278615#comment-15278615 ]
ASF GitHub Bot commented on CLOUDSTACK-9373: -------------------------------------------- Github user swill commented on the pull request: https://github.com/apache/cloudstack/pull/1528#issuecomment-218244511 ### CI RESULTS ``` Tests Run: 94 Skipped: 0 Failed: 3 Errors: 0 Duration: 11h 00m 30s ``` **Summary of the problem(s):** ``` FAIL: Test create, assign, remove of an Internal LB with roundrobin http traffic to 3 vm's in a Single VPC ---------------------------------------------------------------------- Traceback (most recent call last): File "/data/git/cs1/cloudstack/test/integration/smoke/test_internal_lb.py", line 599, in test_01_internallb_roundrobin_1VPC_3VM_HTTP_port80 self.execute_internallb_roundrobin_tests(vpc_offering) File "/data/git/cs1/cloudstack/test/integration/smoke/test_internal_lb.py", line 668, in execute_internallb_roundrobin_tests self.setup_http_daemon(vm) File "/data/git/cs1/cloudstack/test/integration/smoke/test_internal_lb.py", line 519, in setup_http_daemon self.fail("Failed to ssh into vm: %s due to %s" % (vm, e)) AssertionError: Failed to ssh into vm: <marvin.lib.base.VirtualMachine instance at 0x3724ab8> due to not all arguments converted during string formatting ---------------------------------------------------------------------- Additional details in: /tmp/MarvinLogs/test_internal_lb_5LJ82V/results.txt ``` ``` FAIL: Test redundant router internals ---------------------------------------------------------------------- Traceback (most recent call last): File "/data/git/cs1/cloudstack/test/integration/smoke/test_routers_network_ops.py", line 290, in test_01_RVR_Network_FW_PF_SSH_default_routes_egress_true "Attempt to retrieve google.com index page should be successful!" AssertionError: Attempt to retrieve google.com index page should be successful! ---------------------------------------------------------------------- Additional details in: /tmp/MarvinLogs/test_network_63OJF5/results.txt ``` ``` FAIL: Test create, assign, remove of an Internal LB with roundrobin http traffic to 3 vm's in a Single VPC ---------------------------------------------------------------------- Traceback (most recent call last): File "/data/git/cs1/cloudstack/test/integration/smoke/test_internal_lb.py", line 599, in test_01_internallb_roundrobin_1VPC_3VM_HTTP_port80 self.execute_internallb_roundrobin_tests(vpc_offering) File "/data/git/cs1/cloudstack/test/integration/smoke/test_internal_lb.py", line 668, in execute_internallb_roundrobin_tests self.setup_http_daemon(vm) File "/data/git/cs1/cloudstack/test/integration/smoke/test_internal_lb.py", line 519, in setup_http_daemon self.fail("Failed to ssh into vm: %s due to %s" % (vm, e)) AssertionError: Failed to ssh into vm: <marvin.lib.base.VirtualMachine instance at 0x225b1b8> due to not all arguments converted during string formatting ---------------------------------------------------------------------- Additional details in: /tmp/MarvinLogs/test_network_63OJF5/results.txt ``` **Associated Uploads** **`/tmp/MarvinLogs/DeployDataCenter__May_10_2016_07_06_13_VJQ534:`** * [dc_entries.obj](https://objects-east.cloud.ca/v1/e465abe2f9ae4478b9fff416eab61bd9/PR1528/tmp/MarvinLogs/DeployDataCenter__May_10_2016_07_06_13_VJQ534/dc_entries.obj) * [failed_plus_exceptions.txt](https://objects-east.cloud.ca/v1/e465abe2f9ae4478b9fff416eab61bd9/PR1528/tmp/MarvinLogs/DeployDataCenter__May_10_2016_07_06_13_VJQ534/failed_plus_exceptions.txt) * [runinfo.txt](https://objects-east.cloud.ca/v1/e465abe2f9ae4478b9fff416eab61bd9/PR1528/tmp/MarvinLogs/DeployDataCenter__May_10_2016_07_06_13_VJQ534/runinfo.txt) **`/tmp/MarvinLogs/test_internal_lb_5LJ82V:`** * [failed_plus_exceptions.txt](https://objects-east.cloud.ca/v1/e465abe2f9ae4478b9fff416eab61bd9/PR1528/tmp/MarvinLogs/test_internal_lb_5LJ82V/failed_plus_exceptions.txt) * [results.txt](https://objects-east.cloud.ca/v1/e465abe2f9ae4478b9fff416eab61bd9/PR1528/tmp/MarvinLogs/test_internal_lb_5LJ82V/results.txt) * [runinfo.txt](https://objects-east.cloud.ca/v1/e465abe2f9ae4478b9fff416eab61bd9/PR1528/tmp/MarvinLogs/test_internal_lb_5LJ82V/runinfo.txt) **`/tmp/MarvinLogs/test_network_63OJF5:`** * [failed_plus_exceptions.txt](https://objects-east.cloud.ca/v1/e465abe2f9ae4478b9fff416eab61bd9/PR1528/tmp/MarvinLogs/test_network_63OJF5/failed_plus_exceptions.txt) * [results.txt](https://objects-east.cloud.ca/v1/e465abe2f9ae4478b9fff416eab61bd9/PR1528/tmp/MarvinLogs/test_network_63OJF5/results.txt) * [runinfo.txt](https://objects-east.cloud.ca/v1/e465abe2f9ae4478b9fff416eab61bd9/PR1528/tmp/MarvinLogs/test_network_63OJF5/runinfo.txt) **`/tmp/MarvinLogs/test_vpc_routers_GY7WB8:`** * [failed_plus_exceptions.txt](https://objects-east.cloud.ca/v1/e465abe2f9ae4478b9fff416eab61bd9/PR1528/tmp/MarvinLogs/test_vpc_routers_GY7WB8/failed_plus_exceptions.txt) * [results.txt](https://objects-east.cloud.ca/v1/e465abe2f9ae4478b9fff416eab61bd9/PR1528/tmp/MarvinLogs/test_vpc_routers_GY7WB8/results.txt) * [runinfo.txt](https://objects-east.cloud.ca/v1/e465abe2f9ae4478b9fff416eab61bd9/PR1528/tmp/MarvinLogs/test_vpc_routers_GY7WB8/runinfo.txt) Uploads will be available until `2016-07-10 02:00:00 +0200 CEST` *Comment created by [`upr comment`](https://github.com/cloudops/upr).* > Marvin issue with class and instance methods named the same > ----------------------------------------------------------- > > Key: CLOUDSTACK-9373 > URL: https://issues.apache.org/jira/browse/CLOUDSTACK-9373 > Project: CloudStack > Issue Type: Bug > Security Level: Public(Anyone can view this level - this is the > default.) > Components: marvin > Affects Versions: 4.9.0 > Environment: N/A > Reporter: Mike Tutkowski > Assignee: Mike Tutkowski > Fix For: 4.9.0 > > > We have some methods in base.py that are named the same. > Per my findings below, Python methods in a class should not be named the same > even if one is a class method and the other is an instance method. > The solution discussed on dev@ is to remove the instance versions (reason > listed below). > From a chain of e-mails on dev@: > Python Question (with regards to Marvin) > Mark as unread > Tutkowski, Mike > Sun 5/1/2016 7:16 PM > Sent Items; Inbox > "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). > REPLYREPLY ALLFORWARD > Mark as unread > Tutkowski, Mike > Sun 5/1/2016 5:24 PM > Sent Items; Inbox > To: > d...@cloudstack.apache.org; > 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 <williamstev...@gmail.com> > Sent: Sunday, May 1, 2016 12:15 PM > To: d...@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" <mike.tutkow...@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 <williamstev...@gmail.com> > > Sent: Sunday, May 1, 2016 12:03 PM > > To: d...@cloudstack.apache.org > > Subject: Re: Python Question (with regards to Marvin) > > > > It will be easy to grep if there class methods, so we should start there. > > If not, then I agree that an instance method is probably the best way to > > go. > > On May 1, 2016 12:41 PM, "Tutkowski, Mike" <mike.tutkow...@netapp.com> > > wrote: > > > > > However, from a design standpoint, I prefer the instance method here as > > it > > > would be nice to ask the object itself to place itself in maintenance > > mode. > > > > > > So, it's really a question of just staying backward compatible (the class > > > method) or a possibly better design (the instance method). > > > ________________________________________ > > > From: Tutkowski, Mike <mike.tutkow...@netapp.com> > > > Sent: Sunday, May 1, 2016 10:18 AM > > > To: d...@cloudstack.apache.org > > > Subject: Re: Python Question (with regards to Marvin) > > > > > > The question then becomes, do we want to keep the instance or the class > > > method? > > > > > > There exists the same problem for at least one other pair of methods. > > > > > > Since the class method is listed second in the file currently, it is the > > > only one of the two that can be utilized. That being the case, we might > > > just want to keep the class method and remove the instance method. > > > > > > > On May 1, 2016, at 5:43 AM, Will Stevens <williamstev...@gmail.com> > > > wrote: > > > > > > > > Yep. Looking like there is a bug in that file. Thanks for testing. :) > > > >> On May 1, 2016 1:40 AM, "Tutkowski, Mike" <mike.tutkow...@netapp.com> > > > wrote: > > > >> > > > >> Here are my tests (run from http://ideone.com/). > > > >> > > > >> The short story is that having multiple methods with the same name > > (even > > > >> if one is an instance method and one is a class method) should > > probably > > > not > > > >> be done. > > > >> > > > >> If you try to invoke the instance method (ex. test.run()), the last > > > method > > > >> by that name in the source file is invoked (which could be the class > > > >> method). If the number of parameters don't match, that's an error. > > > >> > > > >> If you try to invoke the class method (ex. Test.run()), the last > > method > > > by > > > >> that name in the source file is invoked. If this is not a class method > > > or > > > >> if the number of parameters don't match, that's an error. > > > >> > > > >> class Test: > > > >> @classmethod > > > >> def run(cls): > > > >> print "class hi" > > > >> > > > >> def run(self): > > > >> print "instance hi" > > > >> > > > >> test = Test() > > > >> > > > >> test.run() > > > >> > > > >> What gets printed: > > > >> instance hi > > > >> > > > >> class Test: > > > >> def run(self): > > > >> print "instance hi" > > > >> > > > >> @classmethod > > > >> def run(cls): > > > >> print "class hi" > > > >> > > > >> test = Test() > > > >> > > > >> test.run() > > > >> > > > >> What gets printed: > > > >> class hi > > > >> > > > >> class Test: > > > >> @classmethod > > > >> def run(cls): > > > >> print "class hi" > > > >> > > > >> def run(self): > > > >> print "instance hi" > > > >> > > > >> # test = Test() > > > >> > > > >> Test.run() > > > >> > > > >> Runtime error > > > >> > > > >> class Test: > > > >> @classmethod > > > >> def run(cls): > > > >> print "class hi" > > > >> > > > >> # test = Test() > > > >> > > > >> Test.run() > > > >> > > > >> What gets printed: > > > >> class hi > > > >> > > > >> class Test: > > > >> def run(self): > > > >> print "instance hi" > > > >> > > > >> @classmethod > > > >> def run(cls): > > > >> print "class hi" > > > >> > > > >> # test = Test() > > > >> > > > >> Test.run() > > > >> > > > >> What gets printed: > > > >> class hi > > > >> > > > >> class Test: > > > >> @classmethod > > > >> def run(cls): > > > >> print "class hi" > > > >> > > > >> # test = Test() > > > >> > > > >> Test.run() > > > >> > > > >> What gets printed: > > > >> class hi > > > >> ________________________________________ > > > >> From: Tutkowski, Mike > > > >> Sent: Saturday, April 30, 2016 6:58 PM > > > >> To: d...@cloudstack.apache.org > > > >> Subject: Re: Python Question (with regards to Marvin) > > > >> > > > >> I can play around with it later tonight. I'm not home at the moment. > > > >> > > > >> When I did invoke it as Test.run(), it invoked the class method (the > > > class > > > >> method was listed after the instance method for that test, so I wasn't > > > >> surprised that the class method did, in fact, get executed there). > > > >> > > > >> What I did not try was to list the class method first, then list the > > > >> instance method, and then try to invoke the class method. > > > >> > > > >> As mentioned in my prior e-mail, when I did try to invoke the instance > > > >> version of run, it was only successful if the instance version was the > > > >> second one declared in the file. If the class method was declared > > > second, > > > >> then it was invoked even when I was trying to invoke the instance one. > > > >> > > > >>>> On Apr 30, 2016, at 6:06 PM, Will Stevens <williamstev...@gmail.com > > > > > > >>> wrote: > > > >>> > > > >>> That's strange. That means the @classmethod decorator is not working. > > > You > > > >>> should have gotten the instance method in both cases. > > > >>> > > > >>> What if you don't instantiate Test and only do the following. > > > >>> > > > >>> Test.run() > > > >>> > > > >>> In both cases. > > > >>> On Apr 30, 2016 6:04 PM, "Tutkowski, Mike" < > > mike.tutkow...@netapp.com> > > > >>> wrote: > > > >>> > > > >>>> I ran this with an online Python tool and it calls the class method: > > > >>>> > > > >>>> 1 class Test: > > > >>>> 2 def run(self): > > > >>>> 3 print 'instance hi' > > > >>>> 4 > > > >>>> 5 @classmethod > > > >>>> 6 def run(cls): > > > >>>> 7 print 'class hi' > > > >>>> 8 > > > >>>> 9 test = Test() > > > >>>> 10 > > > >>>> 11 test.run() > > > >>>> > > > >>>> If I reverse the order of the methods, the instance method is > > invoked: > > > >>>> > > > >>>> 1 class Test: > > > >>>> 2 @classmethod > > > >>>> 3 def run(cls): > > > >>>> 4 print 'class hi' > > > >>>> 5 > > > >>>> 6 def run(self): > > > >>>> 7 print 'instance hi' > > > >>>> 8 > > > >>>> 9 test = Test() > > > >>>> 10 > > > >>>> 11 test.run() > > > >>>> > > > >>>> As I suspected, I think this means we have a problem in base.py. > > > >>>> ________________________________________ > > > >>>> From: Will Stevens <williamstev...@gmail.com> > > > >>>> Sent: Saturday, April 30, 2016 1:46 PM > > > >>>> To: d...@cloudstack.apache.org > > > >>>> Subject: Re: Python Question (with regards to Marvin) > > > >>>> > > > >>>> I am on my phone so I have not been able to research this for you. I > > > >> think > > > >>>> you are right for the most part. Instead of multiple methods, > > python > > > >> kind > > > >>>> of fakes overloading by being to have named function arguments which > > > can > > > >>>> have default values, so you can call the method with a dynamic > > number > > > of > > > >>>> arguments making it appear like you are overloading, but you are > > > >> actually > > > >>>> calling the same function. > > > >>>> > > > >>>> I think in this case the two methods are actually in different > > scopes > > > >> (even > > > >>>> though they are next to each other). The decorator actually wraps > > the > > > >>>> method, so I believe in the actual runtime the to methods are in > > > >> different > > > >>>> scopes. > > > >>>> > > > >>>> I would have to look into this more to know for sure. I am taking a > > > few > > > >>>> minute break from building garden boxes right now. :) > > > >>>> On Apr 30, 2016 3:31 PM, "Tutkowski, Mike" < > > mike.tutkow...@netapp.com > > > > > Mark as unread > Will Stevens <williamstev...@gmail.com> > Sun 5/1/2016 12:15 PM > Inbox > 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" <mike.tutkow...@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 <williamstev...@gmail.com> > > Sent: Sunday, May 1, 2016 12:03 PM > > To: d...@cloudstack.apache.org > > Subject: Re: Python Question (with regards to Marvin) > > > > It will be easy to grep if there class methods, so we should start there. > > If not, then I agree that an instance method is probably the best way to > > go. > > On May 1, 2016 12:41 PM, "Tutkowski, Mike" <mike.tutkow...@netapp.com> > > wrote: > > > > > However, from a design standpoint, I prefer the instance method here as > > it > > > would be nice to ask the object itself to place itself in maintenance > > mode. > > > > > > So, it's really a question of just staying backward compatible (the class > > > method) or a possibly better design (the instance method). > > > ________________________________________ > > > From: Tutkowski, Mike <mike.tutkow...@netapp.com> > > > Sent: Sunday, May 1, 2016 10:18 AM > > > To: d...@cloudstack.apache.org > > > Subject: Re: Python Question (with regards to Marvin) > > > > > > The question then becomes, do we want to keep the instance or the class > > > method? > > > > > > There exists the same problem for at least one other pair of methods. > > > > > > Since the class method is listed second in the file currently, it is the > > > only one of the two that can be utilized. That being the case, we might > > > just want to keep the class method and remove the instance method. > > > > > > > On May 1, 2016, at 5:43 AM, Will Stevens <williamstev...@gmail.com> > > > wrote: > > > > > > > > Yep. Looking like there is a bug in that file. Thanks for testing. :) > > > >> On May 1, 2016 1:40 AM, "Tutkowski, Mike" <mike.tutkow...@netapp.com> > > > wrote: > > > >> > > > >> Here are my tests (run from http://ideone.com/). > > > >> > > > >> The short story is that having multiple methods with the same name > > (even > > > >> if one is an instance method and one is a class method) should > > probably > > > not > > > >> be done. > > > >> > > > >> If you try to invoke the instance method (ex. test.run()), the last > > > method > > > >> by that name in the source file is invoked (which could be the class > > > >> method). If the number of parameters don't match, that's an error. > > > >> > > > >> If you try to invoke the class method (ex. Test.run()), the last > > method > > > by > > > >> that name in the source file is invoked. If this is not a class method > > > or > > > >> if the number of parameters don't match, that's an error. > > > >> > > > >> class Test: > > > >> @classmethod > > > >> def run(cls): > > > >> print "class hi" > > > >> > > > >> def run(self): > > > >> print "instance hi" > > > >> > > > >> test = Test() > > > >> > > > >> test.run() > > > >> > > > >> What gets printed: > > > >> instance hi > > > >> > > > >> class Test: > > > >> def run(self): > > > >> print "instance hi" > > > >> > > > >> @classmethod > > > >> def run(cls): > > > >> print "class hi" > > > >> > > > >> test = Test() > > > >> > > > >> test.run() > > > >> > > > >> What gets printed: > > > >> class hi > > > >> > > > >> class Test: > > > >> @classmethod > > > >> def run(cls): > > > >> print "class hi" > > > >> > > > >> def run(self): > > > >> print "instance hi" > > > >> > > > >> # test = Test() > > > >> > > > >> Test.run() > > > >> > > > >> Runtime error > > > >> > > > >> class Test: > > > >> @classmethod > > > >> def run(cls): > > > >> print "class hi" > > > >> > > > >> # test = Test() > > > >> > > > >> Test.run() > > > >> > > > >> What gets printed: > > > >> class hi > > > >> > > > >> class Test: > > > >> def run(self): > > > >> print "instance hi" > > > >> > > > >> @classmethod > > > >> def run(cls): > > > >> print "class hi" > > > >> > > > >> # test = Test() > > > >> > > > >> Test.run() > > > >> > > > >> What gets printed: > > > >> class hi > > > >> > > > >> class Test: > > > >> @classmethod > > > >> def run(cls): > > > >> print "class hi" > > > >> > > > >> # test = Test() > > > >> > > > >> Test.run() > > > >> > > > >> What gets printed: > > > >> class hi > > > >> ________________________________________ > > > >> From: Tutkowski, Mike > > > >> Sent: Saturday, April 30, 2016 6:58 PM > > > >> To: d...@cloudstack.apache.org > > > >> Subject: Re: Python Question (with regards to Marvin) > > > >> > > > >> I can play around with it later tonight. I'm not home at the moment. > > > >> > > > >> When I did invoke it as Test.run(), it invoked the class method (the > > > class > > > >> method was listed after the instance method for that test, so I wasn't > > > >> surprised that the class method did, in fact, get executed there). > > > >> > > > >> What I did not try was to list the class method first, then list the > > > >> instance method, and then try to invoke the class method. > > > >> > > > >> As mentioned in my prior e-mail, when I did try to invoke the instance > > > >> version of run, it was only successful if the instance version was the > > > >> second one declared in the file. If the class method was declared > > > second, > > > >> then it was invoked even when I was trying to invoke the instance one. > > > >> > > > >>>> On Apr 30, 2016, at 6:06 PM, Will Stevens <williamstev...@gmail.com > > > > > > >>> wrote: > > > >>> > > > >>> That's strange. That means the @classmethod decorator is not working. > > > You > > > >>> should have gotten the instance method in both cases. > > > >>> > > > >>> What if you don't instantiate Test and only do the following. > > > >>> > > > >>> Test.run() > > > >>> > > > >>> In both cases. > > > >>> On Apr 30, 2016 6:04 PM, "Tutkowski, Mike" < > > mike.tutkow...@netapp.com> > > > >>> wrote: > > > >>> > > > >>>> I ran this with an online Python tool and it calls the class method: > > > >>>> > > > >>>> 1 class Test: > > > >>>> 2 def run(self): > > > >>>> 3 print 'instance hi' > > > >>>> 4 > > > >>>> 5 @classmethod > > > >>>> 6 def run(cls): > > > >>>> 7 print 'class hi' > > > >>>> 8 > > > >>>> 9 test = Test() > > > >>>> 10 > > > >>>> 11 test.run() > > > >>>> > > > >>>> If I reverse the order of the methods, the instance method is > > invoked: > > > >>>> > > > >>>> 1 class Test: > > > >>>> 2 @classmethod > > > >>>> 3 def run(cls): > > > >>>> 4 print 'class hi' > > > >>>> 5 > > > >>>> 6 def run(self): > > > >>>> 7 print 'instance hi' > > > >>>> 8 > > > >>>> 9 test = Test() > > > >>>> 10 > > > >>>> 11 test.run() > > > >>>> > > > >>>> As I suspected, I think this means we have a problem in base.py. > > > >>>> ________________________________________ > > > >>>> From: Will Stevens <williamstev...@gmail.com> > > > >>>> Sent: Saturday, April 30, 2016 1:46 PM > > > >>>> To: d...@cloudstack.apache.org > > > >>>> Subject: Re: Python Question (with regards to Marvin) > > > >>>> > > > >>>> I am on my phone so I have not been able to research this for you. I > > > >> think > > > >>>> you are right for the most part. Instead of multiple methods, > > python > > > >> kind > > > >>>> of fakes overloading by being to have named function arguments which > > > can > > > >>>> have default values, so you can call the method with a dynamic > > number > > > of > > > >>>> arguments making it appear like you are overloading, but you are > > > >> actually > > > >>>> calling the same function. > > > >>>> > > > >>>> I think in this case the two methods are actually in different > > scopes > > > >> (even > > > >>>> though they are next to each other). The decorator actually wraps > > the > > > >>>> method, so I believe in the actual runtime the to methods are in > > > >> different > > > >>>> scopes. > > > >>>> > > > >>>> I would have to look into this more to know for sure. I am taking a > > > few > > > >>>> minute break from building garden boxes right now. :) > > > >>>> On Apr 30, 2016 3:31 PM, "Tutkowski, Mike" < > > mike.tutkow...@netapp.com > > > > > Mark as unread > Tutkowski, Mike > Sun 5/1/2016 12:06 PM > Sent Items; Inbox > I was just "concerned" that those who have their own Marvin tests that are > not checked in might be broken if I don't keep the class method. > ________________________________________ > From: Will Stevens <williamstev...@gmail.com> > Sent: Sunday, May 1, 2016 12:03 PM > To: d...@cloudstack.apache.org > Subject: Re: Python Question (with regards to Marvin) > It will be easy to grep if there class methods, so we should start there. > If not, then I agree that an instance method is probably the best way to > go. > On May 1, 2016 12:41 PM, "Tutkowski, Mike" <mike.tutkow...@netapp.com> > wrote: > > However, from a design standpoint, I prefer the instance method here as it > > would be nice to ask the object itself to place itself in maintenance mode. > > > > So, it's really a question of just staying backward compatible (the class > > method) or a possibly better design (the instance method). > > ________________________________________ > > From: Tutkowski, Mike <mike.tutkow...@netapp.com> > > Sent: Sunday, May 1, 2016 10:18 AM > > To: d...@cloudstack.apache.org > > Subject: Re: Python Question (with regards to Marvin) > > > > The question then becomes, do we want to keep the instance or the class > > method? > > > > There exists the same problem for at least one other pair of methods. > > > > Since the class method is listed second in the file currently, it is the > > only one of the two that can be utilized. That being the case, we might > > just want to keep the class method and remove the instance method. > > > > > On May 1, 2016, at 5:43 AM, Will Stevens <williamstev...@gmail.com> > > wrote: > > > > > > Yep. Looking like there is a bug in that file. Thanks for testing. :) > > >> On May 1, 2016 1:40 AM, "Tutkowski, Mike" <mike.tutkow...@netapp.com> > > wrote: > > >> > > >> Here are my tests (run from http://ideone.com/). > > >> > > >> The short story is that having multiple methods with the same name (even > > >> if one is an instance method and one is a class method) should probably > > not > > >> be done. > > >> > > >> If you try to invoke the instance method (ex. test.run()), the last > > method > > >> by that name in the source file is invoked (which could be the class > > >> method). If the number of parameters don't match, that's an error. > > >> > > >> If you try to invoke the class method (ex. Test.run()), the last method > > by > > >> that name in the source file is invoked. If this is not a class method > > or > > >> if the number of parameters don't match, that's an error. > > >> > > >> class Test: > > >> @classmethod > > >> def run(cls): > > >> print "class hi" > > >> > > >> def run(self): > > >> print "instance hi" > > >> > > >> test = Test() > > >> > > >> test.run() > > >> > > >> What gets printed: > > >> instance hi > > >> > > >> class Test: > > >> def run(self): > > >> print "instance hi" > > >> > > >> @classmethod > > >> def run(cls): > > >> print "class hi" > > >> > > >> test = Test() > > >> > > >> test.run() > > >> > > >> What gets printed: > > >> class hi > > >> > > >> class Test: > > >> @classmethod > > >> def run(cls): > > >> print "class hi" > > >> > > >> def run(self): > > >> print "instance hi" > > >> > > >> # test = Test() > > >> > > >> Test.run() > > >> > > >> Runtime error > > >> > > >> class Test: > > >> @classmethod > > >> def run(cls): > > >> print "class hi" > > >> > > >> # test = Test() > > >> > > >> Test.run() > > >> > > >> What gets printed: > > >> class hi > > >> > > >> class Test: > > >> def run(self): > > >> print "instance hi" > > >> > > >> @classmethod > > >> def run(cls): > > >> print "class hi" > > >> > > >> # test = Test() > > >> > > >> Test.run() > > >> > > >> What gets printed: > > >> class hi > > >> > > >> class Test: > > >> @classmethod > > >> def run(cls): > > >> print "class hi" > > >> > > >> # test = Test() > > >> > > >> Test.run() > > >> > > >> What gets printed: > > >> class hi > > >> ________________________________________ > > >> From: Tutkowski, Mike > > >> Sent: Saturday, April 30, 2016 6:58 PM > > >> To: d...@cloudstack.apache.org > > >> Subject: Re: Python Question (with regards to Marvin) > > >> > > >> I can play around with it later tonight. I'm not home at the moment. > > >> > > >> When I did invoke it as Test.run(), it invoked the class method (the > > class > > >> method was listed after the instance method for that test, so I wasn't > > >> surprised that the class method did, in fact, get executed there). > > >> > > >> What I did not try was to list the class method first, then list the > > >> instance method, and then try to invoke the class method. > > >> > > >> As mentioned in my prior e-mail, when I did try to invoke the instance > > >> version of run, it was only successful if the instance version was the > > >> second one declared in the file. If the class method was declared > > second, > > >> then it was invoked even when I was trying to invoke the instance one. > > >> > > >>>> On Apr 30, 2016, at 6:06 PM, Will Stevens <williamstev...@gmail.com> > > >>> wrote: > > >>> > > >>> That's strange. That means the @classmethod decorator is not working. > > You > > >>> should have gotten the instance method in both cases. > > >>> > > >>> What if you don't instantiate Test and only do the following. > > >>> > > >>> Test.run() > > >>> > > >>> In both cases. > > >>> On Apr 30, 2016 6:04 PM, "Tutkowski, Mike" <mike.tutkow...@netapp.com> > > >>> wrote: > > >>> > > >>>> I ran this with an online Python tool and it calls the class method: > > >>>> > > >>>> 1 class Test: > > >>>> 2 def run(self): > > >>>> 3 print 'instance hi' > > >>>> 4 > > >>>> 5 @classmethod > > >>>> 6 def run(cls): > > >>>> 7 print 'class hi' > > >>>> 8 > > >>>> 9 test = Test() > > >>>> 10 > > >>>> 11 test.run() > > >>>> > > >>>> If I reverse the order of the methods, the instance method is invoked: > > >>>> > > >>>> 1 class Test: > > >>>> 2 @classmethod > > >>>> 3 def run(cls): > > >>>> 4 print 'class hi' > > >>>> 5 > > >>>> 6 def run(self): > > >>>> 7 print 'instance hi' > > >>>> 8 > > >>>> 9 test = Test() > > >>>> 10 > > >>>> 11 test.run() > > >>>> > > >>>> As I suspected, I think this means we have a problem in base.py. > > >>>> ________________________________________ > > >>>> From: Will Stevens <williamstev...@gmail.com> > > >>>> Sent: Saturday, April 30, 2016 1:46 PM > > >>>> To: d...@cloudstack.apache.org > > >>>> Subject: Re: Python Question (with regards to Marvin) > > >>>> > > >>>> I am on my phone so I have not been able to research this for you. I > > >> think > > >>>> you are right for the most part. Instead of multiple methods, python > > >> kind > > >>>> of fakes overloading by being to have named function arguments which > > can > > >>>> have default values, so you can call the method with a dynamic number > > of > > >>>> arguments making it appear like you are overloading, but you are > > >> actually > > >>>> calling the same function. > > >>>> > > >>>> I think in this case the two methods are actually in different scopes > > >> (even > > >>>> though they are next to each other). The decorator actually wraps the > > >>>> method, so I believe in the actual runtime the to methods are in > > >> different > > >>>> scopes. > > >>>> > > >>>> I would have to look into this more to know for sure. I am taking a > > few > > >>>> minute break from building garden boxes right now. :) > > >>>> On Apr 30, 2016 3:31 PM, "Tutkowski, Mike" <mike.tutkow...@netapp.com > > > > > >>>> wrote: > > >>>> > > >>>>> Will - You can override a method in Python, but can you overload it? > > >> > > http://stackoverflow.com/questions/10202938/how-do-i-use-method-overloading-in-python > > >>>>> > > >>>>>>> On Apr 30, 2016, at 6:23 AM, Will Stevens < > > williamstev...@gmail.com> > > >>>>>> wrote: > > >>>>>> > > >>>>>> Here is a pretty good explanation. > > >> > > http://stackoverflow.com/questions/136097/what-is-the-difference-between-staticmethod-and-classmethod-in-python > > >>>>>> > > >>>>>> I am guessing that both exist because the function is called both > > with > > >>>> a > > >>>>>> host instance and with the class itself. > > >>>>>> > > >>>>>> Class instance example: `h.enableMaintenance(client)` > > >>>>>> > > >>>>>> Class example: `Host.enableMaintenance(client, 1)` > > >>>>>> > > >>>>>> In both cases the first parameter is implicitly `h` and `Host` > > >>>>>> respectively. > > >>>>>> > > >>>>>> I am not sure why we need both (because I am not familiar with how > > >> this > > >>>>>> code is called), but method overloading is definitely valid in > > python. > > >>>>>> > > >>>>>> On Apr 30, 2016 1:08 AM, "Tutkowski, Mike" < > > mike.tutkow...@netapp.com > > >>> > Mark as unread > Will Stevens <williamstev...@gmail.com> > Sun 5/1/2016 12:04 PM > Inbox > It will be easy to grep if there class methods, so we should start there. > If not, then I agree that an instance method is probably the best way to > go. > On May 1, 2016 12:41 PM, "Tutkowski, Mike" <mike.tutkow...@netapp.com> > wrote: > > However, from a design standpoint, I prefer the instance method here as it > > would be nice to ask the object itself to place itself in maintenance mode. > > > > So, it's really a question of just staying backward compatible (the class > > method) or a possibly better design (the instance method). > > ________________________________________ > > From: Tutkowski, Mike <mike.tutkow...@netapp.com> > > Sent: Sunday, May 1, 2016 10:18 AM > > To: d...@cloudstack.apache.org > > Subject: Re: Python Question (with regards to Marvin) > > > > The question then becomes, do we want to keep the instance or the class > > method? > > > > There exists the same problem for at least one other pair of methods. > > > > Since the class method is listed second in the file currently, it is the > > only one of the two that can be utilized. That being the case, we might > > just want to keep the class method and remove the instance method. > > > > > On May 1, 2016, at 5:43 AM, Will Stevens <williamstev...@gmail.com> > > wrote: > > > > > > Yep. Looking like there is a bug in that file. Thanks for testing. :) > > >> On May 1, 2016 1:40 AM, "Tutkowski, Mike" <mike.tutkow...@netapp.com> > > wrote: > > >> > > >> Here are my tests (run from http://ideone.com/). > > >> > > >> The short story is that having multiple methods with the same name (even > > >> if one is an instance method and one is a class method) should probably > > not > > >> be done. > > >> > > >> If you try to invoke the instance method (ex. test.run()), the last > > method > > >> by that name in the source file is invoked (which could be the class > > >> method). If the number of parameters don't match, that's an error. > > >> > > >> If you try to invoke the class method (ex. Test.run()), the last method > > by > > >> that name in the source file is invoked. If this is not a class method > > or > > >> if the number of parameters don't match, that's an error. > > >> > > >> class Test: > > >> @classmethod > > >> def run(cls): > > >> print "class hi" > > >> > > >> def run(self): > > >> print "instance hi" > > >> > > >> test = Test() > > >> > > >> test.run() > > >> > > >> What gets printed: > > >> instance hi > > >> > > >> class Test: > > >> def run(self): > > >> print "instance hi" > > >> > > >> @classmethod > > >> def run(cls): > > >> print "class hi" > > >> > > >> test = Test() > > >> > > >> test.run() > > >> > > >> What gets printed: > > >> class hi > > >> > > >> class Test: > > >> @classmethod > > >> def run(cls): > > >> print "class hi" > > >> > > >> def run(self): > > >> print "instance hi" > > >> > > >> # test = Test() > > >> > > >> Test.run() > > >> > > >> Runtime error > > >> > > >> class Test: > > >> @classmethod > > >> def run(cls): > > >> print "class hi" > > >> > > >> # test = Test() > > >> > > >> Test.run() > > >> > > >> What gets printed: > > >> class hi > > >> > > >> class Test: > > >> def run(self): > > >> print "instance hi" > > >> > > >> @classmethod > > >> def run(cls): > > >> print "class hi" > > >> > > >> # test = Test() > > >> > > >> Test.run() > > >> > > >> What gets printed: > > >> class hi > > >> > > >> class Test: > > >> @classmethod > > >> def run(cls): > > >> print "class hi" > > >> > > >> # test = Test() > > >> > > >> Test.run() > > >> > > >> What gets printed: > > >> class hi > > >> ________________________________________ > > >> From: Tutkowski, Mike > > >> Sent: Saturday, April 30, 2016 6:58 PM > > >> To: d...@cloudstack.apache.org > > >> Subject: Re: Python Question (with regards to Marvin) > > >> > > >> I can play around with it later tonight. I'm not home at the moment. > > >> > > >> When I did invoke it as Test.run(), it invoked the class method (the > > class > > >> method was listed after the instance method for that test, so I wasn't > > >> surprised that the class method did, in fact, get executed there). > > >> > > >> What I did not try was to list the class method first, then list the > > >> instance method, and then try to invoke the class method. > > >> > > >> As mentioned in my prior e-mail, when I did try to invoke the instance > > >> version of run, it was only successful if the instance version was the > > >> second one declared in the file. If the class method was declared > > second, > > >> then it was invoked even when I was trying to invoke the instance one. > > >> > > >>>> On Apr 30, 2016, at 6:06 PM, Will Stevens <williamstev...@gmail.com> > > >>> wrote: > > >>> > > >>> That's strange. That means the @classmethod decorator is not working. > > You > > >>> should have gotten the instance method in both cases. > > >>> > > >>> What if you don't instantiate Test and only do the following. > > >>> > > >>> Test.run() > > >>> > > >>> In both cases. > > >>> On Apr 30, 2016 6:04 PM, "Tutkowski, Mike" <mike.tutkow...@netapp.com> > > >>> wrote: > > >>> > > >>>> I ran this with an online Python tool and it calls the class method: > > >>>> > > >>>> 1 class Test: > > >>>> 2 def run(self): > > >>>> 3 print 'instance hi' > > >>>> 4 > > >>>> 5 @classmethod > > >>>> 6 def run(cls): > > >>>> 7 print 'class hi' > > >>>> 8 > > >>>> 9 test = Test() > > >>>> 10 > > >>>> 11 test.run() > > >>>> > > >>>> If I reverse the order of the methods, the instance method is invoked: > > >>>> > > >>>> 1 class Test: > > >>>> 2 @classmethod > > >>>> 3 def run(cls): > > >>>> 4 print 'class hi' > > >>>> 5 > > >>>> 6 def run(self): > > >>>> 7 print 'instance hi' > > >>>> 8 > > >>>> 9 test = Test() > > >>>> 10 > > >>>> 11 test.run() > > >>>> > > >>>> As I suspected, I think this means we have a problem in base.py. > > >>>> ________________________________________ > > >>>> From: Will Stevens <williamstev...@gmail.com> > > >>>> Sent: Saturday, April 30, 2016 1:46 PM > > >>>> To: d...@cloudstack.apache.org > > >>>> Subject: Re: Python Question (with regards to Marvin) > > >>>> > > >>>> I am on my phone so I have not been able to research this for you. I > > >> think > > >>>> you are right for the most part. Instead of multiple methods, python > > >> kind > > >>>> of fakes overloading by being to have named function arguments which > > can > > >>>> have default values, so you can call the method with a dynamic number > > of > > >>>> arguments making it appear like you are overloading, but you are > > >> actually > > >>>> calling the same function. > > >>>> > > >>>> I think in this case the two methods are actually in different scopes > > >> (even > > >>>> though they are next to each other). The decorator actually wraps the > > >>>> method, so I believe in the actual runtime the to methods are in > > >> different > > >>>> scopes. > > >>>> > > >>>> I would have to look into this more to know for sure. I am taking a > > few > > >>>> minute break from building garden boxes right now. :) > > >>>> On Apr 30, 2016 3:31 PM, "Tutkowski, Mike" <mike.tutkow...@netapp.com > > > > > >>>> wrote: > > >>>> > > >>>>> Will - You can override a method in Python, but can you overload it? > > >> > > http://stackoverflow.com/questions/10202938/how-do-i-use-method-overloading-in-python > > >>>>> > > >>>>>>> On Apr 30, 2016, at 6:23 AM, Will Stevens < > > williamstev...@gmail.com> > > >>>>>> wrote: > > >>>>>> > > >>>>>> Here is a pretty good explanation. > > >> > > http://stackoverflow.com/questions/136097/what-is-the-difference-between-staticmethod-and-classmethod-in-python > > >>>>>> > > >>>>>> I am guessing that both exist because the function is called both > > with > > >>>> a > > >>>>>> host instance and with the class itself. > > >>>>>> > > >>>>>> Class instance example: `h.enableMaintenance(client)` > > >>>>>> > > >>>>>> Class example: `Host.enableMaintenance(client, 1)` > > >>>>>> > > >>>>>> In both cases the first parameter is implicitly `h` and `Host` > > >>>>>> respectively. > > >>>>>> > > >>>>>> I am not sure why we need both (because I am not familiar with how > > >> this > > >>>>>> code is called), but method overloading is definitely valid in > > python. > > >>>>>> > > >>>>>> On Apr 30, 2016 1:08 AM, "Tutkowski, Mike" < > > mike.tutkow...@netapp.com > > >>> > Mark as unread > Tutkowski, Mike > Sun 5/1/2016 10:41 AM > Sent Items; Inbox > 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). > Mark as unread > Tutkowski, Mike > Sun 5/1/2016 10:18 AM > Sent Items; Inbox > The question then becomes, do we want to keep the instance or the class > method? > There exists the same problem for at least one other pair of methods. > Since the class method is listed second in the file currently, it is the only > one of the two that can be utilized. That being the case, we might just want > to keep the class method and remove the instance method. > > On May 1, 2016, at 5:43 AM, Will Stevens <williamstev...@gmail.com> wrote: > > > > Yep. Looking like there is a bug in that file. Thanks for testing. :) > Mark as unread > Will Stevens <williamstev...@gmail.com> > Sun 5/1/2016 5:43 AM > Inbox > Yep. Looking like there is a bug in that file. Thanks for testing. :) > On May 1, 2016 1:40 AM, "Tutkowski, Mike" <mike.tutkow...@netapp.com> wrote: > > Here are my tests (run from http://ideone.com/). > > > > The short story is that having multiple methods with the same name (even > > if one is an instance method and one is a class method) should probably not > > be done. > > > > If you try to invoke the instance method (ex. test.run()), the last method > > by that name in the source file is invoked (which could be the class > > method). If the number of parameters don't match, that's an error. > > > > If you try to invoke the class method (ex. Test.run()), the last method by > > that name in the source file is invoked. If this is not a class method or > > if the number of parameters don't match, that's an error. > > > > class Test: > > @classmethod > > def run(cls): > > print "class hi" > > > > def run(self): > > print "instance hi" > > > > test = Test() > > > > test.run() > > > > What gets printed: > > instance hi > > > > class Test: > > def run(self): > > print "instance hi" > > > > @classmethod > > def run(cls): > > print "class hi" > > > > test = Test() > > > > test.run() > > > > What gets printed: > > class hi > > > > class Test: > > @classmethod > > def run(cls): > > print "class hi" > > > > def run(self): > > print "instance hi" > > > > # test = Test() > > > > Test.run() > > > > Runtime error > > > > class Test: > > @classmethod > > def run(cls): > > print "class hi" > > > > # test = Test() > > > > Test.run() > > > > What gets printed: > > class hi > > > > class Test: > > def run(self): > > print "instance hi" > > > > @classmethod > > def run(cls): > > print "class hi" > > > > # test = Test() > > > > Test.run() > > > > What gets printed: > > class hi > > > > class Test: > > @classmethod > > def run(cls): > > print "class hi" > > > > # test = Test() > > > > Test.run() > > > > What gets printed: > > class hi > > ________________________________________ > > From: Tutkowski, Mike > > Sent: Saturday, April 30, 2016 6:58 PM > > To: d...@cloudstack.apache.org > > Subject: Re: Python Question (with regards to Marvin) > > > > I can play around with it later tonight. I'm not home at the moment. > > > > When I did invoke it as Test.run(), it invoked the class method (the class > > method was listed after the instance method for that test, so I wasn't > > surprised that the class method did, in fact, get executed there). > > > > What I did not try was to list the class method first, then list the > > instance method, and then try to invoke the class method. > > > > As mentioned in my prior e-mail, when I did try to invoke the instance > > version of run, it was only successful if the instance version was the > > second one declared in the file. If the class method was declared second, > > then it was invoked even when I was trying to invoke the instance one. > > > > > On Apr 30, 2016, at 6:06 PM, Will Stevens <williamstev...@gmail.com> > Mark as unread > Tutkowski, Mike > Sat 4/30/2016 11:40 PM > Sent Items; Inbox > >> 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 > Mark as unread > Tutkowski, Mike > Sat 4/30/2016 6:58 PM > Sent Items; Inbox > I can play around with it later tonight. I'm not home at the moment. > When I did invoke it as Test.run(), it invoked the class method (the class > method was listed after the instance method for that test, so I wasn't > surprised that the class method did, in fact, get executed there). > What I did not try was to list the class method first, then list the instance > method, and then try to invoke the class method. > As mentioned in my prior e-mail, when I did try to invoke the instance > version of run, it was only successful if the instance version was the second > one declared in the file. If the class method was declared second, then it > was invoked even when I was trying to invoke the instance one. > > On Apr 30, 2016, at 6:06 PM, Will Stevens <williamstev...@gmail.com> wrote: > > > > That's strange. That means the @classmethod decorator is not working. You > > should have gotten the instance method in both cases. > > > > What if you don't instantiate Test and only do the following. > > > > Test.run() > > > > In both cases. > Mark as unread > Will Stevens <williamstev...@gmail.com> > Sat 4/30/2016 6:06 PM > Inbox > That's strange. That means the @classmethod decorator is not working. You > should have gotten the instance method in both cases. > What if you don't instantiate Test and only do the following. > Test.run() > In both cases. > On Apr 30, 2016 6:04 PM, "Tutkowski, Mike" <mike.tutkow...@netapp.com> > wrote: > > I ran this with an online Python tool and it calls the class method: > > > > 1 class Test: > > 2 def run(self): > > 3 print 'instance hi' > > 4 > > 5 @classmethod > > 6 def run(cls): > > 7 print 'class hi' > > 8 > > 9 test = Test() > > 10 > > 11 test.run() > > > > If I reverse the order of the methods, the instance method is invoked: > > > > 1 class Test: > > 2 @classmethod > > 3 def run(cls): > > 4 print 'class hi' > > 5 > > 6 def run(self): > > 7 print 'instance hi' > > 8 > > 9 test = Test() > > 10 > > 11 test.run() > > > > As I suspected, I think this means we have a problem in base.py. > Mark as unread > Tutkowski, Mike > Sat 4/30/2016 4:03 PM > Sent Items; Inbox > >> I ran this with an online Python tool and it calls the class method: > >> > >> 1 class Test: > >> 2 def run(self): > >> 3 print 'instance hi' > >> 4 > >> 5 @classmethod > >> 6 def run(cls): > >> 7 print 'class hi' > >> 8 > >> 9 test = Test() > >> 10 > >> 11 test.run() > >> > >> If I reverse the order of the methods, the instance method is invoked: > >> > >> 1 class Test: > >> 2 @classmethod > >> 3 def run(cls): > >> 4 print 'class hi' > >> 5 > >> 6 def run(self): > >> 7 print 'instance hi' > >> 8 > >> 9 test = Test() > >> 10 > >> 11 test.run() > >> > >> As I suspected, I think this means we have a problem in base.py. > >> ________________________________________ > >> From: Will Stevens <williamstev...@gmail.com> > >> Sent: Saturday, April 30, 2016 1:46 PM > >> To: d...@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. :) > Mark as unread > Will Stevens <williamstev...@gmail.com> > Sat 4/30/2016 1:46 PM > Inbox > I am on my phone so I have not been able to research this for you. I think > you are right for the most part. Instead of multiple methods, python kind > of fakes overloading by being to have named function arguments which can > have default values, so you can call the method with a dynamic number of > arguments making it appear like you are overloading, but you are actually > calling the same function. > I think in this case the two methods are actually in different scopes (even > though they are next to each other). The decorator actually wraps the > method, so I believe in the actual runtime the to methods are in different > scopes. > I would have to look into this more to know for sure. I am taking a few > minute break from building garden boxes right now. :) > On Apr 30, 2016 3:31 PM, "Tutkowski, Mike" <mike.tutkow...@netapp.com> > wrote: > > Will - You can override a method in Python, but can you overload it? > > > > > > http://stackoverflow.com/questions/10202938/how-do-i-use-method-overloading-in-python > > > > > On Apr 30, 2016, at 6:23 AM, Will Stevens <williamstev...@gmail.com> > Mark as unread > Tutkowski, Mike > Sat 4/30/2016 1:31 PM > Sent Items; Inbox > Will - You can override a method in Python, but can you overload it? > http://stackoverflow.com/questions/10202938/how-do-i-use-method-overloading-in-python > > On Apr 30, 2016, at 6:23 AM, Will Stevens <williamstev...@gmail.com> wrote: > > > > Here is a pretty good explanation. > > > > http://stackoverflow.com/questions/136097/what-is-the-difference-between-staticmethod-and-classmethod-in-python > > > > I am guessing that both exist because the function is called both with a > > host instance and with the class itself. > > > > Class instance example: `h.enableMaintenance(client)` > > > > Class example: `Host.enableMaintenance(client, 1)` > > > > In both cases the first parameter is implicitly `h` and `Host` > > respectively. > > > > I am not sure why we need both (because I am not familiar with how this > > code is called), but method overloading is definitely valid in python. > Mark as unread > Tutkowski, Mike > Sat 4/30/2016 9:40 AM > Sent Items; Inbox > Allow me to clarify. :-) > host.enableMaintenance(apiclient) is how I was invoking it. Just like a > regular instance method. > For some reason, it wanted to invoke the class method when I did that and was > complaining about the lack of a parameter. > That being the case, I switched my code to the following (to make use of the > class method): > Host.enableMaintenance(apiclient, host.id) > The weird part is that it seems like Python was trying to invoke the class > method when I had syntax specifying I wanted to invoke the instance method. > To circumvent the issue, I just switched my syntax to make use of the class > method instead of the instance method. > Seems like I shouldn't have had to do that, though. > > On Apr 30, 2016, at 6:30 AM, Will Stevens <williamstev...@gmail.com> wrote: > > > > You are probably getting this error because you are trying to call: > > Host.enableMaintenance(client) > > > > Check my examples above for how to call it. > > > > Sorry I am on my phone, so I am not very efficient with my phone and cant > > civet you better details. :) > >> On Apr 30, 2016 8:23 AM, "Will Stevens" <williamstev...@gmail.com> wrote: > >> > >> Here is a pretty good explanation. > >> > >> > >> http://stackoverflow.com/questions/136097/what-is-the-difference-between-staticmethod-and-classmethod-in-python > >> > >> I am guessing that both exist because the function is called both with a > >> host instance and with the class itself. > >> > >> Class instance example: `h.enableMaintenance(client)` > >> > >> Class example: `Host.enableMaintenance(client, 1)` > >> > >> In both cases the first parameter is implicitly `h` and `Host` > >> respectively. > >> > >> I am not sure why we need both (because I am not familiar with how this > >> code is called), but method overloading is definitely valid in python. > Mark as unread > Will Stevens <williamstev...@gmail.com> > Sat 4/30/2016 6:30 AM > Inbox > You are probably getting this error because you are trying to call: > Host.enableMaintenance(client) > Check my examples above for how to call it. > Sorry I am on my phone, so I am not very efficient with my phone and cant > civet you better details. :) > Mark as unread > Will Stevens <williamstev...@gmail.com> > Sat 4/30/2016 6:23 AM > Inbox > 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. > Mark as unread > Prashanth Manthena <prashanth.manth...@nuagenetworks.net> > Sat 4/30/2016 6:10 AM > Inbox > Hi Mike, > classmethod's first argument is always its class as it is always bound to > the class, which is not the case with normal methods. Thus, both of the > above methods can in essence still co-exist in base.py as they serve > different purposes. > In the latter classmethod, you need to pass your host object ID as one of > the argument while calling it with its class name as its first argument. > e.g. Host.enableMaintenance(self.apiclient, host_1.id) > Note: "Host" is the class name of the above methods in base.py. "host_1" is > your host object. > In the former method, you just need to call it with your host object as its > first argument, it takes the host ID from the passed host object. > e.g. host_1.enableMaintenance(self.apiclient) > Mark as unread > Tutkowski, Mike <mike.tutkow...@netapp.com> > Fri 4/29/2016 11:08 PM > Inbox > > 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 > Mark as unread > Tutkowski, Mike > Fri 4/29/2016 11:08 PM > 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 -- This message was sent by Atlassian JIRA (v6.3.4#6332)