diff --git a/pyproject.toml b/pyproject.toml index fc951ee..2c32836 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "oslg" -version = "0.3.3" +version = "0.4.0" description = "OpenStudio SDK logger for Python" readme = "README.md" requires-python = ">=3.2" diff --git a/src/oslg/oslg.py b/src/oslg/oslg.py index ca2d1f9..eb7faad 100644 --- a/src/oslg/oslg.py +++ b/src/oslg/oslg.py @@ -74,31 +74,31 @@ class _CN: _status = 0 -def trim(txt="", length=160) -> str: +def trim(txt="", sz=None) -> str: """ Converts an object to a string. Strips if necessary. Args: txt (str): An object. - length (int): - Desired maximum string length (max 160). + sz (int): + Selected maximum string length, or 'size' (optional). Returns: str: Stripped, trimmed string. - "": If 'length' cannot be converted to an integer. "": If 'txt' cannot be converted to a valid string. """ try: - length = int(length) + txt = str(txt).strip() except: - length = 160 + txt = "" try: - txt = str(txt).strip()[:length] + sz = int(sz) + if len(txt) > sz: txt = txt[:sz] + " ..." except: - txt = "" + pass return txt @@ -217,7 +217,7 @@ def reset(lvl=CN.DEBUG) -> int: return _level -def log(lvl=CN.DEBUG, message="", length=160) -> int: +def log(lvl=CN.DEBUG, message="", sz=None) -> int: """ Logs a new entry. Overall log status is raised if new level is greater (e.g. FATAL > ERROR). Candidate log entry is ignored and status remains @@ -230,8 +230,8 @@ def log(lvl=CN.DEBUG, message="", length=160) -> int: Selected log level (e.g. CN.DEBUG). message (str): Selected log message. - length (int): - Selected log message length (max 160 chars). + sz (int): + Selected maximum string length, or 'size' (optional). Returns: Current log status, potentially raised. @@ -245,14 +245,7 @@ def log(lvl=CN.DEBUG, message="", length=160) -> int: except: return _status - try: - length = int(length) - except: - return _status - - if length > 160: length = 160 - - message = trim(message, length) + message = trim(message, sz) if not message or lvl < CN.DEBUG or lvl > CN.FATAL or lvl < _level: return _status @@ -265,7 +258,7 @@ def log(lvl=CN.DEBUG, message="", length=160) -> int: return _status -def invalid(id="", mth="", ord=0, lvl=CN.DEBUG, res=None): +def invalid(id="", mth="", ord=0, lvl=CN.DEBUG, res=None, sz=None): """ Logs template 'invalid object' entry, based on arguments. Relies on OSlg method 'log()': first check out its own operation, exit conditions and @@ -284,6 +277,8 @@ def invalid(id="", mth="", ord=0, lvl=CN.DEBUG, res=None): Selected log level (e.g. CN.DEBUG). res: Selected return object (e.g. 'False', None). + sz (int): + Selected maximum string length, or 'size' (optional). Returns: Selected return object ('res'). @@ -311,12 +306,12 @@ def invalid(id="", mth="", ord=0, lvl=CN.DEBUG, res=None): msg += "arg #%d " % (ord) msg += "(%s)" % (mth) - log(lvl, msg) + log(lvl, msg, sz) return res -def mismatch(id="", obj=None, cl=None, mth="", lvl=CN.DEBUG, res=None): +def mismatch(id="", obj=None, cl=None, mth="", lvl=CN.DEBUG, res=None, sz=None): """ Logs template 'instance/class mismatch' entry, based on arguments. Relies on OSlg method 'log()': first check out its own operation, exit conditions @@ -336,6 +331,8 @@ def mismatch(id="", obj=None, cl=None, mth="", lvl=CN.DEBUG, res=None): Selected log level (e.g. CN.DEBUG). res: Selected return object (e.g. 'False', None). + sz (int): + Selected maximum string length, or 'size' (optional). Returns: Selected return object ('res'). @@ -358,12 +355,12 @@ def mismatch(id="", obj=None, cl=None, mth="", lvl=CN.DEBUG, res=None): msg = "'%s' %s? " % (id, type(obj).__name__) msg += "expecting %s (%s)" % (cl.__name__, mth) - log(lvl, msg) + log(lvl, msg, sz) return res -def hashkey(id="", dct={}, key="", mth="", lvl=CN.DEBUG, res=None): +def hashkey(id="", dct={}, key="", mth="", lvl=CN.DEBUG, res=None, sz=None): """ Logs template 'missing hash key' entry, based on arguments. Relies on OSlg method 'log()': first check out its own operation, exit conditions and @@ -383,6 +380,8 @@ def hashkey(id="", dct={}, key="", mth="", lvl=CN.DEBUG, res=None): Selected log level (e.g. CN.DEBUG). res: Selected return object (e.g. 'False', None). + sz (int): + Selected maximum string length, or 'size' (optional). Returns: Selected return object ('res'). @@ -404,12 +403,12 @@ def hashkey(id="", dct={}, key="", mth="", lvl=CN.DEBUG, res=None): if not isinstance(dct, dict): return res if key in dct: return res - log(lvl, "Missing '%s' key in %s (%s)" % (ky, id, mth)) + log(lvl, "Missing '%s' key in %s (%s)" % (ky, id, mth), sz) return res -def empty(id="", mth="", lvl=CN.DEBUG, res=None): +def empty(id="", mth="", lvl=CN.DEBUG, res=None, sz=None): """ Logs template 'empty' entry, based on arguments. Relies on OSlg method 'log()': first check out its own operation, exit conditions and module side @@ -424,6 +423,8 @@ def empty(id="", mth="", lvl=CN.DEBUG, res=None): Selected log level (e.g. CN.DEBUG). res: Selected return object (e.g. 'False', None). + sz (int): + Selected maximum string length, or 'size' (optional). Returns: Selected return object ('res'). @@ -442,12 +443,12 @@ def empty(id="", mth="", lvl=CN.DEBUG, res=None): if lvl < CN.DEBUG: return res if lvl > CN.FATAL: return res - log(lvl, "Empty '%s' (%s)" % (id, mth)) + log(lvl, "Empty '%s' (%s)" % (id, mth), sz) return res -def zero(id="", mth="", lvl=CN.DEBUG, res=None): +def zero(id="", mth="", lvl=CN.DEBUG, res=None, sz=None): """ Logs template 'zero' entry, based on arguments. Relies on OSlg method 'log()': first check out its own operation, exit conditions and module side @@ -462,6 +463,8 @@ def zero(id="", mth="", lvl=CN.DEBUG, res=None): Selected log level (e.g. CN.DEBUG). res: Selected return object (e.g. 'False', None). + sz (int): + Selected maximum string length, or 'size' (optional). Returns: Selected return object ('res'). @@ -480,12 +483,12 @@ def zero(id="", mth="", lvl=CN.DEBUG, res=None): if lvl < CN.DEBUG: return res if lvl > CN.FATAL: return res - log(lvl, "Zero '%s' (%s)" % (id, mth)) + log(lvl, "Zero '%s' (%s)" % (id, mth), sz) return res -def negative(id="", mth="", lvl=CN.DEBUG, res=None): +def negative(id="", mth="", lvl=CN.DEBUG, res=None, sz=None): """ Logs template 'negative' entry, based on arguments. Relies on OSlg method 'log()': first check out its own operation, exit conditions and module side @@ -500,6 +503,8 @@ def negative(id="", mth="", lvl=CN.DEBUG, res=None): Selected log level (e.g. CN.DEBUG). res: Selected return object (e.g. 'False', None). + sz (int): + Selected maximum string length, or 'size' (optional). Returns: Selected return object ('res'). @@ -518,7 +523,7 @@ def negative(id="", mth="", lvl=CN.DEBUG, res=None): if lvl < CN.DEBUG: return res if lvl > CN.FATAL: return res - log(lvl, "Negative '%s' (%s)" % (id, mth)) + log(lvl, "Negative '%s' (%s)" % (id, mth), sz) return res diff --git a/tests/test_oslg.py b/tests/test_oslg.py index 0480490..2ac658a 100644 --- a/tests/test_oslg.py +++ b/tests/test_oslg.py @@ -56,7 +56,7 @@ def test01_oslg_initialized(self): self.assertEqual(oslg.msg(FTL), "Failure, triggered fatal errors") self.assertNotEqual(oslg.msg(FTL), "Debugging ...") self.assertEqual(oslg.trim(" oslg "), "oslg") - self.assertEqual(oslg.trim(" oslg ", 3), "osl") + self.assertEqual(oslg.trim(" oslg ", 3), "osl ...") self.assertEqual(oslg.trim(" oslg ", 64), "oslg") self.assertEqual(oslg.reset(INF), INF) self.assertEqual(oslg.clean(), INF) @@ -99,6 +99,30 @@ def test03_oslg_invalid_argument_log(self): self.assertEqual(oslg.clean(), INF) self.assertEqual(oslg.level(), INF) + # Longish error message, exceeding 160 chars. + a = str([i+1 for i in range(60)]) + l1 = 3 * 9 # "1, " + "2, " + "3, " ...+ "9, " + l2 = 4 * (59 - 9) # "10, " + "11, " + 12, ...+ "59, " + l3 = 2 # "60" + l4 = 2 # "[]" + self.assertEqual(l1 + l2 + l3 + l4, 231) + self.assertEqual(len(a), l1 + l2 + l3 + l4) + self.assertEqual(oslg.mismatch("x", "String", list, a, FTL, None, 156), None) + self.assertEqual(oslg.status(), FTL) + str1 = "'x' str? expecting list " # 24 chars + str2 = "([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, " # 45 chars + str3 = "14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, " # 44 chars + str4 = "25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, ..." # 47 chars + str0 = str1 + str2 + str3 + str4 + self.assertEqual(len(str0), 160) # 156 + " ..." + self.assertEqual(len(oslg.logs()[0]["message"]), len(str0)) + self.assertEqual(oslg.logs()[0]["message"], str0) + self.assertEqual(oslg.level(), INF) + self.assertEqual(len(oslg.logs()), 1) + self.assertEqual(oslg.reset(INF), INF) + self.assertEqual(oslg.clean(), INF) + self.assertEqual(oslg.level(), INF) + def test04_oslg_mismatched_argument_log(self): m1 = "'radius' str? expecting float (area)" m2 = "'roster' list? expecting dict (index)"