Nir Soffer has posted comments on this change.
Change subject: assert: Replace assetion with AssertionError
......................................................................
Patch Set 3:
(9 comments)
I think that most of the original asserts are correct. Since assert are not reliable (can
be removed by the user in runtime), we should not use them, as this make the code
unpredictable and harder to test and maintain.
The purpose of the patch is to replace unreliable assertions with reliable
AssertionError.
Generrly using stdlib exceptions such as RuntimeError, TypeError and ValueError is a bad
idea, making it hard to distinguish between stdlib errors and bugs and application
errors.
http://gerrit.ovirt.org/#/c/29307/3/lib/vdsm/libvirtconnection.py
File lib/vdsm/libvirtconnection.py:
Line 37: self.__thread = None
Line 38:
Line 39: def start(self):
Line 40: if self.run:
Line 41: raise AssertionError("EventLoop is running")
raise RuntimeError("EventLoop is already running")
Why do you think RuntimeError it is better?
Clearly this is not a runtime error but a programmer error, calling start() twice.
When an API is used incorrectly, AssertionError is the best response.
Line 42: self.__thread = threading.Thread(target=self.__run,
Line 43: name="libvirtEventLoop")
Line 44: self.__thread.setDaemon(True)
Line 45: self.run = True
http://gerrit.ovirt.org/#/c/29307/3/lib/vdsm/netinfo.py
File lib/vdsm/netinfo.py:
Line 842: nic in attrs['slaves']]
Line 843: if bondings:
Line 844: if len(bondings) != 1:
Line 845: raise AssertionError("Unexpected configuration: More than
"
Line 846: "one bonding per nic")
ValueError
ValueError is used when given invalid argument for a
function. Here the error is invalid configuration.
Since this is not programmer error, we can raise here another exception like
InvalidConfiguration.
Antoni?
Line 847: return bondings[0]
Line 848: return None
Line 849:
Line 850: def getNicsVlanAndBondingForNetwork(self, network):
Line 861:
Line 862: for port in ports:
Line 863: if port in self.vlans:
Line 864: if vlan is not None:
Line 865: raise AssertionError("Unexpected vlan: %s exepected:
None"
ValueError
See above
Line 866: % (vlan,))
Line 867: nic = getVlanDevice(port)
Line 868: vlan = getVlanID(port)
Line 869: if self.vlans[port]['iface'] != nic:
Line 866: % (vlan,))
Line 867: nic = getVlanDevice(port)
Line 868: vlan = getVlanID(port)
Line 869: if self.vlans[port]['iface'] != nic:
Line 870: raise AssertionError("Unexpected iface: %s expected:
%s" %
ValueError
See above
Line 871: (self.vlans[port]['iface'],
nic))
Line 872: port = nic
Line 873: if port in self.bondings:
Line 874: if bonding is not None:
Line 871: (self.vlans[port]['iface'],
nic))
Line 872: port = nic
Line 873: if port in self.bondings:
Line 874: if bonding is not None:
Line 875: raise AssertionError("Unexpected bonding: %s expected:
"
ValueError
See above
Line 876: "None" % bonding)
Line 877: bonding = port
Line 878: lnics += self.bondings[bonding]['slaves']
Line 879: elif port in self.nics:
http://gerrit.ovirt.org/#/c/29307/3/vdsm/rpc/BindingXMLRPC.py
File vdsm/rpc/BindingXMLRPC.py:
Line 1132: logLevel = logging.TRACE
Line 1133: displayArgs = args
Line 1134: if f.__name__ == 'vmDesktopLogin':
Line 1135: if 'password' in kwargs:
Line 1136: raise AssertionError("Unexpected kwarg:
password")
raise TypeError("Unexpected keyword argument
'password'")
How type error is related? It is used when a function
cannot handle some type of argument, but here we don't have any problem with the type
(str), but with the existence of an kwarg.
I'm not sure what kind of error is this - client error or failure of other code to
remove the password, So I kept the original behavior.
Line 1137: if len(args) > 3:
Line 1138: displayArgs = args[:3] + ('****',) + args[4:]
Line 1139:
Line 1140: # Logging current call
http://gerrit.ovirt.org/#/c/29307/3/vdsm/rpc/process-schema.py
File vdsm/rpc/process-schema.py:
Line 104:
Line 105: # Pop a blank line
Line 106: line = lines.pop(0)
Line 107: if line != '':
Line 108: raise AssertionError("Expected empty line: %s" % line)
leave as assert
Leaving the assert means the code will be
broken if running with -O (line.pop() will not be invoked)
This is the typical example of how *not* to use assert.
Line 109:
Line 110: # Grab the entity description. It might span multiple lines.
Line 111: symbol['desc'] = lines.pop(0)
Line 112: while (lines[0] != ''):
Line 113: symbol['desc'] += lines.pop(0)
Line 114:
Line 115: # Pop a blank line
Line 116: line = lines.pop(0)
Line 117: if line != '':
leave as assert
See above
Line 118: raise AssertionError("Expected empty line: %s" % line)
Line 119:
Line 120: # Populate the rest of the human-readable data.
Line 121: # First try to read the parameters/members information. We are finished
http://gerrit.ovirt.org/#/c/29307/3/vdsm/storage/misc.py
File vdsm/storage/misc.py:
Line 695: return False
Line 696:
Line 697: def exit(self):
Line 698: with self._cond:
Line 699: if not self._busy:
leave as assert
The cost of this check is insignificant, and
removing it is too risky.
When an API is used incorrectly, AssertionError is the best response.
Line 700: raise AssertionError("Attempt to exit a barrier without
"
Line 701: "entering")
Line 702: self._busy = False
Line 703: self._cond.notifyAll()
--
To view, visit
http://gerrit.ovirt.org/29307
To unsubscribe, visit
http://gerrit.ovirt.org/settings
Gerrit-MessageType: comment
Gerrit-Change-Id: I8c60c65b283f4343448bb9eaf6ccf2526b188db0
Gerrit-PatchSet: 3
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Nir Soffer <nsoffer(a)redhat.com>
Gerrit-Reviewer: Adam Litke <alitke(a)redhat.com>
Gerrit-Reviewer: Allon Mureinik <amureini(a)redhat.com>
Gerrit-Reviewer: Antoni Segura Puimedon <asegurap(a)redhat.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
Gerrit-Reviewer: Federico Simoncelli <fsimonce(a)redhat.com>
Gerrit-Reviewer: Nir Soffer <nsoffer(a)redhat.com>
Gerrit-Reviewer: Saggi Mizrahi <smizrahi(a)redhat.com>
Gerrit-Reviewer: Yaniv Bronhaim <ybronhei(a)redhat.com>
Gerrit-Reviewer: automation(a)ovirt.org
Gerrit-Reviewer: oVirt Jenkins CI Server
Gerrit-HasComments: Yes