direct: Get direct to pass a mypy check

Closes #1476
This commit is contained in:
WMOkiishi 2023-08-04 14:31:11 +02:00 committed by rdb
parent ab93d88f1b
commit 32edfa43fd
44 changed files with 352 additions and 244 deletions

23
.github/workflows/mypy.yml vendored Normal file
View File

@ -0,0 +1,23 @@
name: Run Mypy
on: [push, pull_request]
jobs:
mypy:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ['3.8', '3.11']
fail-fast: false
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install mypy==1.4.0
- name: Run mypy on direct
run: python tests/run_mypy.py

View File

@ -15,7 +15,7 @@ to and may be replaced by the following code:
base = ShowBase() base = ShowBase()
""" """
__all__ = [] __all__ = ()
if __debug__: if __debug__:
print('Using deprecated DirectStart interface.') print('Using deprecated DirectStart interface.')

View File

@ -6,7 +6,7 @@ from direct.showbase import ShowBase
base = ShowBase.ShowBase() base = ShowBase.ShowBase()
# Put an axis in the world: # Put an axis in the world:
base.loader.loadModel("models/misc/xyzAxis").reparentTo(render) base.loader.loadModel("models/misc/xyzAxis").reparentTo(base.render)
base.camera.setPosHpr(0, -10.0, 0, 0, 0, 0) base.camera.setPosHpr(0, -10.0, 0, 0, 0, 0)
base.camLens.setFov(52.0) base.camLens.setFov(52.0)

View File

@ -8,7 +8,7 @@ from direct.showbase import ThreeUpShow
base = ThreeUpShow.ThreeUpShow() base = ThreeUpShow.ThreeUpShow()
# Put an axis in the world: # Put an axis in the world:
base.loader.loadModel("models/misc/xyzAxis").reparentTo(render) base.loader.loadModel("models/misc/xyzAxis").reparentTo(base.render)
base.camera.setPosHpr(0, -10.0, 0, 0, 0, 0) base.camera.setPosHpr(0, -10.0, 0, 0, 0, 0)
base.camLens.setFov(52.0) base.camLens.setFov(52.0)

View File

@ -41,8 +41,12 @@ class DirectJoybox(DirectObject):
xyzMultiplier = 1.0 xyzMultiplier = 1.0
hprMultiplier = 1.0 hprMultiplier = 1.0
def __init__(self, device = 'CerealBox', nodePath = base.direct.camera, def __init__(self, device = 'CerealBox', nodePath = None, headingNP = None):
headingNP = base.direct.camera): from direct.showbase.ShowBaseGlobal import base
if nodePath is None:
nodePath = base.direct.camera
if headingNP is None:
headingNP = base.direct.camera
# See if device manager has been initialized # See if device manager has been initialized
if base.direct.deviceManager is None: if base.direct.deviceManager is None:
base.direct.deviceManager = DirectDeviceManager() base.direct.deviceManager = DirectDeviceManager()

View File

@ -1,3 +1,5 @@
from __future__ import annotations
#from otp.ai.AIBaseGlobal import * #from otp.ai.AIBaseGlobal import *
from direct.directnotify import DirectNotifyGlobal from direct.directnotify import DirectNotifyGlobal
from direct.showbase.DirectObject import DirectObject from direct.showbase.DirectObject import DirectObject
@ -39,7 +41,7 @@ class AsyncRequest(DirectObject):
will be called again when the new self.neededObjects is complete. You will be called again when the new self.neededObjects is complete. You
may repeat this as necessary. may repeat this as necessary.
""" """
_asyncRequests = {} _asyncRequests: dict[int, AsyncRequest] = {}
notify = DirectNotifyGlobal.directNotify.newCategory('AsyncRequest') notify = DirectNotifyGlobal.directNotify.newCategory('AsyncRequest')

View File

@ -20,3 +20,10 @@ class CachedDOData:
# override and destroy the cached data # override and destroy the cached data
# cached data is typically created by the DistributedObject and destroyed here # cached data is typically created by the DistributedObject and destroyed here
pass pass
# These next two methods tell mypy to allow arbitrary attributes.
def __getattribute__(self, name: str):
return object.__getattribute__(self, name)
def __setattr__(self, name: str, value) -> None:
object.__setattr__(self, name, value)

View File

@ -299,7 +299,7 @@ class DistributedObjectAI(DistributedObjectBase):
# setLocation destroys self._zoneData if we move away to # setLocation destroys self._zoneData if we move away to
# a different zone # a different zone
if self._zoneData is None: if self._zoneData is None:
from otp.ai.AIZoneData import AIZoneData from otp.ai.AIZoneData import AIZoneData # type: ignore[import]
self._zoneData = AIZoneData(self.air, self.parentId, self.zoneId) self._zoneData = AIZoneData(self.air, self.parentId, self.zoneId)
return self._zoneData return self._zoneData
@ -489,7 +489,7 @@ class DistributedObjectAI(DistributedObjectBase):
# simultaneously on different lists of avatars, although they # simultaneously on different lists of avatars, although they
# should have different names. # should have different names.
from otp.ai import Barrier from otp.ai import Barrier # type: ignore[import]
context = self.__nextBarrierContext context = self.__nextBarrierContext
# We assume the context number is passed as a uint16. # We assume the context number is passed as a uint16.
self.__nextBarrierContext = (self.__nextBarrierContext + 1) & 0xffff self.__nextBarrierContext = (self.__nextBarrierContext + 1) & 0xffff

View File

@ -424,7 +424,7 @@ class DistributedObjectUD(DistributedObjectBase):
# simultaneously on different lists of avatars, although they # simultaneously on different lists of avatars, although they
# should have different names. # should have different names.
from otp.ai import Barrier from otp.ai import Barrier # type: ignore[import]
context = self.__nextBarrierContext context = self.__nextBarrierContext
# We assume the context number is passed as a uint16. # We assume the context number is passed as a uint16.
self.__nextBarrierContext = (self.__nextBarrierContext + 1) & 0xffff self.__nextBarrierContext = (self.__nextBarrierContext + 1) & 0xffff

View File

@ -7,6 +7,8 @@ zone, remove interest in that zone.
p.s. A great deal of this code is just code moved from ClientRepository.py. p.s. A great deal of this code is just code moved from ClientRepository.py.
""" """
from __future__ import annotations
from panda3d.core import ConfigVariableBool from panda3d.core import ConfigVariableBool
from .MsgTypes import CLIENT_ADD_INTEREST, CLIENT_ADD_INTEREST_MULTIPLE, CLIENT_REMOVE_INTEREST from .MsgTypes import CLIENT_ADD_INTEREST, CLIENT_ADD_INTEREST_MULTIPLE, CLIENT_REMOVE_INTEREST
from direct.showbase import DirectObject from direct.showbase import DirectObject
@ -98,9 +100,9 @@ class DoInterestManager(DirectObject.DirectObject):
_ContextIdSerialNum = 100 _ContextIdSerialNum = 100
_ContextIdMask = 0x3FFFFFFF # avoid making Python create a long _ContextIdMask = 0x3FFFFFFF # avoid making Python create a long
_interests = {} _interests: dict[int, InterestState] = {}
if __debug__: if __debug__:
_debug_interestHistory = [] _debug_interestHistory: list[tuple] = []
_debug_maxDescriptionLen = 40 _debug_maxDescriptionLen = 40
_SerialGen = SerialNumGen() _SerialGen = SerialNumGen()

