Clean up common module, and fix a few typing issues (#1188)

This commit is contained in:
Veronica Berglyd Olsen
2022-10-19 00:18:07 +02:00
committed by GitHub
7 changed files with 102 additions and 123 deletions
+21 -30
View File
@@ -45,52 +45,54 @@ logger = logging.getLogger(__name__)
# Checker Functions
# =============================================================================================== #
def checkString(value, default, allowNone=False):
def checkStringNone(value, default):
"""Check if a variable is a string or a None.
"""
if allowNone and (value is None or value == "None"):
if value is None or value == "None":
return None
if isinstance(value, str):
return str(value)
return default
def checkInt(value, default, allowNone=False):
"""Check if a variable is an integer or a None.
def checkString(value, default):
"""Check if a variable is a string.
"""
if isinstance(value, str):
return str(value)
return default
def checkInt(value, default):
"""Check if a variable is an integer.
"""
if allowNone and (value is None or value == "None"):
return None
try:
return int(value)
except Exception:
return default
def checkFloat(value, default, allowNone=False):
"""Check if a variable is a float or a None.
def checkFloat(value, default):
"""Check if a variable is a float.
"""
if allowNone and (value is None or value == "None"):
return None
try:
return float(value)
except Exception:
return default
def checkBool(value, default, allowNone=False):
"""Check if a variable is a boolean or a None.
def checkBool(value, default):
"""Check if a variable is a boolean.
"""
if allowNone and (value is None or value == "None"):
return None
if isinstance(value, str):
if isinstance(value, bool):
return value
elif isinstance(value, str):
if value == "True":
return True
elif value == "False":
return False
else:
return default
elif isinstance(value, int):
if value == 1:
return True
@@ -98,7 +100,6 @@ def checkBool(value, default, allowNone=False):
return False
else:
return default
return default
@@ -174,16 +175,6 @@ def hexToInt(value, default=0):
return default
def checkIntRange(value, first, last, default):
"""Check that an int is in a given range. If it isn't, return the
default value.
"""
if isinstance(value, int):
if value >= first and value <= last:
return value
return default
def minmax(value, minVal, maxVal):
"""Make sure an integer is between min and max value (inclusive).
"""
@@ -263,7 +254,7 @@ def splitVersionNumber(value):
and patch, and computes an integer value aabbcc.
"""
if not isinstance(value, str):
return [0, 0, 0, 0]
return 0, 0, 0, 0
vMajor = 0
vMinor = 0
@@ -282,7 +273,7 @@ def splitVersionNumber(value):
vInt = vMajor*10000 + vMinor*100 + vPatch
return [vMajor, vMinor, vPatch, vInt]
return vMajor, vMinor, vPatch, vInt
def transferCase(theSource, theTarget):
+3 -9
View File
@@ -668,23 +668,17 @@ class TagsIndex:
def tagHandle(self, tagKey):
"""Get the handle of a given tag.
"""
if tagKey in self._tags:
return self._tags.get(tagKey).get("handle")
return None
return self._tags.get(tagKey, {}).get("handle", None)
def tagHeading(self, tagKey):
"""Get the heading of a given tag.
"""
if tagKey in self._tags:
return self._tags.get(tagKey).get("heading")
return nwHeaders.TT_NONE
return self._tags.get(tagKey, {}).get("heading", nwHeaders.TT_NONE)
def tagClass(self, tagKey):
"""Get the class of a given tag.
"""
if tagKey in self._tags:
return self._tags.get(tagKey).get("class")
return None
return self._tags.get(tagKey, {}).get("class", None)
##
# Pack/Unpack
+1 -2
View File
@@ -188,8 +188,7 @@ class OptionState:
the default value.
"""
if group in self._theState:
if name in self._theState[group]:
return checkBool(self._theState[group].get(name, default), default)
return checkBool(self._theState[group].get(name, default), default)
return default
def getEnum(self, group, name, lookup, default):
+18 -18
View File
@@ -44,7 +44,7 @@ from novelwriter.core.document import NWDoc
from novelwriter.enum import nwItemType, nwItemClass, nwItemLayout, nwAlert
from novelwriter.error import logException
from novelwriter.common import (
checkString, checkBool, checkInt, isHandle, formatTimeStamp,
checkString, checkBool, checkInt, checkStringNone, isHandle, formatTimeStamp,
makeFileNameSafe, hexToInt, minmax, simplified
)
from novelwriter.constants import trConst, nwFiles, nwLabels
@@ -187,7 +187,7 @@ class NWProject:
return False
newDoc = NWDoc(self, tHandle)
if newDoc.readDocument().strip():
if (newDoc.readDocument() or "").strip():
return False
hshText = "#"*minmax(hLevel, 1, 4)
@@ -593,13 +593,13 @@ class NWProject:
if xItem.text is None:
continue
if xItem.tag == "name":
self.projName = checkString(simplified(xItem.text), "")
self.projName = simplified(checkString(xItem.text, ""))
logger.verbose("Working Title: '%s'", self.projName)
elif xItem.tag == "title":
self.bookTitle = checkString(simplified(xItem.text), "")
self.bookTitle = simplified(checkString(xItem.text, ""))
logger.verbose("Title is '%s'", self.bookTitle)
elif xItem.tag == "author":
author = checkString(simplified(xItem.text), "")
author = simplified(checkString(xItem.text, ""))
if author:
self.bookAuthors.append(author)
logger.verbose("Author: '%s'", author)
@@ -618,25 +618,25 @@ class NWProject:
if xItem.tag == "doBackup":
self.doBackup = checkBool(xItem.text, False)
elif xItem.tag == "language":
self.projLang = checkString(xItem.text, None, True)
self.projLang = checkStringNone(xItem.text, None)
elif xItem.tag == "spellCheck":
self.spellCheck = checkBool(xItem.text, False)
elif xItem.tag == "spellLang":
self.projSpell = checkString(xItem.text, None, True)
self.projSpell = checkStringNone(xItem.text, None)
elif xItem.tag == "lastEdited":
self.lastEdited = checkString(xItem.text, None, True)
self.lastEdited = checkStringNone(xItem.text, None)
elif xItem.tag == "lastViewed":
self.lastViewed = checkString(xItem.text, None, True)
self.lastViewed = checkStringNone(xItem.text, None)
elif xItem.tag == "lastNovel":
self.lastNovel = checkString(xItem.text, None, True)
self.lastNovel = checkStringNone(xItem.text, None)
elif xItem.tag == "lastOutline":
self.lastOutline = checkString(xItem.text, None, True)
self.lastOutline = checkStringNone(xItem.text, None)
elif xItem.tag == "lastWordCount":
self.lastWCount = checkInt(xItem.text, 0, False)
self.lastWCount = checkInt(xItem.text, 0)
elif xItem.tag == "novelWordCount":
self.lastNovelWC = checkInt(xItem.text, 0, False)
self.lastNovelWC = checkInt(xItem.text, 0)
elif xItem.tag == "notesWordCount":
self.lastNotesWC = checkInt(xItem.text, 0, False)
self.lastNotesWC = checkInt(xItem.text, 0)
elif xItem.tag == "status":
self.statusItems.unpackXML(xItem)
elif xItem.tag == "importance":
@@ -645,12 +645,12 @@ class NWProject:
for xEntry in xItem:
if xEntry.tag == "entry" and "key" in xEntry.attrib:
self.autoReplace[xEntry.attrib["key"]] = checkString(
xEntry.text, None, False
xEntry.text, "ERROR"
)
elif xItem.tag == "titleFormat":
titleFormat = self.titleFormat.copy()
for xEntry in xItem:
titleFormat[xEntry.tag] = checkString(xEntry.text, "", False)
titleFormat[xEntry.tag] = checkString(xEntry.text, "")
self.setTitleFormat(titleFormat)
elif xChild.tag == "content":
@@ -1091,7 +1091,7 @@ class NWProject:
def setSpellLang(self, theLang):
"""Set the project-specific spell check language.
"""
theLang = checkString(theLang, None, True)
theLang = checkStringNone(theLang, None)
if self.projSpell != theLang:
self.projSpell = theLang
self.setProjectChanged(True)
@@ -1101,7 +1101,7 @@ class NWProject:
def setProjectLang(self, theLang):
"""Set the project-specific language.
"""
theLang = checkString(theLang, None, True)
theLang = checkStringNone(theLang, None)
if self.projLang != theLang:
self.projLang = theLang
self._loadProjectLocalisation()
+4 -10
View File
@@ -304,16 +304,10 @@ class Tokenizer(ABC):
if self._theItem is None:
return False
self._theText = ""
if theText is not None:
# If the text is set, just use that
self._theText = theText
else:
# Otherwise, load it from file
theDoc = NWDoc(self.theProject, theHandle)
theText = theDoc.readDocument()
if theText:
self._theText = theText
if theText is None:
theText = NWDoc(self.theProject, theHandle).readDocument() or ""
self._theText = theText
docSize = len(self._theText)
if docSize > nwConst.MAX_DOCSIZE:
+2 -2
View File
@@ -39,7 +39,7 @@ from PyQt5.QtWidgets import (
from novelwriter.enum import nwAlert
from novelwriter.error import formatException
from novelwriter.common import formatTime, checkInt, checkIntRange, checkIntTuple
from novelwriter.common import formatTime, checkInt, checkIntTuple, minmax
from novelwriter.custom import QSwitch
from novelwriter.constants import nwConst, nwFiles
@@ -116,7 +116,7 @@ class GuiWritingStats(QDialog):
hHeader.setTextAlignment(self.C_IDLE, Qt.AlignRight)
hHeader.setTextAlignment(self.C_COUNT, Qt.AlignRight)
sortCol = checkIntRange(pOptions.getInt("GuiWritingStats", "sortCol", 0), 0, 2, 0)
sortCol = minmax(pOptions.getInt("GuiWritingStats", "sortCol", 0), 0, 2)
sortOrder = checkIntTuple(
pOptions.getInt("GuiWritingStats", "sortOrder", Qt.DescendingOrder),
(Qt.AscendingOrder, Qt.DescendingOrder), Qt.DescendingOrder
+53 -52
View File
@@ -29,8 +29,8 @@ from tools import writeFile
from novelwriter.guimain import GuiMain
from novelwriter.common import (
checkString, checkInt, checkFloat, checkBool, checkHandle, isHandle,
isTitleTag, isItemClass, isItemType, isItemLayout, hexToInt, checkIntRange,
checkStringNone, checkString, checkInt, checkFloat, checkBool, checkHandle,
isHandle, isTitleTag, isItemClass, isItemType, isItemLayout, hexToInt,
minmax, checkIntTuple, formatInt, formatTimeStamp, formatTime, simplified,
splitVersionNumber, transferCase, fuzzyTime, numberToRoman, jsonEncode,
readTextFile, makeFileNameSafe, ensureFolder, sha256sum, getGuiItem,
@@ -38,17 +38,29 @@ from novelwriter.common import (
)
@pytest.mark.base
def testBaseCommon_CheckStringNone():
"""Test the checkStringNone function.
"""
assert checkStringNone("Stuff", "NotNone") == "Stuff"
assert checkStringNone("None", "NotNone") is None
assert checkStringNone(None, "NotNone") is None
assert checkStringNone(1, "NotNone") == "NotNone"
assert checkStringNone(1.0, "NotNone") == "NotNone"
assert checkStringNone(True, "NotNone") == "NotNone"
# END Test testBaseCommon_CheckStringNone
@pytest.mark.base
def testBaseCommon_CheckString():
"""Test the checkString function.
"""
assert checkString(None, "NotNone", True) is None
assert checkString("None", "NotNone", True) is None
assert checkString("None", "NotNone", False) == "None"
assert checkString(None, "NotNone", False) == "NotNone"
assert checkString(1, "NotNone", False) == "NotNone"
assert checkString(1.0, "NotNone", False) == "NotNone"
assert checkString(True, "NotNone", False) == "NotNone"
assert checkString("None", "NotNone") == "None"
assert checkString(None, "NotNone") == "NotNone"
assert checkString(1, "NotNone") == "NotNone"
assert checkString(1.0, "NotNone") == "NotNone"
assert checkString(True, "NotNone") == "NotNone"
# END Test testBaseCommon_CheckString
@@ -57,12 +69,12 @@ def testBaseCommon_CheckString():
def testBaseCommon_CheckInt():
"""Test the checkInt function.
"""
assert checkInt(None, 3, True) is None
assert checkInt("None", 3, True) is None
assert checkInt(None, 3, False) == 3
assert checkInt(1, 3, False) == 1
assert checkInt(1.0, 3, False) == 1
assert checkInt(True, 3, False) == 1
assert checkInt(None, 3) == 3
assert checkInt("1", 3) == 1
assert checkInt("1.0", 3) == 3
assert checkInt(1, 3) == 1
assert checkInt(1.0, 3) == 1
assert checkInt(True, 3) == 1
# END Test testBaseCommon_CheckInt
@@ -71,12 +83,12 @@ def testBaseCommon_CheckInt():
def testBaseCommon_CheckFloat():
"""Test the checkFloat function.
"""
assert checkFloat(None, 3.0, True) is None
assert checkFloat("None", 3.0, True) is None
assert checkFloat(None, 3.0, False) == 3.0
assert checkFloat(1, 3.0, False) == 1.0
assert checkFloat(1.0, 3.0, False) == 1.0
assert checkFloat(True, 3.0, False) == 1.0
assert checkFloat(None, 3.0) == 3.0
assert checkFloat("1", 3.0) == 1.0
assert checkFloat("1.0", 3.0) == 1.0
assert checkFloat(1, 3.0) == 1.0
assert checkFloat(1.0, 3.0) == 1.0
assert checkFloat(True, 3.0) == 1.0
# END Test testBaseCommon_CheckInt
@@ -85,17 +97,18 @@ def testBaseCommon_CheckFloat():
def testBaseCommon_CheckBool():
"""Test the checkBool function.
"""
assert checkBool(None, 3, True) is None
assert checkBool("None", 3, True) is None
assert checkBool("True", False, False) is True
assert checkBool("False", True, False) is False
assert checkBool("Boo", None, False) is None
assert checkBool(0, None, False) is False
assert checkBool(1, None, False) is True
assert checkBool(2, None, False) is None
assert checkBool(0.0, None, False) is None
assert checkBool(1.0, None, False) is None
assert checkBool(2.0, None, False) is None
assert checkBool("True", False) is True
assert checkBool("False", True) is False
assert checkBool("Boo", False) is False
assert checkBool("Boo", True) is True
assert checkBool(0, True) is False
assert checkBool(1, False) is True
assert checkBool(2, True) is True
assert checkBool(2, False) is False
assert checkBool(0.0, True) is True
assert checkBool(1.0, False) is False
assert checkBool(2.0, True) is True
assert checkBool(2.0, False) is False
# END Test testBaseCommon_CheckBool
@@ -229,18 +242,6 @@ def testBaseCommon_HexToInt():
# END Test testBaseCommon_HexToInt
@pytest.mark.base
def testBaseCommon_CheckIntRange():
"""Test the checkIntRange function.
"""
assert checkIntRange(5, 0, 9, 3) == 5
assert checkIntRange(5, 0, 4, 3) == 3
assert checkIntRange(5, 0, 5, 3) == 5
assert checkIntRange(0, 0, 5, 3) == 0
# END Test testBaseCommon_CheckIntRange
@pytest.mark.base
def testBaseCommon_MinMax():
"""Test the minmax function.
@@ -311,16 +312,16 @@ def testBaseCommon_SplitVersionNumber():
"""Test the splitVersionNumber function.
"""
# OK Values
assert splitVersionNumber("1") == [1, 0, 0, 10000]
assert splitVersionNumber("1.2") == [1, 2, 0, 10200]
assert splitVersionNumber("1.2.3") == [1, 2, 3, 10203]
assert splitVersionNumber("1.2.3.4") == [1, 2, 3, 10203]
assert splitVersionNumber("99.99.99") == [99, 99, 99, 999999]
assert splitVersionNumber("1") == (1, 0, 0, 10000)
assert splitVersionNumber("1.2") == (1, 2, 0, 10200)
assert splitVersionNumber("1.2.3") == (1, 2, 3, 10203)
assert splitVersionNumber("1.2.3.4") == (1, 2, 3, 10203)
assert splitVersionNumber("99.99.99") == (99, 99, 99, 999999)
# Failed Values
assert splitVersionNumber(None) == [0, 0, 0, 0]
assert splitVersionNumber(1234) == [0, 0, 0, 0]
assert splitVersionNumber("1.2abc") == [1, 0, 0, 10000]
assert splitVersionNumber(None) == (0, 0, 0, 0)
assert splitVersionNumber(1234) == (0, 0, 0, 0)
assert splitVersionNumber("1.2abc") == (1, 0, 0, 10000)
# END Test testBaseCommon_SplitVersionNumber