New get_all_subclasses function in basic modules and use it in fact modules.
This commit is contained in:
parent
eb18767f91
commit
72f17f3ff3
2 changed files with 28 additions and 21 deletions
|
@ -303,6 +303,26 @@ def get_distribution_version():
|
||||||
distribution_version = None
|
distribution_version = None
|
||||||
return distribution_version
|
return distribution_version
|
||||||
|
|
||||||
|
def get_all_subclasses(cls):
|
||||||
|
'''
|
||||||
|
used by modules like Hardware or Network fact classes to retrieve all subclasses of a given class.
|
||||||
|
__subclasses__ return only direct sub classes. This one go down into the class tree.
|
||||||
|
'''
|
||||||
|
# Retrieve direct subclasses
|
||||||
|
subclasses = cls.__subclasses__()
|
||||||
|
to_visit = list(subclasses)
|
||||||
|
# Then visit all subclasses
|
||||||
|
while to_visit:
|
||||||
|
for sc in to_visit:
|
||||||
|
# The current class is now visited, so remove it from list
|
||||||
|
to_visit.remove(sc)
|
||||||
|
# Appending all subclasses to visit and keep a reference of available class
|
||||||
|
for ssc in sc.__subclasses__():
|
||||||
|
subclasses.append(ssc)
|
||||||
|
to_visit.append(ssc)
|
||||||
|
return subclasses
|
||||||
|
|
||||||
|
|
||||||
def load_platform_subclass(cls, *args, **kwargs):
|
def load_platform_subclass(cls, *args, **kwargs):
|
||||||
'''
|
'''
|
||||||
used by modules like User to have different implementations based on detected platform. See User
|
used by modules like User to have different implementations based on detected platform. See User
|
||||||
|
@ -315,11 +335,11 @@ def load_platform_subclass(cls, *args, **kwargs):
|
||||||
|
|
||||||
# get the most specific superclass for this platform
|
# get the most specific superclass for this platform
|
||||||
if distribution is not None:
|
if distribution is not None:
|
||||||
for sc in cls.__subclasses__():
|
for sc in get_all_subclasses(cls):
|
||||||
if sc.distribution is not None and sc.distribution == distribution and sc.platform == this_platform:
|
if sc.distribution is not None and sc.distribution == distribution and sc.platform == this_platform:
|
||||||
subclass = sc
|
subclass = sc
|
||||||
if subclass is None:
|
if subclass is None:
|
||||||
for sc in cls.__subclasses__():
|
for sc in get_all_subclasses(cls):
|
||||||
if sc.platform == this_platform and sc.distribution is None:
|
if sc.platform == this_platform and sc.distribution is None:
|
||||||
subclass = sc
|
subclass = sc
|
||||||
if subclass is None:
|
if subclass is None:
|
||||||
|
|
|
@ -32,6 +32,7 @@ import datetime
|
||||||
import getpass
|
import getpass
|
||||||
import pwd
|
import pwd
|
||||||
import ConfigParser
|
import ConfigParser
|
||||||
|
from basic import get_all_subclasses
|
||||||
|
|
||||||
# py2 vs py3; replace with six via ziploader
|
# py2 vs py3; replace with six via ziploader
|
||||||
try:
|
try:
|
||||||
|
@ -867,7 +868,7 @@ class Hardware(Facts):
|
||||||
|
|
||||||
def __new__(cls, *arguments, **keyword):
|
def __new__(cls, *arguments, **keyword):
|
||||||
subclass = cls
|
subclass = cls
|
||||||
for sc in Hardware.__subclasses__():
|
for sc in get_all_subclasses(Hardware):
|
||||||
if sc.platform == platform.system():
|
if sc.platform == platform.system():
|
||||||
subclass = sc
|
subclass = sc
|
||||||
return super(cls, subclass).__new__(subclass, *arguments, **keyword)
|
return super(cls, subclass).__new__(subclass, *arguments, **keyword)
|
||||||
|
@ -1949,23 +1950,9 @@ class Network(Facts):
|
||||||
|
|
||||||
def __new__(cls, *arguments, **keyword):
|
def __new__(cls, *arguments, **keyword):
|
||||||
subclass = cls
|
subclass = cls
|
||||||
# Retrieve direct subclasses
|
for sc in get_all_subclasses(Network):
|
||||||
to_visit = Network.__subclasses__()
|
if sc.platform == platform.system():
|
||||||
# Then visit all subclasses
|
subclass = sc
|
||||||
while to_visit:
|
|
||||||
for sc in to_visit:
|
|
||||||
# Check if current class is the good one
|
|
||||||
if sc.platform == platform.system():
|
|
||||||
subclass = sc
|
|
||||||
to_visit = []
|
|
||||||
break
|
|
||||||
# The current class is now visited, so remove it from list
|
|
||||||
to_visit.remove(sc)
|
|
||||||
# Appending all subclasses to visit and keep a reference of available class
|
|
||||||
for ssc in sc.__subclasses__():
|
|
||||||
to_visit.append(ssc)
|
|
||||||
|
|
||||||
# Now, return corresponding subclass
|
|
||||||
return super(cls, subclass).__new__(subclass, *arguments, **keyword)
|
return super(cls, subclass).__new__(subclass, *arguments, **keyword)
|
||||||
|
|
||||||
def populate(self):
|
def populate(self):
|
||||||
|
@ -2725,7 +2712,7 @@ class Virtual(Facts):
|
||||||
|
|
||||||
def __new__(cls, *arguments, **keyword):
|
def __new__(cls, *arguments, **keyword):
|
||||||
subclass = cls
|
subclass = cls
|
||||||
for sc in Virtual.__subclasses__():
|
for sc in get_all_subclasses(Virtual):
|
||||||
if sc.platform == platform.system():
|
if sc.platform == platform.system():
|
||||||
subclass = sc
|
subclass = sc
|
||||||
return super(cls, subclass).__new__(subclass, *arguments, **keyword)
|
return super(cls, subclass).__new__(subclass, *arguments, **keyword)
|
||||||
|
|
Loading…
Reference in a new issue