Improve sysfs.py
- Add docstring comments to classes and functions - Make the code more readable by using os.path.join on file components - Initialize class variables in the __init__ when possible - Use "with" for opening files where possible - and __repr__ to classes for debugging purposes - Specify the type of exception where possible (replace bare exceptions) - Replace old style has_key with __contains__
Signed-off-by: John Kacur jkacur@redhat.com --- tuna/sysfs.py | 48 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 11 deletions(-)
diff --git a/tuna/sysfs.py b/tuna/sysfs.py index bce96af2f7b5..1c903e106a44 100755 --- a/tuna/sysfs.py +++ b/tuna/sysfs.py @@ -1,38 +1,54 @@ # -*- python -*- # -*- coding: utf-8 -*- +""" +classes for /sys/devices/system/cpu/ +so we can get topology information and do CPU hotplug operations +"""
import os
+ class cpu: + """ + class to query if a cpu is online or not + and to bring a cpu online or to take it offline + """ + def __init__(self, basedir, name): self.name = name - self.dir = "%s/%s" % (basedir, name) + self.dir = os.path.join(basedir, name) + self.online = None self.reload()
def __lt__(self, other): # Previously it is assumed that name[:3] == "cpu" and name[3].isdigit(), so: - int(self.name[3:]) < int(other.name[3:]) + return int(self.name[3:]) < int(other.name[3:])
def readfile(self, name): + """ read file "name", typically the per cpu "online" file """ try: - f = open("%s/%s" % (self.dir, name)) - value = f.readline().strip() - f.close() + with open(os.path.join(self.dir, name)) as f: + value = f.readline().strip() + return value except: raise - return value + + def __repr__(self): + return f'name={self.name}, online={self.online}, physical_package_id={self.physical_package_id}'
def reload_online(self): + """ read the "online" file """ self.online = True try: self.online = self.readfile("online") == "1" - except: + except FileNotFoundError: # boot CPU, usually cpu0, can't be brought offline, so # lacks the file and non root users can't read. In both # cases assume CPU is online. pass
def reload(self): + """ Load or reload the values of this class """ self.reload_online() if self.online: try: @@ -43,17 +59,20 @@ class cpu: self.physical_package_id = None
def set_online(self, online=True): + """ Turn a cpu on or off using the online file """ try: - f = open("%s/online" % self.dir, "w") - f.write("%d\n" % (online and 1 or 0)) - f.close() + with open(os.path.join(self.dir, "online"), "w") as f: + f.write("1" if online else "0") except: pass
self.reload_online() return online == self.online
+ class cpus: + """ a class that creates a dictionary of cpu information keyed by cpu """ + def __init__(self, basedir="/sys/devices/system/cpu"): self.basedir = basedir self.cpus = {} @@ -65,12 +84,17 @@ class cpus: return self.cpus[key]
def keys(self): + """ Returns a list of keys, for example a key could be cpu9 """ return list(self.cpus.keys())
- def has_key(self, key): + def __contains__(self, key): return key in self.cpus
+ def __repr__(self): + return f'cpus={self.cpus}, sockets={self.sockets}, nr_cpus={self.nr_cpus}' + def reload(self): + """ load or reload the values of this class """ sockets_to_sort = [] for name in os.listdir(self.basedir): if name[:3] != "cpu" or not name[3].isdigit(): @@ -96,9 +120,11 @@ class cpus: for socket in sockets_to_sort: self.sockets[socket].sort(key=lambda x: int(x.name[3:]))
+ if __name__ == '__main__':
cpus = cpus() + print(f'{cpus}')
for socket in list(cpus.sockets.keys()): print("Socket %s" % socket)
tuna-devel@lists.fedorahosted.org