direct: Annotate functions called directly by top-level code (#1727)

This commit is contained in:
WMOkiishi 2025-04-06 02:10:15 -06:00 committed by GitHub
parent 6274b478aa
commit 4b4fa03895
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 38 additions and 23 deletions

View File

@ -48,7 +48,7 @@ class ClockDelta(DirectObject.DirectObject):
notify = DirectNotifyGlobal.directNotify.newCategory('ClockDelta')
def __init__(self):
def __init__(self) -> None:
self.globalClock = ClockObject.getGlobalClock()
# self.delta is the relative delta from our clock to the

View File

@ -1,15 +1,19 @@
from __future__ import annotations
__all__ = ["Dtool_ObjectToDict", "Dtool_funcToMethod"]
from collections.abc import Callable
def Dtool_ObjectToDict(cls, name, obj):
cls.DtoolClassDict[name] = obj
def Dtool_funcToMethod(func, cls, method_name=None):
def Dtool_funcToMethod(func: Callable, cls, method_name: str | None = None) -> None:
"""Adds func to class so it is an accessible method; use method_name to specify the name to be used for calling the method.
The new method is accessible to any instance immediately."""
func.__func__ = func
func.__self__ = None
func.__func__ = func # type: ignore[attr-defined]
func.__self__ = None # type: ignore[attr-defined]
if not method_name:
method_name = func.__name__
cls.DtoolClassDict[method_name] = func

View File

@ -41,13 +41,17 @@ import time
import builtins
import importlib
import functools
from typing import Callable
from collections.abc import Callable, Container, Iterable, Mapping
from typing import Any, Generic, TypeVar
__report_indent = 3
from panda3d.core import ConfigVariableBool, ConfigVariableString, ConfigFlags
from panda3d.core import ClockObject
_T = TypeVar('_T')
_KT = TypeVar('_KT')
_VT = TypeVar('_VT')
## with one integer positional arg, this uses about 4/5 of the memory of the Functor class below
#def Functor(function, *args, **kArgs):
@ -100,9 +104,9 @@ class Functor:
return s
class Stack:
def __init__(self):
self.__list = []
class Stack(Generic[_T]):
def __init__(self) -> None:
self.__list: list[_T] = []
def push(self, item):
self.__list.append(item)
@ -411,7 +415,7 @@ def list2dict(L, value=None):
return dict([(k, value) for k in L])
def listToIndex2item(L):
def listToIndex2item(L: Iterable[_VT]) -> dict[int, _VT]:
"""converts list to dict of list index->list item"""
d = {}
for i, item in enumerate(L):
@ -422,7 +426,7 @@ def listToIndex2item(L):
assert listToIndex2item(['a','b']) == {0: 'a', 1: 'b',}
def listToItem2index(L):
def listToItem2index(L: Iterable[_KT]) -> dict[_KT, int]:
"""converts list to dict of list item->list index
This is lossy if there are duplicate list items"""
d = {}
@ -451,7 +455,7 @@ def invertDict(D, lossy=False):
return n
def invertDictLossless(D):
def invertDictLossless(D: Mapping[_KT, _VT]) -> dict[_VT, list[_KT]]:
"""similar to invertDict, but values of new dict are lists of keys from
old dict. No information is lost.
@ -459,7 +463,7 @@ def invertDictLossless(D):
>>> invertDictLossless(old)
{1: ['key1'], 2: ['key2', 'keyA']}
"""
n = {}
n: dict[_VT, list[_KT]] = {}
for key, value in D.items():
n.setdefault(value, [])
n[value].append(key)
@ -706,7 +710,7 @@ if __debug__:
movedDumpFuncs: list[Callable] = []
movedLoadFuncs: list[Callable] = []
profileFilenames = set()
profileFilenameList = Stack()
profileFilenameList = Stack[str]()
profileFilename2file = {}
profileFilename2marshalData = {}
@ -1278,7 +1282,7 @@ def randInt32(rng=random.random):
class SerialNumGen:
"""generates serial numbers"""
def __init__(self, start=None):
def __init__(self, start: int | None = None) -> None:
if start is None:
start = 0
self.__counter = start-1
@ -1305,7 +1309,7 @@ class SerialMaskedGen(SerialNumGen):
_serialGen = SerialNumGen()
def serialNum():
def serialNum() -> int:
return _serialGen.next()
@ -1588,7 +1592,7 @@ class ScratchPad:
class Sync:
_SeriesGen = SerialNumGen()
def __init__(self, name, other=None):
def __init__(self, name: str, other: Sync | None = None) -> None:
self._name = name
if other is None:
self._series = self._SeriesGen.next()
@ -1972,7 +1976,13 @@ def pstatcollect(scope, level = None):
__report_indent = 0
def report(types = [], prefix = '', xform = None, notifyFunc = None, dConfigParam = []):
def report(
types: Container[str] = [],
prefix: str = '',
xform: Callable[[Any], object] | None = None,
notifyFunc: Callable[[str], object] | None = None,
dConfigParam: str | list[str] | tuple[str, ...] = [],
) -> Callable[[_T], _T]:
"""
This is a decorator generating function. Use is similar to
a @decorator, except you must be sure to call it as a function.
@ -2031,7 +2041,7 @@ def report(types = [], prefix = '', xform = None, notifyFunc = None, dConfigPara
return f
try:
if not __dev__ and not ConfigVariableBool('force-reports', False):
if not __dev__ and not ConfigVariableBool('force-reports', False): # type: ignore[name-defined]
return decorator
# determine whether we should use the decorator
@ -2041,6 +2051,7 @@ def report(types = [], prefix = '', xform = None, notifyFunc = None, dConfigPara
if not dConfigParam:
doPrint = True
else:
dConfigParams: list[str] | tuple[str, ...]
if not isinstance(dConfigParam, (list,tuple)):
dConfigParams = (dConfigParam,)
else:
@ -2070,7 +2081,7 @@ def report(types = [], prefix = '', xform = None, notifyFunc = None, dConfigPara
globalClockDelta = importlib.import_module("direct.distributed.ClockDelta").globalClockDelta
def decorator(f):
def decorator(f): # type: ignore[no-redef]
def wrap(*args, **kwargs):
if args:
rArgs = [args[0].__class__.__name__ + ', ']

View File

@ -382,7 +382,7 @@ class ShowBase(DirectObject.DirectObject):
#: yourself every frame.
self.cTrav: CollisionTraverser | Literal[0] = 0
self.shadowTrav: CollisionTraverser | Literal[0] = 0
self.cTravStack = Stack()
self.cTravStack = Stack[CollisionTraverser]()
# Ditto for an AppTraverser.
self.appTrav: Any | Literal[0] = 0

View File

@ -250,7 +250,7 @@ def exit():
raise SystemExit
def allocate_lock():
def allocate_lock() -> LockType:
return LockType()

View File

@ -654,7 +654,7 @@ class _Timer(Thread):
class _MainThread(Thread):
def __init__(self):
def __init__(self) -> None:
Thread.__init__(self, name="MainThread")
self._Thread__started = True
_active_limbo_lock.acquire()

View File

@ -48,7 +48,7 @@ def inspectorFor(anObject):
### initializing
def initializeInspectorMap():
def initializeInspectorMap() -> None:
global _InspectorMap
notFinishedTypes = ['BufferType', 'EllipsisType', 'FrameType', 'TracebackType', 'XRangeType']