View File

@ -1,3 +1,5 @@
from __future__ import annotations
from panda3d.core import NodePath from panda3d.core import NodePath
# #
@ -13,8 +15,8 @@ from panda3d.core import NodePath
class GridParent: class GridParent:
# this lets GridParents share CellOrigins # this lets GridParents share CellOrigins
GridZone2CellOrigin = {} GridZone2CellOrigin: dict[tuple, NodePath] = {}
GridZone2count = {} GridZone2count: dict[tuple, int] = {}
@staticmethod @staticmethod
def getCellOrigin(grid, zoneId): def getCellOrigin(grid, zoneId):
tup = (grid, zoneId) tup = (grid, zoneId)

View File

@ -1,143 +1,145 @@
"""MsgTypes module: contains distributed object message types""" """MsgTypes module: contains distributed object message types"""
from __future__ import annotations
from direct.showbase.PythonUtil import invertDictLossless from direct.showbase.PythonUtil import invertDictLossless
MsgName2Id = { CLIENT_HELLO = 1
'CLIENT_HELLO': 1, CLIENT_HELLO_RESP = 2
'CLIENT_HELLO_RESP': 2,
# Sent by the client when it's leaving. # Sent by the client when it's leaving.
'CLIENT_DISCONNECT': 3, CLIENT_DISCONNECT = 3
# Sent by the server when it is dropping the connection deliberately. # Sent by the server when it is dropping the connection deliberately.
'CLIENT_EJECT': 4, CLIENT_EJECT = 4
'CLIENT_HEARTBEAT': 5, CLIENT_HEARTBEAT = 5
'CLIENT_OBJECT_SET_FIELD': 120, CLIENT_OBJECT_SET_FIELD = 120
'CLIENT_OBJECT_SET_FIELDS': 121, CLIENT_OBJECT_SET_FIELDS = 121
'CLIENT_OBJECT_LEAVING': 132, CLIENT_OBJECT_LEAVING = 132
'CLIENT_OBJECT_LEAVING_OWNER': 161, CLIENT_OBJECT_LEAVING_OWNER = 161
'CLIENT_ENTER_OBJECT_REQUIRED': 142, CLIENT_ENTER_OBJECT_REQUIRED = 142
'CLIENT_ENTER_OBJECT_REQUIRED_OTHER': 143, CLIENT_ENTER_OBJECT_REQUIRED_OTHER = 143
'CLIENT_ENTER_OBJECT_REQUIRED_OWNER': 172, CLIENT_ENTER_OBJECT_REQUIRED_OWNER = 172
'CLIENT_ENTER_OBJECT_REQUIRED_OTHER_OWNER': 173, CLIENT_ENTER_OBJECT_REQUIRED_OTHER_OWNER = 173
'CLIENT_DONE_INTEREST_RESP': 204, CLIENT_DONE_INTEREST_RESP = 204
'CLIENT_ADD_INTEREST': 200, CLIENT_ADD_INTEREST = 200
'CLIENT_ADD_INTEREST_MULTIPLE': 201, CLIENT_ADD_INTEREST_MULTIPLE = 201
'CLIENT_REMOVE_INTEREST': 203, CLIENT_REMOVE_INTEREST = 203
'CLIENT_OBJECT_LOCATION': 140, CLIENT_OBJECT_LOCATION = 140
# These are sent internally inside the Astron cluster. # These are sent internally inside the Astron cluster.
# Message Director control messages: # Message Director control messages:
'CONTROL_CHANNEL': 1, CONTROL_CHANNEL = 1
'CONTROL_ADD_CHANNEL': 9000, CONTROL_ADD_CHANNEL = 9000
'CONTROL_REMOVE_CHANNEL': 9001, CONTROL_REMOVE_CHANNEL = 9001
'CONTROL_ADD_RANGE': 9002, CONTROL_ADD_RANGE = 9002
'CONTROL_REMOVE_RANGE': 9003, CONTROL_REMOVE_RANGE = 9003
'CONTROL_ADD_POST_REMOVE': 9010, CONTROL_ADD_POST_REMOVE = 9010
'CONTROL_CLEAR_POST_REMOVES': 9011, CONTROL_CLEAR_POST_REMOVES = 9011
# State Server control messages: # State Server control messages:
'STATESERVER_CREATE_OBJECT_WITH_REQUIRED': 2000, STATESERVER_CREATE_OBJECT_WITH_REQUIRED = 2000
'STATESERVER_CREATE_OBJECT_WITH_REQUIRED_OTHER': 2001, STATESERVER_CREATE_OBJECT_WITH_REQUIRED_OTHER = 2001
'STATESERVER_DELETE_AI_OBJECTS': 2009, STATESERVER_DELETE_AI_OBJECTS = 2009
'STATESERVER_OBJECT_GET_FIELD': 2010, STATESERVER_OBJECT_GET_FIELD = 2010
'STATESERVER_OBJECT_GET_FIELD_RESP': 2011, STATESERVER_OBJECT_GET_FIELD_RESP = 2011
'STATESERVER_OBJECT_GET_FIELDS': 2012, STATESERVER_OBJECT_GET_FIELDS = 2012
'STATESERVER_OBJECT_GET_FIELDS_RESP': 2013, STATESERVER_OBJECT_GET_FIELDS_RESP = 2013
'STATESERVER_OBJECT_GET_ALL': 2014, STATESERVER_OBJECT_GET_ALL = 2014
'STATESERVER_OBJECT_GET_ALL_RESP': 2015, STATESERVER_OBJECT_GET_ALL_RESP = 2015
'STATESERVER_OBJECT_SET_FIELD': 2020, STATESERVER_OBJECT_SET_FIELD = 2020
'STATESERVER_OBJECT_SET_FIELDS': 2021, STATESERVER_OBJECT_SET_FIELDS = 2021
'STATESERVER_OBJECT_DELETE_FIELD_RAM': 2030, STATESERVER_OBJECT_DELETE_FIELD_RAM = 2030
'STATESERVER_OBJECT_DELETE_FIELDS_RAM': 2031, STATESERVER_OBJECT_DELETE_FIELDS_RAM = 2031
'STATESERVER_OBJECT_DELETE_RAM': 2032, STATESERVER_OBJECT_DELETE_RAM = 2032
'STATESERVER_OBJECT_SET_LOCATION': 2040, STATESERVER_OBJECT_SET_LOCATION = 2040
'STATESERVER_OBJECT_CHANGING_LOCATION': 2041, STATESERVER_OBJECT_CHANGING_LOCATION = 2041
'STATESERVER_OBJECT_ENTER_LOCATION_WITH_REQUIRED': 2042, STATESERVER_OBJECT_ENTER_LOCATION_WITH_REQUIRED = 2042
'STATESERVER_OBJECT_ENTER_LOCATION_WITH_REQUIRED_OTHER': 2043, STATESERVER_OBJECT_ENTER_LOCATION_WITH_REQUIRED_OTHER = 2043
'STATESERVER_OBJECT_GET_LOCATION': 2044, STATESERVER_OBJECT_GET_LOCATION = 2044
'STATESERVER_OBJECT_GET_LOCATION_RESP': 2045, STATESERVER_OBJECT_GET_LOCATION_RESP = 2045
'STATESERVER_OBJECT_SET_AI': 2050, STATESERVER_OBJECT_SET_AI = 2050
'STATESERVER_OBJECT_CHANGING_AI': 2051, STATESERVER_OBJECT_CHANGING_AI = 2051
'STATESERVER_OBJECT_ENTER_AI_WITH_REQUIRED': 2052, STATESERVER_OBJECT_ENTER_AI_WITH_REQUIRED = 2052
'STATESERVER_OBJECT_ENTER_AI_WITH_REQUIRED_OTHER': 2053, STATESERVER_OBJECT_ENTER_AI_WITH_REQUIRED_OTHER = 2053
'STATESERVER_OBJECT_GET_AI': 2054, STATESERVER_OBJECT_GET_AI = 2054
'STATESERVER_OBJECT_GET_AI_RESP': 2055, STATESERVER_OBJECT_GET_AI_RESP = 2055
'STATESERVER_OBJECT_SET_OWNER': 2060, STATESERVER_OBJECT_SET_OWNER = 2060
'STATESERVER_OBJECT_CHANGING_OWNER': 2061, STATESERVER_OBJECT_CHANGING_OWNER = 2061
'STATESERVER_OBJECT_ENTER_OWNER_WITH_REQUIRED': 2062, STATESERVER_OBJECT_ENTER_OWNER_WITH_REQUIRED = 2062
'STATESERVER_OBJECT_ENTER_OWNER_WITH_REQUIRED_OTHER': 2063, STATESERVER_OBJECT_ENTER_OWNER_WITH_REQUIRED_OTHER = 2063
'STATESERVER_OBJECT_GET_OWNER': 2064, STATESERVER_OBJECT_GET_OWNER = 2064
'STATESERVER_OBJECT_GET_OWNER_RESP': 2065, STATESERVER_OBJECT_GET_OWNER_RESP = 2065
'STATESERVER_OBJECT_GET_ZONE_OBJECTS': 2100, STATESERVER_OBJECT_GET_ZONE_OBJECTS = 2100
'STATESERVER_OBJECT_GET_ZONES_OBJECTS': 2102, STATESERVER_OBJECT_GET_ZONES_OBJECTS = 2102
'STATESERVER_OBJECT_GET_CHILDREN': 2104, STATESERVER_OBJECT_GET_CHILDREN = 2104
'STATESERVER_OBJECT_GET_ZONE_COUNT': 2110, STATESERVER_OBJECT_GET_ZONE_COUNT = 2110
'STATESERVER_OBJECT_GET_ZONE_COUNT_RESP': 2111, STATESERVER_OBJECT_GET_ZONE_COUNT_RESP = 2111
'STATESERVER_OBJECT_GET_ZONES_COUNT': 2112, STATESERVER_OBJECT_GET_ZONES_COUNT = 2112
'STATESERVER_OBJECT_GET_ZONES_COUNT_RESP': 2113, STATESERVER_OBJECT_GET_ZONES_COUNT_RESP = 2113
'STATESERVER_OBJECT_GET_CHILD_COUNT': 2114, STATESERVER_OBJECT_GET_CHILD_COUNT = 2114
'STATESERVER_OBJECT_GET_CHILD_COUNT_RESP': 2115, STATESERVER_OBJECT_GET_CHILD_COUNT_RESP = 2115
'STATESERVER_OBJECT_DELETE_ZONE': 2120, STATESERVER_OBJECT_DELETE_ZONE = 2120
'STATESERVER_OBJECT_DELETE_ZONES': 2122, STATESERVER_OBJECT_DELETE_ZONES = 2122
'STATESERVER_OBJECT_DELETE_CHILDREN': 2124, STATESERVER_OBJECT_DELETE_CHILDREN = 2124
# DBSS-backed-object messages: # DBSS-backed-object messages:
'DBSS_OBJECT_ACTIVATE_WITH_DEFAULTS': 2200, DBSS_OBJECT_ACTIVATE_WITH_DEFAULTS = 2200
'DBSS_OBJECT_ACTIVATE_WITH_DEFAULTS_OTHER': 2201, DBSS_OBJECT_ACTIVATE_WITH_DEFAULTS_OTHER = 2201
'DBSS_OBJECT_GET_ACTIVATED': 2207, DBSS_OBJECT_GET_ACTIVATED = 2207
'DBSS_OBJECT_GET_ACTIVATED_RESP': 2208, DBSS_OBJECT_GET_ACTIVATED_RESP = 2208
'DBSS_OBJECT_DELETE_FIELD_DISK': 2230, DBSS_OBJECT_DELETE_FIELD_DISK = 2230
'DBSS_OBJECT_DELETE_FIELDS_DISK': 2231, DBSS_OBJECT_DELETE_FIELDS_DISK = 2231
'DBSS_OBJECT_DELETE_DISK': 2232, DBSS_OBJECT_DELETE_DISK = 2232
# Database Server control messages: # Database Server control messages:
'DBSERVER_CREATE_OBJECT': 3000, DBSERVER_CREATE_OBJECT = 3000
'DBSERVER_CREATE_OBJECT_RESP': 3001, DBSERVER_CREATE_OBJECT_RESP = 3001
'DBSERVER_OBJECT_GET_FIELD': 3010, DBSERVER_OBJECT_GET_FIELD = 3010
'DBSERVER_OBJECT_GET_FIELD_RESP': 3011, DBSERVER_OBJECT_GET_FIELD_RESP = 3011
'DBSERVER_OBJECT_GET_FIELDS': 3012, DBSERVER_OBJECT_GET_FIELDS = 3012
'DBSERVER_OBJECT_GET_FIELDS_RESP': 3013, DBSERVER_OBJECT_GET_FIELDS_RESP = 3013
'DBSERVER_OBJECT_GET_ALL': 3014, DBSERVER_OBJECT_GET_ALL = 3014
'DBSERVER_OBJECT_GET_ALL_RESP': 3015, DBSERVER_OBJECT_GET_ALL_RESP = 3015
'DBSERVER_OBJECT_SET_FIELD': 3020, DBSERVER_OBJECT_SET_FIELD = 3020
'DBSERVER_OBJECT_SET_FIELDS': 3021, DBSERVER_OBJECT_SET_FIELDS = 3021
'DBSERVER_OBJECT_SET_FIELD_IF_EQUALS': 3022, DBSERVER_OBJECT_SET_FIELD_IF_EQUALS = 3022
'DBSERVER_OBJECT_SET_FIELD_IF_EQUALS_RESP': 3023, DBSERVER_OBJECT_SET_FIELD_IF_EQUALS_RESP = 3023
'DBSERVER_OBJECT_SET_FIELDS_IF_EQUALS': 3024, DBSERVER_OBJECT_SET_FIELDS_IF_EQUALS = 3024
'DBSERVER_OBJECT_SET_FIELDS_IF_EQUALS_RESP': 3025, DBSERVER_OBJECT_SET_FIELDS_IF_EQUALS_RESP = 3025
'DBSERVER_OBJECT_SET_FIELD_IF_EMPTY': 3026, DBSERVER_OBJECT_SET_FIELD_IF_EMPTY = 3026
'DBSERVER_OBJECT_SET_FIELD_IF_EMPTY_RESP': 3027, DBSERVER_OBJECT_SET_FIELD_IF_EMPTY_RESP = 3027
'DBSERVER_OBJECT_DELETE_FIELD': 3030, DBSERVER_OBJECT_DELETE_FIELD = 3030
'DBSERVER_OBJECT_DELETE_FIELDS': 3031, DBSERVER_OBJECT_DELETE_FIELDS = 3031
'DBSERVER_OBJECT_DELETE': 3032, DBSERVER_OBJECT_DELETE = 3032
# Client Agent control messages: # Client Agent control messages:
'CLIENTAGENT_SET_STATE': 1000, CLIENTAGENT_SET_STATE = 1000
'CLIENTAGENT_SET_CLIENT_ID': 1001, CLIENTAGENT_SET_CLIENT_ID = 1001
'CLIENTAGENT_SEND_DATAGRAM': 1002, CLIENTAGENT_SEND_DATAGRAM = 1002
'CLIENTAGENT_EJECT': 1004, CLIENTAGENT_EJECT = 1004
'CLIENTAGENT_DROP': 1005, CLIENTAGENT_DROP = 1005
'CLIENTAGENT_GET_NETWORK_ADDRESS': 1006, CLIENTAGENT_GET_NETWORK_ADDRESS = 1006
'CLIENTAGENT_GET_NETWORK_ADDRESS_RESP': 1007, CLIENTAGENT_GET_NETWORK_ADDRESS_RESP = 1007
'CLIENTAGENT_DECLARE_OBJECT': 1010, CLIENTAGENT_DECLARE_OBJECT = 1010
'CLIENTAGENT_UNDECLARE_OBJECT': 1011, CLIENTAGENT_UNDECLARE_OBJECT = 1011
'CLIENTAGENT_ADD_SESSION_OBJECT': 1012, CLIENTAGENT_ADD_SESSION_OBJECT = 1012
'CLIENTAGENT_REMOVE_SESSION_OBJECT': 1013, CLIENTAGENT_REMOVE_SESSION_OBJECT = 1013
'CLIENTAGENT_SET_FIELDS_SENDABLE': 1014, CLIENTAGENT_SET_FIELDS_SENDABLE = 1014
'CLIENTAGENT_OPEN_CHANNEL': 1100, CLIENTAGENT_OPEN_CHANNEL = 1100
'CLIENTAGENT_CLOSE_CHANNEL': 1101, CLIENTAGENT_CLOSE_CHANNEL = 1101
'CLIENTAGENT_ADD_POST_REMOVE': 1110, CLIENTAGENT_ADD_POST_REMOVE = 1110
'CLIENTAGENT_CLEAR_POST_REMOVES': 1111, CLIENTAGENT_CLEAR_POST_REMOVES = 1111
'CLIENTAGENT_ADD_INTEREST': 1200, CLIENTAGENT_ADD_INTEREST = 1200
'CLIENTAGENT_ADD_INTEREST_MULTIPLE': 1201, CLIENTAGENT_ADD_INTEREST_MULTIPLE = 1201
'CLIENTAGENT_REMOVE_INTEREST': 1203, CLIENTAGENT_REMOVE_INTEREST = 1203
}
MsgName2Id = {name: value for name, value in globals().items() if isinstance(value, int)}
# create id->name table for debugging # create id->name table for debugging
MsgId2Names = invertDictLossless(MsgName2Id) MsgId2Names = invertDictLossless(MsgName2Id)
@ -146,7 +148,7 @@ MsgId2Names = invertDictLossless(MsgName2Id)
globals().update(MsgName2Id) globals().update(MsgName2Id)
# These messages are ignored when the client is headed to the quiet zone # These messages are ignored when the client is headed to the quiet zone
QUIET_ZONE_IGNORED_LIST = [ QUIET_ZONE_IGNORED_LIST: list[int] = [
# We mustn't ignore updates, because some updates for localToon # We mustn't ignore updates, because some updates for localToon
# are always important. # are always important.

View File

@ -5,25 +5,22 @@ implementation. """
from direct.showbase.PythonUtil import invertDictLossless from direct.showbase.PythonUtil import invertDictLossless
MsgName2Id = { SET_DOID_RANGE_CMU = 9001
'SET_DOID_RANGE_CMU' : 9001, CLIENT_OBJECT_GENERATE_CMU = 9002
'CLIENT_OBJECT_GENERATE_CMU' : 9002, OBJECT_GENERATE_CMU = 9003
'OBJECT_GENERATE_CMU' : 9003, OBJECT_UPDATE_FIELD_CMU = 9004
'OBJECT_UPDATE_FIELD_CMU' : 9004, OBJECT_DISABLE_CMU = 9005
'OBJECT_DISABLE_CMU' : 9005, OBJECT_DELETE_CMU = 9006
'OBJECT_DELETE_CMU' : 9006, REQUEST_GENERATES_CMU = 9007
'REQUEST_GENERATES_CMU' : 9007, CLIENT_DISCONNECT_CMU = 9008
'CLIENT_DISCONNECT_CMU' : 9008, CLIENT_SET_INTEREST_CMU = 9009
'CLIENT_SET_INTEREST_CMU' : 9009, OBJECT_SET_ZONE_CMU = 9010
'OBJECT_SET_ZONE_CMU' : 9010, CLIENT_HEARTBEAT_CMU = 9011
'CLIENT_HEARTBEAT_CMU' : 9011, CLIENT_OBJECT_UPDATE_FIELD_TARGETED_CMU = 9011
'CLIENT_OBJECT_UPDATE_FIELD_TARGETED_CMU' : 9011,
'CLIENT_OBJECT_UPDATE_FIELD' : 120, # Matches MsgTypes.CLIENT_OBJECT_SET_FIELD CLIENT_OBJECT_UPDATE_FIELD = 120 # Matches MsgTypes.CLIENT_OBJECT_SET_FIELD
}
MsgName2Id = {name: value for name, value in globals().items() if isinstance(value, int)}
# create id->name table for debugging # create id->name table for debugging
MsgId2Names = invertDictLossless(MsgName2Id) MsgId2Names = invertDictLossless(MsgName2Id)
# put msg names in module scope, assigned to msg value
globals().update(MsgName2Id)

View File

@ -5,6 +5,8 @@ Note:
existing code. New code should use the :mod:`.FSM` module instead. existing code. New code should use the :mod:`.FSM` module instead.
""" """
from __future__ import annotations
__all__ = ['ClassicFSM'] __all__ = ['ClassicFSM']
from direct.directnotify.DirectNotifyGlobal import directNotify from direct.directnotify.DirectNotifyGlobal import directNotify
@ -13,7 +15,7 @@ from direct.showbase.MessengerGlobal import messenger
import weakref import weakref
if __debug__: if __debug__:
_debugFsms = {} _debugFsms: dict[str, weakref.ref] = {}
def printDebugFsmList(): def printDebugFsmList():
for k in sorted(_debugFsms.keys()): for k in sorted(_debugFsms.keys()):

View File

@ -1,5 +1,7 @@
"""State module: contains State class""" """State module: contains State class"""
from __future__ import annotations
__all__ = ['State'] __all__ = ['State']
from direct.directnotify.DirectNotifyGlobal import directNotify from direct.directnotify.DirectNotifyGlobal import directNotify
@ -18,7 +20,7 @@ class State(DirectObject):
# should not cause any leaks. # should not cause any leaks.
if __debug__: if __debug__:
import weakref import weakref
States = weakref.WeakKeyDictionary() States: weakref.WeakKeyDictionary[State, int] = weakref.WeakKeyDictionary()
@classmethod @classmethod
def replaceMethod(cls, oldFunction, newFunction): def replaceMethod(cls, oldFunction, newFunction):

View File

@ -1,6 +1,8 @@
# classes for event-driven programming # classes for event-driven programming
# http://en.wikipedia.org/wiki/Event-driven_programming # http://en.wikipedia.org/wiki/Event-driven_programming
from __future__ import annotations
__all__ = ['StateVar', 'FunctionCall', 'EnterExit', 'Pulse', 'EventPulse', __all__ = ['StateVar', 'FunctionCall', 'EnterExit', 'Pulse', 'EventPulse',
'EventArgument', ] 'EventArgument', ]

View File

@ -4,6 +4,8 @@ See the :ref:`directdialog` page in the programming manual for a more
in-depth explanation and an example of how to use this class. in-depth explanation and an example of how to use this class.
""" """
from __future__ import annotations
__all__ = [ __all__ = [
'findDialog', 'cleanupDialog', 'DirectDialog', 'OkDialog', 'findDialog', 'cleanupDialog', 'DirectDialog', 'OkDialog',
'OkCancelDialog', 'YesNoDialog', 'YesNoCancelDialog', 'RetryCancelDialog', 'OkCancelDialog', 'YesNoDialog', 'YesNoCancelDialog', 'RetryCancelDialog',
@ -45,7 +47,7 @@ def cleanupDialog(uniqueName):
class DirectDialog(DirectFrame): class DirectDialog(DirectFrame):
AllDialogs = {} AllDialogs: dict[str, DirectDialog] = {}
PanelIndex = 0 PanelIndex = 0
def __init__(self, parent=None, **kw): def __init__(self, parent=None, **kw):

View File

@ -84,6 +84,8 @@ Code overview:
see if any keywords are left unused. If so, an error is raised. see if any keywords are left unused. If so, an error is raised.
""" """
from __future__ import annotations
__all__ = ['DirectGuiBase', 'DirectGuiWidget'] __all__ = ['DirectGuiBase', 'DirectGuiWidget']
@ -680,7 +682,7 @@ class DirectGuiWidget(DirectGuiBase, NodePath):
else: else:
inactiveInitState = DGG.DISABLED inactiveInitState = DGG.DISABLED
guiDict = {} guiDict: dict[str, DirectGuiWidget] = {}
def __init__(self, parent = None, **kw): def __init__(self, parent = None, **kw):
# Direct gui widgets are node paths # Direct gui widgets are node paths

View File

@ -3,7 +3,7 @@ Global definitions used by Direct Gui Classes and handy constants
that can be used during widget construction that can be used during widget construction
""" """
__all__ = [] __all__ = ()
from panda3d.core import ( from panda3d.core import (
KeyboardButton, KeyboardButton,

View File

@ -1,5 +1,7 @@
"""FunctionInterval module: contains the FunctionInterval class""" """FunctionInterval module: contains the FunctionInterval class"""
from __future__ import annotations
__all__ = ['FunctionInterval', 'EventInterval', 'AcceptInterval', 'IgnoreInterval', 'ParentInterval', 'WrtParentInterval', 'PosInterval', 'HprInterval', 'ScaleInterval', 'PosHprInterval', 'HprScaleInterval', 'PosHprScaleInterval', 'Func', 'Wait'] __all__ = ['FunctionInterval', 'EventInterval', 'AcceptInterval', 'IgnoreInterval', 'ParentInterval', 'WrtParentInterval', 'PosInterval', 'HprInterval', 'ScaleInterval', 'PosHprInterval', 'HprScaleInterval', 'PosHprScaleInterval', 'Func', 'Wait']
from panda3d.direct import WaitInterval from panda3d.direct import WaitInterval
@ -23,7 +25,7 @@ class FunctionInterval(Interval.Interval):
# should not cause any leaks. # should not cause any leaks.
if __debug__: if __debug__:
import weakref import weakref
FunctionIntervals = weakref.WeakKeyDictionary() FunctionIntervals: weakref.WeakKeyDictionary[FunctionInterval, int] = weakref.WeakKeyDictionary()
@classmethod @classmethod
def replaceMethod(cls, oldFunction, newFunction): def replaceMethod(cls, oldFunction, newFunction):

View File

@ -1,6 +1,6 @@
"""Undocumented Module""" """Undocumented Module"""
__all__ = [] __all__ = ()
if __name__ == "__main__": if __name__ == "__main__":
@ -26,7 +26,7 @@ if __name__ == "__main__":
base = ShowBase() base = ShowBase()
boat = base.loader.loadModel('models/misc/smiley') boat = base.loader.loadModel('models/misc/smiley')
boat.reparentTo(render) boat.reparentTo(base.render)
donald = Actor() donald = Actor()
donald.loadModel("phase_6/models/char/donald-wheel-1000") donald.loadModel("phase_6/models/char/donald-wheel-1000")
@ -34,7 +34,7 @@ if __name__ == "__main__":
donald.reparentTo(boat) donald.reparentTo(boat)
dock = base.loader.loadModel('models/misc/smiley') dock = base.loader.loadModel('models/misc/smiley')
dock.reparentTo(render) dock.reparentTo(base.render)
sound = base.loader.loadSfx('phase_6/audio/sfx/SZ_DD_waterlap.mp3') sound = base.loader.loadSfx('phase_6/audio/sfx/SZ_DD_waterlap.mp3')
foghorn = base.loader.loadSfx('phase_6/audio/sfx/SZ_DD_foghorn.mp3') foghorn = base.loader.loadSfx('phase_6/audio/sfx/SZ_DD_foghorn.mp3')
@ -93,7 +93,7 @@ if __name__ == "__main__":
foghornSound = SoundInterval(foghorn, name='foghorn') foghornSound = SoundInterval(foghorn, name='foghorn')
soundTrack2 = Track([(foghornStartTime, foghornSound)], 'soundtrack2') soundTrack2 = Track([(foghornStartTime, foghornSound)], 'soundtrack2')
mtrack = MultiTrack([boatTrack, dockTrack, soundTrack, soundTrack2, waterEventTrack, mtrack = MultiTrack([boatTrack, dockTrack, soundTrack, soundTrack2, waterEventTrack, # type: ignore[name-defined]
donaldSteerTrack]) donaldSteerTrack])
# Print out MultiTrack parameters # Print out MultiTrack parameters
print(mtrack) print(mtrack)
@ -175,11 +175,11 @@ if __name__ == "__main__":
# Just to take time # Just to take time
i2 = LerpPosInterval(base.camera, 2.0, Point3(0, 10, 5)) i2 = LerpPosInterval(base.camera, 2.0, Point3(0, 10, 5))
# This will be relative to end of camera move # This will be relative to end of camera move
i3 = FunctionInterval(printPreviousEnd) i3 = FunctionInterval(printPreviousEnd) # type: ignore[assignment]
# Just to take time # Just to take time
i4 = LerpPosInterval(base.camera, 2.0, Point3(0, 0, 5)) i4 = LerpPosInterval(base.camera, 2.0, Point3(0, 0, 5))
# This will be relative to the start of the camera move # This will be relative to the start of the camera move
i5 = FunctionInterval(printPreviousStart) i5 = FunctionInterval(printPreviousStart) # type: ignore[assignment]
# This will be relative to track start # This will be relative to track start
i6 = FunctionInterval(printTrackStart) i6 = FunctionInterval(printTrackStart)
# This will print some arguments # This will print some arguments

View File

@ -4,7 +4,7 @@ if __name__ == '__main__':
from direct.showbase.ShowBase import ShowBase from direct.showbase.ShowBase import ShowBase
base = ShowBase() base = ShowBase()
base.le = LevelEditor.LevelEditor() base.le = LevelEditor.LevelEditor() # type: ignore[attr-defined]
# You should define LevelEditor instance as # You should define LevelEditor instance as
# base.le so it can be reached in global scope # base.le so it can be reached in global scope

View File

@ -1,4 +1,5 @@
from panda3d.core import Point3, VBase3 from panda3d.core import Point3, VBase3
from direct.showbase.ShowBaseGlobal import base
if hasattr(base, 'le'): if hasattr(base, 'le'):
objectMgr = base.le.objectMgr objectMgr = base.le.objectMgr
@ -6,7 +7,7 @@ if hasattr(base, 'le'):
ui.sceneGraphUI.reset() ui.sceneGraphUI.reset()
else: else:
objectMgr = base.objectMgr objectMgr = base.objectMgr # type: ignore[attr-defined]
# temporary place holder for nodepath # temporary place holder for nodepath
objects = {} objects = {}

View File

@ -1,3 +1,5 @@
from __future__ import annotations
from panda3d.core import ( from panda3d.core import (
BoundingVolume, BoundingVolume,
ColorBlendAttrib, ColorBlendAttrib,
@ -92,7 +94,7 @@ class MotionTrail(NodePath, DirectObject):
notify = directNotify.newCategory("MotionTrail") notify = directNotify.newCategory("MotionTrail")
task_added = False task_added = False
motion_trail_list = [] motion_trail_list: list[MotionTrail] = []
motion_trail_task_name = "motion_trail_task" motion_trail_task_name = "motion_trail_task"
global_enable = True global_enable = True

View File

@ -1,3 +1,5 @@
from __future__ import annotations
from direct.directnotify.DirectNotifyGlobal import directNotify from direct.directnotify.DirectNotifyGlobal import directNotify
import direct.showbase.DConfig as config import direct.showbase.DConfig as config
from direct.showbase.PythonUtil import makeFlywheelGen, flywheel from direct.showbase.PythonUtil import makeFlywheelGen, flywheel
@ -982,7 +984,7 @@ class ContainerLeakDetector(Job):
""" """
notify = directNotify.newCategory("ContainerLeakDetector") notify = directNotify.newCategory("ContainerLeakDetector")
# set of containers that should not be examined # set of containers that should not be examined
PrivateIds = set() PrivateIds: set[int] = set()
def __init__(self, name, firstCheckDelay = None): def __init__(self, name, firstCheckDelay = None):
Job.__init__(self, name) Job.__init__(self, name)

View File

@ -1,3 +1,5 @@
from __future__ import annotations
from direct.directnotify.DirectNotifyGlobal import directNotify from direct.directnotify.DirectNotifyGlobal import directNotify
from direct.showbase.PythonUtil import Queue, invertDictLossless from direct.showbase.PythonUtil import Queue, invertDictLossless
from direct.showbase.PythonUtil import safeRepr from direct.showbase.PythonUtil import safeRepr
@ -11,7 +13,7 @@ import io
class ContainerReport(Job): class ContainerReport(Job):
notify = directNotify.newCategory("ContainerReport") notify = directNotify.newCategory("ContainerReport")
# set of containers that should not be included in the report # set of containers that should not be included in the report
PrivateIds = set() PrivateIds: set[int] = set()
def __init__(self, name, log=False, limit=None, threaded=False): def __init__(self, name, log=False, limit=None, threaded=False):
Job.__init__(self, name) Job.__init__(self, name)

View File

@ -1,6 +1,6 @@
"This module contains a deprecated shim emulating the old DConfig API." "This module contains a deprecated shim emulating the old DConfig API."
__all__ = [] __all__ = ()
from panda3d.core import (ConfigFlags, ConfigVariableBool, ConfigVariableInt, from panda3d.core import (ConfigFlags, ConfigVariableBool, ConfigVariableInt,
ConfigVariableDouble, ConfigVariableString) ConfigVariableDouble, ConfigVariableString)

View File

@ -1,3 +1,5 @@
from __future__ import annotations
from direct.showbase.DirectObject import DirectObject from direct.showbase.DirectObject import DirectObject
from direct.directnotify.DirectNotifyGlobal import directNotify from direct.directnotify.DirectNotifyGlobal import directNotify
from panda3d.core import ( from panda3d.core import (
@ -62,7 +64,7 @@ class DistancePhasedNode(PhasedObject, DirectObject, NodePath):
notify = directNotify.newCategory("DistancePhasedObject") notify = directNotify.newCategory("DistancePhasedObject")
__InstanceSequence = 0 __InstanceSequence = 0
__InstanceDeque = [] __InstanceDeque: list[int] = []
@staticmethod @staticmethod
def __allocateId(): def __allocateId():

View File

@ -69,7 +69,7 @@ oldExcepthook = None
# from its main exception handler # from its main exception handler
wantStackDumpLog = False wantStackDumpLog = False
wantStackDumpUpload = False wantStackDumpUpload = False
variableDumpReasons = [] variableDumpReasons: list = []
dumpOnExceptionInit = False dumpOnExceptionInit = False

View File

@ -11,6 +11,8 @@
>>> o.diff(o2) >>> o.diff(o2)
""" """
from __future__ import annotations
__all__ = ['ExclusiveObjectPool', 'ObjectReport'] __all__ = ['ExclusiveObjectPool', 'ObjectReport']
from direct.directnotify.DirectNotifyGlobal import directNotify from direct.directnotify.DirectNotifyGlobal import directNotify
@ -26,8 +28,8 @@ import builtins
class ExclusiveObjectPool(DirectObject): class ExclusiveObjectPool(DirectObject):
# ObjectPool specialization that excludes particular objects # ObjectPool specialization that excludes particular objects
# IDs of objects to globally exclude from reporting # IDs of objects to globally exclude from reporting
_ExclObjs = [] _ExclObjs: list[object] = []
_ExclObjIds = {} _ExclObjIds: dict[int, int] = {}
_SyncMaster = Sync('ExclusiveObjectPool.ExcludedObjectList') _SyncMaster = Sync('ExclusiveObjectPool.ExcludedObjectList')
_SerialNumGen = SerialNumGen() _SerialNumGen = SerialNumGen()

View File

@ -1,5 +1,7 @@
"""Contains miscellaneous utility functions and classes.""" """Contains miscellaneous utility functions and classes."""
from __future__ import annotations
__all__ = [ __all__ = [
'indent', 'doc', 'adjust', 'difference', 'intersection', 'union', 'indent', 'doc', 'adjust', 'difference', 'intersection', 'union',
@ -39,6 +41,7 @@ import time
import builtins import builtins
import importlib import importlib
import functools import functools
from typing import Callable
__report_indent = 3 __report_indent = 3
@ -699,9 +702,9 @@ if __debug__:
return profileDecorator return profileDecorator
# intercept profile-related file operations to avoid disk access # intercept profile-related file operations to avoid disk access
movedOpenFuncs = [] movedOpenFuncs: list[Callable] = []
movedDumpFuncs = [] movedDumpFuncs: list[Callable] = []
movedLoadFuncs = [] movedLoadFuncs: list[Callable] = []
profileFilenames = set() profileFilenames = set()
profileFilenameList = Stack() profileFilenameList = Stack()
profileFilename2file = {} profileFilename2file = {}
@ -1899,7 +1902,7 @@ class SubframeCall:
class PStatScope: class PStatScope:
collectors = {} collectors: dict = {}
def __init__(self, level = None): def __init__(self, level = None):
self.levels = [] self.levels = []
@ -2618,52 +2621,52 @@ class PriorityCallbacks:
callback() callback()
builtins.Functor = Functor builtins.Functor = Functor # type: ignore[attr-defined]
builtins.Stack = Stack builtins.Stack = Stack # type: ignore[attr-defined]
builtins.Queue = Queue builtins.Queue = Queue # type: ignore[attr-defined]
builtins.SerialNumGen = SerialNumGen builtins.SerialNumGen = SerialNumGen # type: ignore[attr-defined]
builtins.SerialMaskedGen = SerialMaskedGen builtins.SerialMaskedGen = SerialMaskedGen # type: ignore[attr-defined]
builtins.ScratchPad = ScratchPad builtins.ScratchPad = ScratchPad # type: ignore[attr-defined]
builtins.uniqueName = uniqueName builtins.uniqueName = uniqueName # type: ignore[attr-defined]
builtins.serialNum = serialNum builtins.serialNum = serialNum # type: ignore[attr-defined]
if __debug__: if __debug__:
builtins.profiled = profiled builtins.profiled = profiled # type: ignore[attr-defined]
builtins.exceptionLogged = exceptionLogged builtins.exceptionLogged = exceptionLogged # type: ignore[attr-defined]
builtins.itype = itype builtins.itype = itype # type: ignore[attr-defined]
builtins.appendStr = appendStr builtins.appendStr = appendStr # type: ignore[attr-defined]
builtins.bound = bound builtins.bound = bound # type: ignore[attr-defined]
builtins.clamp = clamp builtins.clamp = clamp # type: ignore[attr-defined]
builtins.lerp = lerp builtins.lerp = lerp # type: ignore[attr-defined]
builtins.makeList = makeList builtins.makeList = makeList # type: ignore[attr-defined]
builtins.makeTuple = makeTuple builtins.makeTuple = makeTuple # type: ignore[attr-defined]
if __debug__: if __debug__:
builtins.printStack = printStack builtins.printStack = printStack # type: ignore[attr-defined]
builtins.printReverseStack = printReverseStack builtins.printReverseStack = printReverseStack # type: ignore[attr-defined]
builtins.printVerboseStack = printVerboseStack builtins.printVerboseStack = printVerboseStack # type: ignore[attr-defined]
builtins.DelayedCall = DelayedCall builtins.DelayedCall = DelayedCall # type: ignore[attr-defined]
builtins.DelayedFunctor = DelayedFunctor builtins.DelayedFunctor = DelayedFunctor # type: ignore[attr-defined]
builtins.FrameDelayedCall = FrameDelayedCall builtins.FrameDelayedCall = FrameDelayedCall # type: ignore[attr-defined]
builtins.SubframeCall = SubframeCall builtins.SubframeCall = SubframeCall # type: ignore[attr-defined]
builtins.invertDict = invertDict builtins.invertDict = invertDict # type: ignore[attr-defined]
builtins.invertDictLossless = invertDictLossless builtins.invertDictLossless = invertDictLossless # type: ignore[attr-defined]
builtins.getBase = getBase builtins.getBase = getBase # type: ignore[attr-defined]
builtins.getRepository = getRepository builtins.getRepository = getRepository # type: ignore[attr-defined]
builtins.safeRepr = safeRepr builtins.safeRepr = safeRepr # type: ignore[attr-defined]
builtins.fastRepr = fastRepr builtins.fastRepr = fastRepr # type: ignore[attr-defined]
builtins.nullGen = nullGen builtins.nullGen = nullGen # type: ignore[attr-defined]
builtins.flywheel = flywheel builtins.flywheel = flywheel # type: ignore[attr-defined]
builtins.loopGen = loopGen builtins.loopGen = loopGen # type: ignore[attr-defined]
if __debug__: if __debug__:
builtins.StackTrace = StackTrace builtins.StackTrace = StackTrace # type: ignore[attr-defined]
builtins.report = report builtins.report = report # type: ignore[attr-defined]
builtins.pstatcollect = pstatcollect builtins.pstatcollect = pstatcollect # type: ignore[attr-defined]
builtins.MiniLog = MiniLog builtins.MiniLog = MiniLog # type: ignore[attr-defined]
builtins.MiniLogSentry = MiniLogSentry builtins.MiniLogSentry = MiniLogSentry # type: ignore[attr-defined]
builtins.logBlock = logBlock builtins.logBlock = logBlock # type: ignore[attr-defined]
builtins.HierarchyException = HierarchyException builtins.HierarchyException = HierarchyException # type: ignore[attr-defined]
builtins.deeptype = deeptype builtins.deeptype = deeptype # type: ignore[attr-defined]
builtins.Default = Default builtins.Default = Default # type: ignore[attr-defined]
builtins.configIsToday = configIsToday builtins.configIsToday = configIsToday # type: ignore[attr-defined]
builtins.typeName = typeName builtins.typeName = typeName # type: ignore[attr-defined]
builtins.safeTypeName = safeTypeName builtins.safeTypeName = safeTypeName # type: ignore[attr-defined]
builtins.histogramDict = histogramDict builtins.histogramDict = histogramDict # type: ignore[attr-defined]

View File

@ -120,7 +120,7 @@ from direct.extensions_native import NodePath_extensions # pylint: disable=unuse
# This needs to be available early for DirectGUI imports # This needs to be available early for DirectGUI imports
import sys import sys
import builtins import builtins
builtins.config = DConfig builtins.config = DConfig # type: ignore[attr-defined]
from direct.directnotify.DirectNotifyGlobal import directNotify, giveNotify from direct.directnotify.DirectNotifyGlobal import directNotify, giveNotify
from .MessengerGlobal import messenger from .MessengerGlobal import messenger

View File

@ -11,7 +11,7 @@ Note that you cannot directly import :data:`~builtins.base` from this module
since ShowBase may not have been created yet; instead, ShowBase dynamically since ShowBase may not have been created yet; instead, ShowBase dynamically
adds itself to this module's scope when instantiated.""" adds itself to this module's scope when instantiated."""
__all__ = [] __all__ = ()
from .ShowBase import ShowBase, WindowControls # pylint: disable=unused-import from .ShowBase import ShowBase, WindowControls # pylint: disable=unused-import
from direct.directnotify.DirectNotifyGlobal import directNotify, giveNotify # pylint: disable=unused-import from direct.directnotify.DirectNotifyGlobal import directNotify, giveNotify # pylint: disable=unused-import
@ -23,6 +23,8 @@ import warnings
__dev__ = ConfigVariableBool('want-dev', __debug__).value __dev__ = ConfigVariableBool('want-dev', __debug__).value
base: ShowBase
#: The global instance of the :ref:`virtual-file-system`, as obtained using #: The global instance of the :ref:`virtual-file-system`, as obtained using
#: :meth:`panda3d.core.VirtualFileSystem.getGlobalPtr()`. #: :meth:`panda3d.core.VirtualFileSystem.getGlobalPtr()`.
vfs = VirtualFileSystem.getGlobalPtr() vfs = VirtualFileSystem.getGlobalPtr()
@ -81,7 +83,7 @@ def inspect(anObject):
import builtins import builtins
builtins.inspect = inspect builtins.inspect = inspect # type: ignore[attr-defined]
# this also appears in AIBaseGlobal # this also appears in AIBaseGlobal
if (not __debug__) and __dev__: if (not __debug__) and __dev__:

View File

@ -3,7 +3,7 @@ This module hooks into Python's import mechanism to print out all imports to
the standard output as they happen. the standard output as they happen.
""" """
__all__ = [] __all__ = ()
import sys import sys

View File

@ -45,7 +45,7 @@ BasePickler = pickle._Pickler
BaseUnpickler = pickle._Unpickler BaseUnpickler = pickle._Unpickler
class Pickler(BasePickler): class Pickler(BasePickler): # type: ignore[misc, valid-type]
def __init__(self, *args, **kw): def __init__(self, *args, **kw):
self.bamWriter = BamWriter() self.bamWriter = BamWriter()
@ -148,7 +148,7 @@ class Pickler(BasePickler):
self.save_reduce(obj=obj, *rv) self.save_reduce(obj=obj, *rv)
class Unpickler(BaseUnpickler): class Unpickler(BaseUnpickler): # type: ignore[misc, valid-type]
def __init__(self, *args, **kw): def __init__(self, *args, **kw):
self.bamReader = BamReader() self.bamReader = BamReader()

View File

@ -83,8 +83,8 @@ class ThreadBase:
# Copy these static methods from Panda's Thread object. These are # Copy these static methods from Panda's Thread object. These are
# useful if you may be running in Panda's SIMPLE_THREADS compilation # useful if you may be running in Panda's SIMPLE_THREADS compilation
# mode. # mode.
ThreadBase.forceYield = core.Thread.forceYield ThreadBase.forceYield = core.Thread.forceYield # type: ignore[attr-defined]
ThreadBase.considerYield = core.Thread.considerYield ThreadBase.considerYield = core.Thread.considerYield # type: ignore[attr-defined]
class Thread(ThreadBase): class Thread(ThreadBase):

View File

@ -65,7 +65,7 @@ if __debug__:
else: else:
# Disable this when using "python -O" # Disable this when using "python -O"
class _Verbose(object): class _Verbose(object): # type: ignore[no-redef]
def __init__(self, verbose=None): def __init__(self, verbose=None):
pass pass
def _note(self, *args): def _note(self, *args):

View File

@ -24,7 +24,7 @@ if hasattr(sys, 'getandroidapilevel'):
signal = None signal = None
else: else:
try: try:
import _signal as signal import _signal as signal # type: ignore[import, no-redef]
except ImportError: except ImportError:
signal = None signal = None

View File

@ -21,11 +21,11 @@ import builtins
# Create toplevel widget dictionary # Create toplevel widget dictionary
if not hasattr(builtins, "widgetDict"): if not hasattr(builtins, "widgetDict"):
builtins.widgetDict = {} builtins.widgetDict = {} # type: ignore[attr-defined]
# Create toplevel variable dictionary # Create toplevel variable dictionary
if not hasattr(builtins, "variableDict"): if not hasattr(builtins, "variableDict"):
builtins.variableDict = {} builtins.variableDict = {} # type: ignore[attr-defined]
def resetWidgetDict(): def resetWidgetDict():

View File

@ -6,6 +6,8 @@ Modified by gjeon.
Modified by Summer 2010 Carnegie Mellon University ETC PandaLE team: fixed a bug in Viewport.Close Modified by Summer 2010 Carnegie Mellon University ETC PandaLE team: fixed a bug in Viewport.Close
""" """
from __future__ import annotations
__all__ = ["Viewport", "ViewportManager"] __all__ = ["Viewport", "ViewportManager"]
from panda3d.core import ( from panda3d.core import (
@ -36,7 +38,7 @@ VPPERSPECTIVE = 13
class ViewportManager: class ViewportManager:
"""Manages the global viewport stuff.""" """Manages the global viewport stuff."""
viewports = [] viewports: list[Viewport] = []
gsg = None gsg = None
@staticmethod @staticmethod
@ -58,7 +60,7 @@ class ViewportManager:
v.Layout(*args, **kwargs) v.Layout(*args, **kwargs)
class Viewport(WxPandaWindow, DirectObject): class Viewport(WxPandaWindow, DirectObject): # type: ignore[misc, valid-type]
"""Class representing a 3D Viewport.""" """Class representing a 3D Viewport."""
CREATENEW = CREATENEW CREATENEW = CREATENEW
VPLEFT = VPLEFT VPLEFT = VPLEFT

View File

@ -1,2 +1,3 @@
from direct.showbase.ShowBaseGlobal import base
from .WxPandaShell import WxPandaShell from .WxPandaShell import WxPandaShell
base.app = WxPandaShell() base.app = WxPandaShell() # type: ignore[attr-defined]

View File

@ -81,7 +81,7 @@ class EmbeddedPandaWindow(wx.Window):
if not hasattr(wxgl, 'GLCanvas'): if not hasattr(wxgl, 'GLCanvas'):
OpenGLPandaWindow = None OpenGLPandaWindow = None
else: else:
class OpenGLPandaWindow(wxgl.GLCanvas): class OpenGLPandaWindow(wxgl.GLCanvas): # type: ignore[no-redef]
""" This class implements a Panda3D "window" that actually draws """ This class implements a Panda3D "window" that actually draws
within the wx GLCanvas object. It is supported whenever OpenGL is within the wx GLCanvas object. It is supported whenever OpenGL is
Panda's rendering engine, and GLCanvas is available in wx. """ Panda's rendering engine, and GLCanvas is available in wx. """

13
mypy.ini Normal file
View File

@ -0,0 +1,13 @@
[mypy]
explicit_package_bases = True
exclude = /(dist|directscripts)/
warn_unused_ignores = True
[mypy-panda3d.*]
ignore_missing_imports = True
[mypy-wx.*]
ignore_missing_imports = True
[mypy-Pmw.*]
ignore_missing_imports = True

25
tests/run_mypy.py Normal file
View File

@ -0,0 +1,25 @@
import os
import pathlib
import shutil
import subprocess
import tempfile
def main():
root = pathlib.Path(__file__).parent.parent
direct_src = root / 'direct' / 'src'
mypy_config = root / 'mypy.ini'
with tempfile.TemporaryDirectory() as temp_dir:
os.environ['MYPYPATH'] = temp_dir
direct_copy = pathlib.Path(temp_dir, 'direct')
shutil.copytree(direct_src, direct_copy)
subprocess.run([
'mypy',
str(direct_copy),
'--config-file',
str(mypy_config),
])
if __name__ == '__main__':
main()