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(a)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)
--
2.31.1