Skip to content

Commit

Permalink
directnotify: annotate types (#1527)
Browse files Browse the repository at this point in the history
  • Loading branch information
WMOkiishi committed Oct 9, 2023
1 parent 526994c commit 1ca0e3f
Show file tree
Hide file tree
Showing 9 changed files with 333 additions and 96 deletions.
62 changes: 35 additions & 27 deletions direct/src/directnotify/DirectNotify.py
Expand Up @@ -2,6 +2,10 @@
DirectNotify module: this module contains the DirectNotify class
"""

from __future__ import annotations

from panda3d.core import StreamWriter

from . import Notifier
from . import Logger

Expand All @@ -12,49 +16,51 @@ class DirectNotify:
mulitple notify categories via a dictionary of Notifiers.
"""

def __init__(self):
def __init__(self) -> None:
"""
DirectNotify class keeps a dictionary of Notfiers
"""
self.__categories = {}
self.__categories: dict[str, Notifier.Notifier] = {}
# create a default log file
self.logger = Logger.Logger()

# This will get filled in later by ShowBase.py with a
# C++-level StreamWriter object for writing to standard
# output.
self.streamWriter = None
self.streamWriter: StreamWriter | None = None

def __str__(self):
def __str__(self) -> str:
"""
Print handling routine
"""
return "DirectNotify categories: %s" % (self.__categories)

#getters and setters
def getCategories(self):
def getCategories(self) -> list[str]:
"""
Return list of category dictionary keys
"""
return list(self.__categories.keys())

def getCategory(self, categoryName):
def getCategory(self, categoryName: str) -> Notifier.Notifier | None:
"""getCategory(self, string)
Return the category with given name if present, None otherwise
"""
return self.__categories.get(categoryName, None)

def newCategory(self, categoryName, logger=None):
def newCategory(self, categoryName: str, logger: Logger.Logger | None = None) -> Notifier.Notifier:
"""newCategory(self, string)
Make a new notify category named categoryName. Return new category
if no such category exists, else return existing category
"""
if categoryName not in self.__categories:
self.__categories[categoryName] = Notifier.Notifier(categoryName, logger)
self.setDconfigLevel(categoryName)
return self.getCategory(categoryName)
notifier = self.getCategory(categoryName)
assert notifier is not None
return notifier

def setDconfigLevel(self, categoryName):
def setDconfigLevel(self, categoryName: str) -> None:
"""
Check to see if this category has a dconfig variable
to set the notify severity and then set that level. You cannot
Expand All @@ -77,40 +83,42 @@ def setDconfigLevel(self, categoryName):
level = 'error'

category = self.getCategory(categoryName)
assert category is not None, f'failed to find category: {categoryName!r}'
# Note - this print statement is making it difficult to
# achieve "no output unless there's an error" operation - Josh
# print ("Setting DirectNotify category: " + categoryName +
# " to severity: " + level)
if level == "error":
category.setWarning(0)
category.setInfo(0)
category.setDebug(0)
category.setWarning(False)
category.setInfo(False)
category.setDebug(False)
elif level == "warning":
category.setWarning(1)
category.setInfo(0)
category.setDebug(0)
category.setWarning(True)
category.setInfo(False)
category.setDebug(False)
elif level == "info":
category.setWarning(1)
category.setInfo(1)
category.setDebug(0)
category.setWarning(True)
category.setInfo(True)
category.setDebug(False)
elif level == "debug":
category.setWarning(1)
category.setInfo(1)
category.setDebug(1)
category.setWarning(True)
category.setInfo(True)
category.setDebug(True)
else:
print("DirectNotify: unknown notify level: " + str(level)
+ " for category: " + str(categoryName))

def setDconfigLevels(self):
def setDconfigLevels(self) -> None:
for categoryName in self.getCategories():
self.setDconfigLevel(categoryName)

def setVerbose(self):
def setVerbose(self) -> None:
for categoryName in self.getCategories():
category = self.getCategory(categoryName)
category.setWarning(1)
category.setInfo(1)
category.setDebug(1)
assert category is not None
category.setWarning(True)
category.setInfo(True)
category.setDebug(True)

def popupControls(self, tl = None):
# Don't use a regular import, to prevent ModuleFinder from picking
Expand All @@ -119,5 +127,5 @@ def popupControls(self, tl = None):
NotifyPanel = importlib.import_module('direct.tkpanels.NotifyPanel')
NotifyPanel.NotifyPanel(self, tl)

def giveNotify(self,cls):
def giveNotify(self, cls) -> None:
cls.notify = self.newCategory(cls.__name__)
24 changes: 14 additions & 10 deletions direct/src/directnotify/Logger.py
@@ -1,52 +1,56 @@
"""Logger module: contains the logger class which creates and writes
data to log files on disk"""

from __future__ import annotations

import io
import time
import math


class Logger:
def __init__(self, fileName="log"):
def __init__(self, fileName: str = "log") -> None:
"""
Logger constructor
"""
self.__timeStamp = 1
self.__timeStamp = True
self.__startTime = 0.0
self.__logFile = None
self.__logFile: io.TextIOWrapper | None = None
self.__logFileName = fileName

def setTimeStamp(self, enable):
def setTimeStamp(self, enable: bool) -> None:
"""
Toggle time stamp printing with log entries on and off
"""
self.__timeStamp = enable

def getTimeStamp(self):
def getTimeStamp(self) -> bool:
"""
Return whether or not we are printing time stamps with log entries
"""
return self.__timeStamp

# logging control

def resetStartTime(self):
def resetStartTime(self) -> None:
"""
Reset the start time of the log file for time stamps
"""
self.__startTime = time.time()

def log(self, entryString):
def log(self, entryString: str) -> None:
"""log(self, string)
Print the given string to the log file"""
if self.__logFile is None:
self.__openLogFile()
assert self.__logFile is not None
if self.__timeStamp:
self.__logFile.write(self.__getTimeStamp())
self.__logFile.write(entryString + '\n')

# logging functions

def __openLogFile(self):
def __openLogFile(self) -> None:
"""
Open a file for logging error/warning messages
"""
Expand All @@ -56,14 +60,14 @@ def __openLogFile(self):
logFileName = self.__logFileName + "." + st
self.__logFile = open(logFileName, "w")

def __closeLogFile(self):
def __closeLogFile(self) -> None:
"""
Close the error/warning output file
"""
if self.__logFile is not None:
self.__logFile.close()

def __getTimeStamp(self):
def __getTimeStamp(self) -> str:
"""
Return the offset between current time and log file startTime
"""
Expand Down

0 comments on commit 1ca0e3f

Please sign in to comment.