# Buggy code
def __del__(self):
    # skip exceptions in destroy-- since destroy() doesn't cover interpreter
    # shutdown-- where globals start going missing
    try:
        self.destroy()
    except Exception as ex:
        log.debug(ex)


# Traceback (KeyError)
[TRACE   ] 'semanage' could not be found in the following search path: ['/srv/mastersalt/makina-states/bin', '/srv/salt/makina-states/bin', '/usr/local/sbin', '/srv/salt/makina-states/bin', '/usr/local/bin', '/srv/salt/makina-states/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin', '/usr/games', '/usr/local/games']
[DEBUG   ] KeyError when loading groupadd
Traceback (most recent call last):
File "/srv/mastersalt/makina-states/src/salt/salt/loader.py", line 1142, in process_virtual
virtual = mod.__virtual__()
File "/srv/mastersalt/makina-states/src/salt/salt/modules/groupadd.py", line 21, in __virtual__
if __grains__['kernel'] in ('Linux', 'OpenBSD', 'NetBSD'):
KeyError: 'kernel'
[TRACE   ] 'varnishd' could not be found in the following search path: ['/srv/mastersalt/makina-states/bin', '/srv/salt/makina-states/bin', '/usr/local/sbin', '/srv/salt/makina-states/bin', '/usr/local/bin', '/srv/salt/makina-states/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin', '/usr/games', '/usr/local/games']
[DEBUG   ] KeyError when loading xapi
Traceback (most recent call last):
File "/srv/mastersalt/makina-states/src/salt/salt/loader.py", line 1142, in process_virtual
virtual = mod.__virtual__()
File "/srv/mastersalt/makina-states/src/salt/salt/modules/xapi.py", line 68, in __virtual__
if _check_xenapi() is not False:
File "/srv/mastersalt/makina-states/src/salt/salt/modules/xapi.py", line 50, in _check_xenapi
if __grains__['os'] == 'Debian':
KeyError: 'os'
[DEBUG   ] KeyError when loading netbsd_sysctl
Traceback (most recent call last):
File "/srv/mastersalt/makina-states/src/salt/salt/loader.py", line 1142, in process_virtual
virtual = mod.__virtual__()
File "/srv/mastersalt/makina-states/src/salt/salt/modules/netbsd_sysctl.py", line 21, in __virtual__
return __virtualname__ if __grains__['os'] == 'NetBSD' else False
KeyError: 'os'
[TRACE   ] 'rabbitmqctl' could not be found in the following search path: ['/srv/mastersalt/makina-states/bin', '/srv/salt/makina-states/bin', '/usr/local/sbin', '/srv/salt/makina-states/bin', '/usr/local/bin', '/srv/salt/makina-states/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin', '/usr/games', '/usr/local/games']
[TRACE   ] Loaded parted as virtual partition
[TRACE   ] 'gluster' could not be found in the following search path: ['/srv/mastersalt/makina-states/bin', '/srv/salt/makina-states/bin', '/usr/local/sbin', '/srv/salt/makina-states/bin', '/usr/local/bin', '/srv/salt/makina-states/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin', '/usr/games', '/usr/local/games']
[DEBUG   ] KeyError when loading solarisips
Traceback (most recent call last):
File "/srv/mastersalt/makina-states/src/salt/salt/loader.py", line 1142, in process_virtual
virtual = mod.__virtual__()
File "/srv/mastersalt/makina-states/src/salt/salt/modules/solarisips.py", line 40, in __virtual__
if __grains__['os'] == 'Solaris' and __grains__['kernelrelease'] == '5.11':
KeyError: 'os'
[DEBUG   ] KeyError when loading pw_group
Traceback (most recent call last):
File "/srv/mastersalt/makina-states/src/salt/salt/loader.py", line 1142, in process_virtual
virtual = mod.__virtual__()
File "/srv/mastersalt/makina-states/src/salt/salt/modules/pw_group.py", line 30, in __virtual__
return __virtualname__ if __grains__['kernel'] == 'FreeBSD' else False
KeyError: 'kernel'
[DEBUG   ] KeyError when loading apache
Traceback (most recent call last):
File "/srv/mastersalt/makina-states/src/salt/salt/loader.py", line 1142, in process_virtual
virtual = mod.__virtual__()
File "/srv/mastersalt/makina-states/src/salt/salt/modules/apache.py", line 41, in __virtual__
cmd = _detect_os()
File "/srv/mastersalt/makina-states/src/salt/salt/modules/apache.py", line 52, in _detect_os
if __grains__['os_family'] == 'RedHat':
KeyError: 'os_family'
[DEBUG   ] KeyError when loading chocolatey

# Fixed code
def __del__(self):
    # skip exceptions in destroy-- since destroy() doesn't cover interpreter
    # shutdown-- where globals start going missing
    try:
        self.destroy()
    except:  # pylint: disable=W0702
        pass