xmlutil: Centralize all 'programming error' exceptions

Raise them directly instead of adding the hard to read conditional
into the function

Signed-off-by: Cole Robinson <crobinso@redhat.com>
This commit is contained in:
Cole Robinson 2020-07-17 18:58:00 -04:00
parent 380a44318a
commit aa89a48371
14 changed files with 48 additions and 49 deletions

View File

@ -11,4 +11,4 @@ exclude_lines =
# Don't complain if tests don't hit defensive assertion code:
raise NotImplementedError
.*raise_programming_error.*
.*DevError.*

View File

@ -8,6 +8,7 @@ import unittest
from virtinst import Guest
from virtinst import OSDB
from virtinst import xmlutil
from virtinst.install import urldetect
from tests import utils
@ -45,7 +46,7 @@ class TestOSDB(unittest.TestCase):
for store in allstores:
for distro in store.matching_distros:
if distro in seen_distro:
raise RuntimeError("programming error: "
raise xmlutil.DevError(
"store=%s has conflicting matching_distro=%s " %
(store.PRETTY_NAME, distro))
seen_distro.append(distro)

View File

@ -310,6 +310,7 @@ class TestXMLMisc(unittest.TestCase):
newdisk.build_storage(None)
# Test cloning onto existing disk
newdisk = virtinst.DeviceDisk(conn, parsexml=newdisk.get_xml())
newdisk.path = newdisk.path
newdisk.set_local_disk_to_clone(srcdisk, True)
newdisk.build_storage(None)

View File

@ -1516,9 +1516,9 @@ class XMLParseTest(unittest.TestCase):
virtinst.DeviceDisk(self.conn, parsexml=-1)
self.assertTrue("xmlParseDoc" in str(cm.exception))
with self.assertRaises(RuntimeError):
from virtinst import xmlutil
xmlutil.raise_programming_error(True, "for coverage")
from virtinst import xmlutil
with self.assertRaises(xmlutil.DevError):
raise xmlutil.DevError("for coverage")
with self.assertRaises(ValueError):
virtinst.DeviceDisk.validate_generic_name("objtype", None)

View File

@ -580,7 +580,7 @@ class vmmConnection(vmmGObject):
elif obj.is_network():
define_cb = self.define_network
else:
raise RuntimeError("programming error: rename_object "
raise virtinst.xmlutil.DevError("rename_object "
"helper doesn't support object class %s" % obj.__class__)
# Undefine the original object

View File

@ -1035,12 +1035,10 @@ class _VirtCLIArgumentStatic(object):
self._aliases = []
if not self.propname and not self.cb:
raise RuntimeError( # pragma: no cover
"programming error: propname or cb must be specified.")
raise xmlutil.DevError("propname or cb must be specified.")
if not self.propname and self.lookup_cb == -1:
raise RuntimeError( # pragma: no cover
"programming error: "
raise xmlutil.DevError(
"cliname=%s propname is None but lookup_cb is not specified. "
"Even if a 'cb' is passed, 'propname' is still used for "
"device lookup for virt-xml --edit.\n\nIf cb is just "
@ -1136,8 +1134,8 @@ class _VirtCLIArgument(object):
if self.propname:
xmlutil.get_prop_path(inst, self.propname)
except AttributeError: # pragma: no cover
raise RuntimeError("programming error: obj=%s does not have "
"member=%s" % (inst, self.propname))
raise xmlutil.DevError(
"obj=%s does not have member=%s" % (inst, self.propname))
if self._virtarg.cb:
self._virtarg.cb(parser, inst, self.val, self)
@ -1274,9 +1272,8 @@ class _InitClass(type):
# Check for leftover aliases
if self.aliases:
raise RuntimeError( # pragma: no cover
"programming error: class=%s "
"leftover aliases=%s" % (self, self.aliases))
raise xmlutil.DevError(
"class=%s leftover aliases=%s" % (self, self.aliases))
return self

View File

@ -323,7 +323,7 @@ class DeviceDisk(Device):
return self._storage_backend.get_path()
def _set_path(self, newpath):
if self._storage_backend.will_create_storage():
xmlutil.raise_programming_error(None,
raise xmlutil.DevError(
"Can't change disk path if storage creation info "
"has been set.")

View File

@ -400,7 +400,7 @@ class _StorageBase(object):
def create(self, progresscb):
ignore = progresscb # pragma: no cover
xmlutil.raise_programming_error(None,
raise xmlutil.DevError(
"%s can't create storage" % self.__class__.__name__)
@ -692,7 +692,7 @@ class StorageBackend(_StorageBase):
self._path = None
if self._vol_object and not self._parent_pool:
xmlutil.raise_programming_error(None,
raise xmlutil.DevError(
"parent_pool must be specified")
# Cached bits

View File

@ -107,8 +107,7 @@ class DomainCpu(XMLBuilder):
self.clear()
self.set_model(guest, self.conn.caps.host.cpu.model)
else:
xmlutil.raise_programming_error(
True, "unknown special cpu mode '%s'" % val)
raise xmlutil.DevError("unknown special cpu mode '%s'" % val)
self.special_mode_was_set = True

View File

@ -304,8 +304,9 @@ class Guest(XMLBuilder):
# tried to access osinfo before we can depend on it being
# available. Try moving whatever bits need osinfo to be
# triggered via set_defaults
xmlutil.raise_programming_error(self.skip_default_osinfo,
"osinfo is accessed before it has been set.")
if self.skip_default_osinfo:
raise xmlutil.DevError(
"osinfo is accessed before it has been set.")
self.set_default_os_name()
return self.__osinfo
osinfo = property(_get_osinfo)

View File

@ -8,6 +8,8 @@
import libvirt
from . import xmlutil
def _check_function(function, flag, run_args, data):
"""
@ -63,9 +65,8 @@ def _version_str_to_int(verstr):
return 0
if verstr.count(".") != 2:
raise RuntimeError( # pragma: no cover
"programming error: version string '%s' needs "
"two '.' in it.")
raise xmlutil.DevError(
"version string '%s' needs two '.' in it." % verstr)
return ((int(verstr.split(".")[0]) * 1000000) +
(int(verstr.split(".")[1]) * 1000) + (int(verstr.split(".")[2])))
@ -113,8 +114,8 @@ class _SupportCheck(object):
for vstr in versions:
v = _version_str_to_int(vstr)
if vstr is not None and v != 0 and v < 7003:
raise RuntimeError( # pragma: no cover
"programming error: Cannot enforce "
raise xmlutil.DevError(
"Cannot enforce "
"support checks for libvirt versions less than 0.7.3, "
"since required APIs were not available. ver=%s" % vstr)

View File

@ -225,8 +225,9 @@ class _XMLBase(object):
xpathobj = _XPath(fullxpath)
parentxpath = "."
parentnode = self._find(parentxpath)
xmlutil.raise_programming_error(not parentnode,
"Did not find XML root node for xpath=%s" % fullxpath)
if not parentnode:
raise xmlutil.DevError(
"Did not find XML root node for xpath=%s" % fullxpath)
for xpathseg in xpathobj.segments[1:]:
oldxpath = parentxpath

View File

@ -192,8 +192,8 @@ class XMLProperty(_XMLPropertyBase):
:param do_abspath: If True, run os.path.abspath on the passed value
"""
self._xpath = xpath
xmlutil.raise_programming_error(not self._xpath,
"XMLProperty: xpath must be passed.")
if not self._xpath:
raise xmlutil.DevError("XMLProperty: xpath must be passed.")
self._is_bool = is_bool
self._is_int = is_int
@ -204,8 +204,8 @@ class XMLProperty(_XMLPropertyBase):
conflicts = sum([int(bool(i)) for i in
[self._is_bool, self._is_int,
self._is_yesno, self._is_onoff]])
xmlutil.raise_programming_error(conflicts > 1,
"Conflict property converter options.")
if conflicts > 1:
raise xmlutil.DevError("Conflict property converter options.")
self._is_tracked = False
if _trackprops:
@ -499,16 +499,16 @@ class XMLBuilder(object):
xmlprops = self._all_xml_props()
childprops = self._all_child_props()
for key in self._XML_PROP_ORDER:
xmlutil.raise_programming_error(
key not in xmlprops and key not in childprops,
"key '%s' must be xml prop or child prop" % key)
if key not in xmlprops and key not in childprops:
raise xmlutil.DevError(
"key '%s' must be xml prop or child prop" % key)
childclasses = []
for childprop in childprops.values():
xmlutil.raise_programming_error(
childprop.child_class in childclasses,
"can't register duplicate child_class=%s" %
childprop.child_class)
if childprop.child_class in childclasses:
raise xmlutil.DevError(
"can't register duplicate child_class=%s" %
childprop.child_class)
childclasses.append(childprop.child_class)
setattr(self.__class__, cachekey, True)
@ -641,7 +641,8 @@ class XMLBuilder(object):
if child_class is xmlprop.child_class:
ret = xmlprop
break
xmlutil.raise_programming_error(not ret,
if not ret:
raise xmlutil.DevError(
"Didn't find child property for child_class=%s" % child_class)
return ret

View File

@ -8,6 +8,11 @@
import os
class DevError(RuntimeError):
def __init__(self, msg):
RuntimeError.__init__(self, "programming error: %s" % msg)
def listify(l):
if l is None:
return []
@ -61,13 +66,5 @@ def set_prop_path(obj, prop_path, value):
return setattr(parent, pieces[-1], value)
def raise_programming_error(cond, msg):
"""
Small helper to raise a consistent error message for coding issues
"""
if cond:
raise RuntimeError("programming error: %s" % msg)
def in_testsuite():
return "VIRTINST_TEST_SUITE" in os.environ