Browse Source

The direct tree is now valid Python 2 *and* 3

rdb 9 years ago
parent
commit
23bf9ea5c7
100 changed files with 703 additions and 711 deletions
  1. 89 107
      direct/src/actor/Actor.py
  2. 1 1
      direct/src/actor/DistributedActor.py
  3. 8 10
      direct/src/cluster/ClusterClient.py
  4. 1 1
      direct/src/cluster/ClusterConfig.py
  5. 2 2
      direct/src/cluster/ClusterServer.py
  6. 3 3
      direct/src/controls/BattleWalker.py
  7. 1 1
      direct/src/controls/GhostWalker.py
  8. 1 1
      direct/src/controls/ObserverWalker.py
  9. 2 2
      direct/src/controls/PhysicsWalker.py
  10. 1 1
      direct/src/controls/TwoDWalker.py
  11. 1 1
      direct/src/directbase/ThreeUpStart.py
  12. 1 1
      direct/src/directdevices/DirectFastrak.py
  13. 1 1
      direct/src/directdevices/DirectJoybox.py
  14. 1 1
      direct/src/directdevices/DirectRadamec.py
  15. 4 4
      direct/src/directnotify/DirectNotify.py
  16. 1 1
      direct/src/directnotify/DirectNotifyGlobal.py
  17. 1 1
      direct/src/directnotify/LoggerGlobal.py
  18. 2 2
      direct/src/directnotify/Notifier.py
  19. 4 3
      direct/src/directnotify/RotatingLog.py
  20. 5 5
      direct/src/directscripts/eggcacher.py
  21. 41 39
      direct/src/directscripts/extract_docs.py
  22. 26 26
      direct/src/directscripts/gendocs.py
  23. 28 28
      direct/src/directscripts/packpanda.py
  24. 6 6
      direct/src/directtools/DirectCameraControl.py
  25. 9 9
      direct/src/directtools/DirectGeometry.py
  26. 2 2
      direct/src/directtools/DirectGlobals.py
  27. 2 2
      direct/src/directtools/DirectGrid.py
  28. 1 1
      direct/src/directtools/DirectLights.py
  29. 6 7
      direct/src/directtools/DirectManipulation.py
  30. 6 6
      direct/src/directtools/DirectSelection.py
  31. 17 16
      direct/src/directtools/DirectSession.py
  32. 1 1
      direct/src/directtools/DirectUtil.py
  33. 2 2
      direct/src/directutil/DeltaProfiler.py
  34. 1 1
      direct/src/directutil/DistributedLargeBlobSender.py
  35. 1 1
      direct/src/directutil/DistributedLargeBlobSenderAI.py
  36. 1 1
      direct/src/directutil/MemoryLeakHelpers.py
  37. 6 6
      direct/src/directutil/Mopath.py
  38. 3 3
      direct/src/directutil/Verify.py
  39. 4 4
      direct/src/distributed/AsyncRequest.py
  40. 1 1
      direct/src/distributed/CRCache.py
  41. 2 2
      direct/src/distributed/CRDataCache.py
  42. 6 6
      direct/src/distributed/ClientRepository.py
  43. 13 15
      direct/src/distributed/ClientRepositoryBase.py
  44. 3 6
      direct/src/distributed/ConnectionRepository.py
  45. 6 6
      direct/src/distributed/DistributedCamera.py
  46. 1 1
      direct/src/distributed/DistributedCartesianGrid.py
  47. 2 2
      direct/src/distributed/DistributedCartesianGridAI.py
  48. 5 6
      direct/src/distributed/DistributedNode.py
  49. 4 4
      direct/src/distributed/DistributedNodeAI.py
  50. 2 2
      direct/src/distributed/DistributedNodeUD.py
  51. 18 15
      direct/src/distributed/DistributedObject.py
  52. 18 16
      direct/src/distributed/DistributedObjectAI.py
  53. 6 7
      direct/src/distributed/DistributedObjectBase.py
  54. 1 1
      direct/src/distributed/DistributedObjectGlobalAI.py
  55. 1 1
      direct/src/distributed/DistributedObjectGlobalUD.py
  56. 12 10
      direct/src/distributed/DistributedObjectOV.py
  57. 14 12
      direct/src/distributed/DistributedObjectUD.py
  58. 3 3
      direct/src/distributed/DistributedSmoothNode.py
  59. 2 2
      direct/src/distributed/DistributedSmoothNodeAI.py
  60. 1 1
      direct/src/distributed/DistributedSmoothNodeBase.py
  61. 14 14
      direct/src/distributed/DoCollectionManager.py
  62. 26 26
      direct/src/distributed/DoInterestManager.py
  63. 1 1
      direct/src/distributed/GridChild.py
  64. 6 2
      direct/src/distributed/NetMessenger.py
  65. 2 2
      direct/src/distributed/OldClientRepository.py
  66. 2 2
      direct/src/distributed/ParentMgr.py
  67. 6 8
      direct/src/distributed/ServerRepository.py
  68. 1 1
      direct/src/distributed/TimeManagerAI.py
  69. 4 1
      direct/src/doc/howto.adjust
  70. 19 16
      direct/src/extensions_native/CInterval_extensions.py
  71. 2 2
      direct/src/extensions_native/NodePath_extensions.py
  72. 1 2
      direct/src/extensions_native/extension_native_helpers.py
  73. 1 1
      direct/src/filter/CommonFilters.py
  74. 7 10
      direct/src/fsm/ClassicFSM.py
  75. 5 5
      direct/src/fsm/FSM.py
  76. 3 3
      direct/src/fsm/FourState.py
  77. 3 3
      direct/src/fsm/FourStateAI.py
  78. 20 21
      direct/src/fsm/SampleFSM.py
  79. 2 2
      direct/src/fsm/State.py
  80. 0 1
      direct/src/fsm/StateData.py
  81. 5 6
      direct/src/fsm/StatePush.py
  82. 3 3
      direct/src/gui/DirectButton.py
  83. 1 1
      direct/src/gui/DirectCheckBox.py
  84. 3 3
      direct/src/gui/DirectCheckButton.py
  85. 9 9
      direct/src/gui/DirectDialog.py
  86. 21 17
      direct/src/gui/DirectEntry.py
  87. 4 4
      direct/src/gui/DirectEntryScroll.py
  88. 17 11
      direct/src/gui/DirectFrame.py
  89. 19 19
      direct/src/gui/DirectGui.py
  90. 22 23
      direct/src/gui/DirectGuiBase.py
  91. 9 9
      direct/src/gui/DirectGuiTest.py
  92. 1 1
      direct/src/gui/DirectLabel.py
  93. 6 8
      direct/src/gui/DirectOptionMenu.py
  94. 4 4
      direct/src/gui/DirectRadioButton.py
  95. 4 4
      direct/src/gui/DirectScrollBar.py
  96. 4 4
      direct/src/gui/DirectScrolledFrame.py
  97. 7 8
      direct/src/gui/DirectScrolledList.py
  98. 4 4
      direct/src/gui/DirectSlider.py
  99. 3 3
      direct/src/gui/DirectWaitBar.py
  100. 18 18
      direct/src/gui/OnscreenGeom.py

+ 89 - 107
direct/src/actor/Actor.py

@@ -6,7 +6,7 @@ from panda3d.core import *
 from panda3d.core import Loader as PandaLoader
 from panda3d.core import Loader as PandaLoader
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
-import types
+
 
 
 class Actor(DirectObject, NodePath):
 class Actor(DirectObject, NodePath):
     """
     """
@@ -239,30 +239,30 @@ class Actor(DirectObject, NodePath):
             #   models{}{}, anims{}{} = multi-part actor w/ LOD
             #   models{}{}, anims{}{} = multi-part actor w/ LOD
             #
             #
             # make sure we have models
             # make sure we have models
-            if (models):
+            if models:
                 # do we have a dictionary of models?
                 # do we have a dictionary of models?
-                if (type(models)==type({})):
+                if type(models) == dict:
                     # if this is a dictionary of dictionaries
                     # if this is a dictionary of dictionaries
-                    if (type(models[models.keys()[0]]) == type({})):
+                    if type(models[next(iter(models))]) == dict:
                         # then it must be a multipart actor w/LOD
                         # then it must be a multipart actor w/LOD
                         self.setLODNode(node = lodNode)
                         self.setLODNode(node = lodNode)
                         # preserve numerical order for lod's
                         # preserve numerical order for lod's
                         # this will make it easier to set ranges
                         # this will make it easier to set ranges
-                        sortedKeys = models.keys()
+                        sortedKeys = list(models.keys())
                         sortedKeys.sort()
                         sortedKeys.sort()
                         for lodName in sortedKeys:
                         for lodName in sortedKeys:
                             # make a node under the LOD switch
                             # make a node under the LOD switch
                             # for each lod (just because!)
                             # for each lod (just because!)
                             self.addLOD(str(lodName))
                             self.addLOD(str(lodName))
                             # iterate over both dicts
                             # iterate over both dicts
-                            for modelName in models[lodName].keys():
+                            for modelName in models[lodName]:
                                 self.loadModel(models[lodName][modelName],
                                 self.loadModel(models[lodName][modelName],
                                                modelName, lodName, copy = copy,
                                                modelName, lodName, copy = copy,
                                                okMissing = okMissing)
                                                okMissing = okMissing)
                     # then if there is a dictionary of dictionaries of anims
                     # then if there is a dictionary of dictionaries of anims
-                    elif (type(anims[anims.keys()[0]])==type({})):
+                    elif type(anims[next(iter(anims))]) == dict:
                         # then this is a multipart actor w/o LOD
                         # then this is a multipart actor w/o LOD
-                        for partName in models.keys():
+                        for partName in models:
                             # pass in each part
                             # pass in each part
                             self.loadModel(models[partName], partName,
                             self.loadModel(models[partName], partName,
                                            copy = copy, okMissing = okMissing)
                                            copy = copy, okMissing = okMissing)
@@ -270,7 +270,7 @@ class Actor(DirectObject, NodePath):
                         # it is a single part actor w/LOD
                         # it is a single part actor w/LOD
                         self.setLODNode(node = lodNode)
                         self.setLODNode(node = lodNode)
                         # preserve order of LOD's
                         # preserve order of LOD's
-                        sortedKeys = models.keys()
+                        sortedKeys = list(models.keys())
                         sortedKeys.sort()
                         sortedKeys.sort()
                         for lodName in sortedKeys:
                         for lodName in sortedKeys:
                             self.addLOD(str(lodName))
                             self.addLOD(str(lodName))
@@ -283,28 +283,28 @@ class Actor(DirectObject, NodePath):
 
 
             # load anims
             # load anims
             # make sure the actor has animations
             # make sure the actor has animations
-            if (anims):
-                if (len(anims) >= 1):
+            if anims:
+                if len(anims) >= 1:
                     # if so, does it have a dictionary of dictionaries?
                     # if so, does it have a dictionary of dictionaries?
-                    if (type(anims[anims.keys()[0]])==type({})):
+                    if type(anims[next(iter(anims))]) == dict:
                         # are the models a dict of dicts too?
                         # are the models a dict of dicts too?
-                        if (type(models)==type({})):
-                            if (type(models[models.keys()[0]]) == type({})):
+                        if type(models) == dict:
+                            if type(models[next(iter(models))]) == dict:
                                 # then we have a multi-part w/ LOD
                                 # then we have a multi-part w/ LOD
-                                sortedKeys = models.keys()
+                                sortedKeys = list(models.keys())
                                 sortedKeys.sort()
                                 sortedKeys.sort()
                                 for lodName in sortedKeys:
                                 for lodName in sortedKeys:
                                     # iterate over both dicts
                                     # iterate over both dicts
-                                    for partName in anims.keys():
+                                    for partName in anims:
                                         self.loadAnims(
                                         self.loadAnims(
                                             anims[partName], partName, lodName)
                                             anims[partName], partName, lodName)
                             else:
                             else:
                                 # then it must be multi-part w/o LOD
                                 # then it must be multi-part w/o LOD
-                                for partName in anims.keys():
+                                for partName in anims:
                                     self.loadAnims(anims[partName], partName)
                                     self.loadAnims(anims[partName], partName)
-                    elif (type(models)==type({})):
+                    elif type(models) == dict:
                         # then we have single-part w/ LOD
                         # then we have single-part w/ LOD
-                        sortedKeys = models.keys()
+                        sortedKeys = list(models.keys())
                         sortedKeys.sort()
                         sortedKeys.sort()
                         for lodName in sortedKeys:
                         for lodName in sortedKeys:
                             self.loadAnims(anims, lodName=lodName)
                             self.loadAnims(anims, lodName=lodName)
@@ -431,11 +431,10 @@ class Actor(DirectObject, NodePath):
                 part.outputValue(lineStream)
                 part.outputValue(lineStream)
                 value = lineStream.getLine()
                 value = lineStream.getLine()
 
 
-            print ' ' * indentLevel, part.getName(), value
+            print(' '.join((' ' * indentLevel, part.getName(), value)))
 
 
-        for i in range(part.getNumChildren()):
-            self.__doListJoints(indentLevel + 2, part.getChild(i),
-                                isIncluded, subset)
+        for child in part.getChildren():
+            self.__doListJoints(indentLevel + 2, child, isIncluded, subset)
 
 
 
 
     def getActorInfo(self):
     def getActorInfo(self):
@@ -449,14 +448,14 @@ class Actor(DirectObject, NodePath):
                 lodName = self.__sortedLODNames[0]
                 lodName = self.__sortedLODNames[0]
 
 
             partInfo = []
             partInfo = []
-            for partName in partDict.keys():
+            for partName in partDict:
                 subpartDef = self.__subpartDict.get(partName, Actor.SubpartDef(partName))
                 subpartDef = self.__subpartDict.get(partName, Actor.SubpartDef(partName))
                 partBundleDict = self.__partBundleDict.get(lodName)
                 partBundleDict = self.__partBundleDict.get(lodName)
                 partDef = partBundleDict.get(subpartDef.truePartName)
                 partDef = partBundleDict.get(subpartDef.truePartName)
                 partBundle = partDef.getBundle()
                 partBundle = partDef.getBundle()
                 animDict = partDict[partName]
                 animDict = partDict[partName]
                 animInfo = []
                 animInfo = []
-                for animName in animDict.keys():
+                for animName in animDict:
                     file = animDict[animName].filename
                     file = animDict[animName].filename
                     animControl = animDict[animName].animControl
                     animControl = animDict[animName].animControl
                     animInfo.append([animName, file, animControl])
                     animInfo.append([animName, file, animControl])
@@ -478,17 +477,17 @@ class Actor(DirectObject, NodePath):
         Pretty print actor's details
         Pretty print actor's details
         """
         """
         for lodName, lodInfo in self.getActorInfo():
         for lodName, lodInfo in self.getActorInfo():
-            print 'LOD:', lodName
+            print('LOD: %s' % lodName)
             for partName, bundle, animInfo in lodInfo:
             for partName, bundle, animInfo in lodInfo:
-                print '  Part:', partName
-                print '  Bundle:', repr(bundle)
+                print('  Part: %s' % partName)
+                print('  Bundle: %r' % bundle)
                 for animName, file, animControl in animInfo:
                 for animName, file, animControl in animInfo:
-                    print '    Anim:', animName
-                    print '      File:', file
+                    print('    Anim: %s' % animName)
+                    print('      File: %s' % file)
                     if animControl == None:
                     if animControl == None:
-                        print ' (not loaded)'
+                        print(' (not loaded)')
                     else:
                     else:
-                        print ('      NumFrames: %d PlayRate: %0.2f' %
+                        print('      NumFrames: %d PlayRate: %0.2f' %
                                (animControl.getNumFrames(),
                                (animControl.getNumFrames(),
                                 animControl.getPlayRate()))
                                 animControl.getPlayRate()))
 
 
@@ -568,7 +567,7 @@ class Actor(DirectObject, NodePath):
     def __updateSortedLODNames(self):
     def __updateSortedLODNames(self):
         # Cache the sorted LOD names so we don't have to grab them
         # Cache the sorted LOD names so we don't have to grab them
         # and sort them every time somebody asks for the list
         # and sort them every time somebody asks for the list
-        self.__sortedLODNames = self.__partBundleDict.keys()
+        self.__sortedLODNames = list(self.__partBundleDict.keys())
         # Reverse sort the doing a string->int
         # Reverse sort the doing a string->int
         def sortKey(x):
         def sortKey(x):
             if not str(x).isdigit():
             if not str(x).isdigit():
@@ -604,8 +603,8 @@ class Actor(DirectObject, NodePath):
         """
         """
         partNames = []
         partNames = []
         if self.__partBundleDict:
         if self.__partBundleDict:
-            partNames = self.__partBundleDict.values()[0].keys()
-        return partNames + self.__subpartDict.keys()
+            partNames = list(next(iter(self.__partBundleDict.values())).keys())
+        return partNames + list(self.__subpartDict.keys())
 
 
     def getGeomNode(self):
     def getGeomNode(self):
         """
         """
@@ -646,33 +645,33 @@ class Actor(DirectObject, NodePath):
         """
         """
         # make sure we don't call this twice in a row
         # make sure we don't call this twice in a row
         # and pollute the the switches dictionary
         # and pollute the the switches dictionary
-##         sortedKeys = self.switches.keys()
+##         sortedKeys = list(self.switches.keys())
 ##         sortedKeys.sort()
 ##         sortedKeys.sort()
         child = self.__LODNode.find(str(lodName))
         child = self.__LODNode.find(str(lodName))
         index = self.__LODNode.node().findChild(child.node())
         index = self.__LODNode.node().findChild(child.node())
         self.__LODNode.node().forceSwitch(index)
         self.__LODNode.node().forceSwitch(index)
 
 
     def printLOD(self):
     def printLOD(self):
-##         sortedKeys = self.switches.keys()
+##         sortedKeys = list(self.switches.keys())
 ##         sortedKeys.sort()
 ##         sortedKeys.sort()
         sortedKeys = self.__sortedLODNames
         sortedKeys = self.__sortedLODNames
         for eachLod in sortedKeys:
         for eachLod in sortedKeys:
-            print "python switches for %s: in: %d, out %d" % (eachLod,
+            print("python switches for %s: in: %d, out %d" % (eachLod,
                                               self.switches[eachLod][0],
                                               self.switches[eachLod][0],
-                                              self.switches[eachLod][1])
+                                              self.switches[eachLod][1]))
 
 
         switchNum = self.__LODNode.node().getNumSwitches()
         switchNum = self.__LODNode.node().getNumSwitches()
         for eachSwitch in range(0, switchNum):
         for eachSwitch in range(0, switchNum):
-            print "c++ switches for %d: in: %d, out: %d" % (eachSwitch,
+            print("c++ switches for %d: in: %d, out: %d" % (eachSwitch,
                    self.__LODNode.node().getIn(eachSwitch),
                    self.__LODNode.node().getIn(eachSwitch),
-                   self.__LODNode.node().getOut(eachSwitch))
+                   self.__LODNode.node().getOut(eachSwitch)))
 
 
 
 
     def resetLOD(self):
     def resetLOD(self):
         """
         """
         Restore all switch distance info (usually after a useLOD call)"""
         Restore all switch distance info (usually after a useLOD call)"""
         self.__LODNode.node().clearForceSwitch()
         self.__LODNode.node().clearForceSwitch()
-##         sortedKeys = self.switches.keys()
+##         sortedKeys = list(self.switches.keys())
 ##         sortedKeys.sort()
 ##         sortedKeys.sort()
 ##         for eachLod in sortedKeys:
 ##         for eachLod in sortedKeys:
 ##             index = sortedKeys.index(eachLod)
 ##             index = sortedKeys.index(eachLod)
@@ -699,7 +698,7 @@ class Actor(DirectObject, NodePath):
         # save the switch distance info
         # save the switch distance info
         self.switches[lodName] = [inDist, outDist]
         self.switches[lodName] = [inDist, outDist]
         # add the switch distance info
         # add the switch distance info
-##         sortedKeys = self.switches.keys()
+##         sortedKeys = list(self.switches.keys())
 ##         sortedKeys.sort()
 ##         sortedKeys.sort()
         self.__LODNode.node().setSwitch(self.getLODIndex(lodName), inDist, outDist)
         self.__LODNode.node().setSwitch(self.getLODIndex(lodName), inDist, outDist)
 
 
@@ -798,7 +797,7 @@ class Actor(DirectObject, NodePath):
             lodName = lodNames[lod]
             lodName = lodNames[lod]
             if partName == None:
             if partName == None:
                 partBundleDict = self.__partBundleDict[lodName]
                 partBundleDict = self.__partBundleDict[lodName]
-                partNames = partBundleDict.keys()
+                partNames = list(partBundleDict.keys())
             else:
             else:
                 partNames = [partName]
                 partNames = [partName]
 
 
@@ -822,7 +821,7 @@ class Actor(DirectObject, NodePath):
         If no part specified, return anim durations of first part.
         If no part specified, return anim durations of first part.
         NOTE: returns info only for an arbitrary LOD
         NOTE: returns info only for an arbitrary LOD
         """
         """
-        lodName = self.__animControlDict.keys()[0]
+        lodName = next(iter(self.__animControlDict))
         controls = self.getAnimControls(animName, partName)
         controls = self.getAnimControls(animName, partName)
         if len(controls) == 0:
         if len(controls) == 0:
             return None
             return None
@@ -834,7 +833,7 @@ class Actor(DirectObject, NodePath):
         Return frame rate of given anim name and given part, unmodified
         Return frame rate of given anim name and given part, unmodified
         by any play rate in effect.
         by any play rate in effect.
         """
         """
-        lodName = self.__animControlDict.keys()[0]
+        lodName = next(iter(self.__animControlDict))
         controls = self.getAnimControls(animName, partName)
         controls = self.getAnimControls(animName, partName)
         if len(controls) == 0:
         if len(controls) == 0:
             return None
             return None
@@ -850,7 +849,7 @@ class Actor(DirectObject, NodePath):
         """
         """
         if self.__animControlDict:
         if self.__animControlDict:
             # use the first lod
             # use the first lod
-            lodName = self.__animControlDict.keys()[0]
+            lodName = next(iter(self.__animControlDict))
             controls = self.getAnimControls(animName, partName)
             controls = self.getAnimControls(animName, partName)
             if controls:
             if controls:
                 return controls[0].getPlayRate()
                 return controls[0].getPlayRate()
@@ -877,7 +876,7 @@ class Actor(DirectObject, NodePath):
         If no part specified, return anim duration of first part.
         If no part specified, return anim duration of first part.
         NOTE: returns info for arbitrary LOD
         NOTE: returns info for arbitrary LOD
         """
         """
-        lodName = self.__animControlDict.keys()[0]
+        lodName = next(iter(self.__animControlDict))
         controls = self.getAnimControls(animName, partName)
         controls = self.getAnimControls(animName, partName)
         if len(controls) == 0:
         if len(controls) == 0:
             return None
             return None
@@ -890,7 +889,7 @@ class Actor(DirectObject, NodePath):
         return ((toFrame+1)-fromFrame) / animControl.getFrameRate()
         return ((toFrame+1)-fromFrame) / animControl.getFrameRate()
 
 
     def getNumFrames(self, animName=None, partName=None):
     def getNumFrames(self, animName=None, partName=None):
-        lodName = self.__animControlDict.keys()[0]
+        lodName = next(iter(self.__animControlDict))
         controls = self.getAnimControls(animName, partName)
         controls = self.getAnimControls(animName, partName)
         if len(controls) == 0:
         if len(controls) == 0:
             return None
             return None
@@ -908,12 +907,12 @@ class Actor(DirectObject, NodePath):
         specified return current anim of an arbitrary part in dictionary.
         specified return current anim of an arbitrary part in dictionary.
         NOTE: only returns info for an arbitrary LOD
         NOTE: only returns info for an arbitrary LOD
         """
         """
-        if len(self.__animControlDict.items()) == 0:
+        if len(self.__animControlDict) == 0:
             return
             return
 
 
-        lodName, animControlDict = self.__animControlDict.items()[0]
+        lodName, animControlDict = next(iter(self.__animControlDict.items()))
         if partName == None:
         if partName == None:
-            partName, animDict = animControlDict.items()[0]
+            partName, animDict = next(iter(animControlDict.items()))
         else:
         else:
             animDict = animControlDict.get(partName)
             animDict = animControlDict.get(partName)
             if animDict == None:
             if animDict == None:
@@ -936,9 +935,9 @@ class Actor(DirectObject, NodePath):
         actor. If part not specified return current anim of first part
         actor. If part not specified return current anim of first part
         in dictionary.  NOTE: only returns info for an arbitrary LOD
         in dictionary.  NOTE: only returns info for an arbitrary LOD
         """
         """
-        lodName, animControlDict = self.__animControlDict.items()[0]
+        lodName, animControlDict = next(iter(self.__animControlDict.items()))
         if partName == None:
         if partName == None:
-            partName, animDict = animControlDict.items()[0]
+            partName, animDict = next(iter(animControlDict.items()))
         else:
         else:
             animDict = animControlDict.get(partName)
             animDict = animControlDict.get(partName)
             if animDict == None:
             if animDict == None:
@@ -1420,17 +1419,15 @@ class Actor(DirectObject, NodePath):
         if mode > 0:
         if mode > 0:
             # Use the 'fixed' bin instead of reordering the scene
             # Use the 'fixed' bin instead of reordering the scene
             # graph.
             # graph.
-            numFrontParts = frontParts.getNumPaths()
-            for partNum in range(0, numFrontParts):
-                frontParts[partNum].setBin('fixed', mode)
+            for part in frontParts:
+                part.setBin('fixed', mode)
             return
             return
 
 
         if mode == -2:
         if mode == -2:
             # Turn off depth test/write on the frontParts.
             # Turn off depth test/write on the frontParts.
-            numFrontParts = frontParts.getNumPaths()
-            for partNum in range(0, numFrontParts):
-                frontParts[partNum].setDepthWrite(0)
-                frontParts[partNum].setDepthTest(0)
+            for part in frontParts:
+                part.setDepthWrite(0)
+                part.setDepthTest(0)
 
 
         # Find the back part.
         # Find the back part.
         backPart = root.find("**/" + backPartName)
         backPart = root.find("**/" + backPartName)
@@ -1457,12 +1454,8 @@ class Actor(DirectObject, NodePath):
                     char = partData.partBundleNP
                     char = partData.partBundleNP
                     char.node().update()
                     char.node().update()
                     geomNodes = char.findAllMatches("**/+GeomNode")
                     geomNodes = char.findAllMatches("**/+GeomNode")
-                    numGeomNodes = geomNodes.getNumPaths()
-                    for nodeNum in xrange(numGeomNodes):
-                        thisGeomNode = geomNodes.getPath(nodeNum)
-                        numGeoms = thisGeomNode.node().getNumGeoms()
-                        for geomNum in xrange(numGeoms):
-                            thisGeom = thisGeomNode.node().getGeom(geomNum)
+                    for thisGeomNode in geomNodes:
+                        for thisGeom in thisGeomNode.node().getGeoms():
                             thisGeom.markBoundsStale()
                             thisGeom.markBoundsStale()
                         thisGeomNode.node().markInternalBoundsStale()
                         thisGeomNode.node().markInternalBoundsStale()
         else:
         else:
@@ -1473,12 +1466,8 @@ class Actor(DirectObject, NodePath):
                     char = partData.partBundleNP
                     char = partData.partBundleNP
                     char.node().update()
                     char.node().update()
                     geomNodes = char.findAllMatches("**/+GeomNode")
                     geomNodes = char.findAllMatches("**/+GeomNode")
-                    numGeomNodes = geomNodes.getNumPaths()
-                    for nodeNum in xrange(numGeomNodes):
-                        thisGeomNode = geomNodes.getPath(nodeNum)
-                        numGeoms = thisGeomNode.node().getNumGeoms()
-                        for geomNum in xrange(numGeoms):
-                            thisGeom = thisGeomNode.node().getGeom(geomNum)
+                    for thisGeomNode in geomNodes:
+                        for thisGeom in thisGeomNode.node().getGeoms():
                             thisGeom.markBoundsStale()
                             thisGeom.markBoundsStale()
                         thisGeomNode.node().markInternalBoundsStale()
                         thisGeomNode.node().markInternalBoundsStale()
 
 
@@ -1494,19 +1483,14 @@ class Actor(DirectObject, NodePath):
 
 
         # update all characters first
         # update all characters first
         charNodes = part.findAllMatches("**/+Character")
         charNodes = part.findAllMatches("**/+Character")
-        numCharNodes = charNodes.getNumPaths()
-        for charNum in range(0, numCharNodes):
-            (charNodes.getPath(charNum)).node().update()
+        for charNode in charNodes:
+            charNode.node().update()
 
 
         # for each geomNode, iterate through all geoms and force update
         # for each geomNode, iterate through all geoms and force update
         # of bounding spheres by marking current bounds as stale
         # of bounding spheres by marking current bounds as stale
         geomNodes = part.findAllMatches("**/+GeomNode")
         geomNodes = part.findAllMatches("**/+GeomNode")
-        numGeomNodes = geomNodes.getNumPaths()
-        for nodeNum in range(0, numGeomNodes):
-            thisGeomNode = geomNodes.getPath(nodeNum)
-            numGeoms = thisGeomNode.node().getNumGeoms()
-            for geomNum in range(0, numGeoms):
-                thisGeom = thisGeomNode.node().getGeom(geomNum)
+        for nodeNum, thisGeomNode in enumerate(geomNodes):
+            for geomNum, thisGeom in enumerate(thisGeomNode.node().getGeoms()):
                 thisGeom.markBoundsStale()
                 thisGeom.markBoundsStale()
                 assert Actor.notify.debug("fixing bounds for node %s, geom %s" % \
                 assert Actor.notify.debug("fixing bounds for node %s, geom %s" % \
                                           (nodeNum, geomNum))
                                           (nodeNum, geomNum))
@@ -1517,20 +1501,18 @@ class Actor(DirectObject, NodePath):
         Show the bounds of all actor geoms
         Show the bounds of all actor geoms
         """
         """
         geomNodes = self.__geomNode.findAllMatches("**/+GeomNode")
         geomNodes = self.__geomNode.findAllMatches("**/+GeomNode")
-        numGeomNodes = geomNodes.getNumPaths()
 
 
-        for nodeNum in range(0, numGeomNodes):
-            geomNodes.getPath(nodeNum).showBounds()
+        for node in geomNodes:
+            node.showBounds()
 
 
     def hideAllBounds(self):
     def hideAllBounds(self):
         """
         """
         Hide the bounds of all actor geoms
         Hide the bounds of all actor geoms
         """
         """
         geomNodes = self.__geomNode.findAllMatches("**/+GeomNode")
         geomNodes = self.__geomNode.findAllMatches("**/+GeomNode")
-        numGeomNodes = geomNodes.getNumPaths()
 
 
-        for nodeNum in range(0, numGeomNodes):
-            geomNodes.getPath(nodeNum).hideBounds()
+        for node in geomNodes:
+            node.hideBounds()
 
 
 
 
     # actions
     # actions
@@ -1698,7 +1680,7 @@ class Actor(DirectObject, NodePath):
         if self.mergeLODBundles:
         if self.mergeLODBundles:
             lodName = 'common'
             lodName = 'common'
         elif self.switches:
         elif self.switches:
-            lodName = str(self.switches.keys()[0])
+            lodName = str(next(iter(self.switches)))
         else:
         else:
             lodName = 'lodRoot'
             lodName = 'lodRoot'
 
 
@@ -1723,7 +1705,7 @@ class Actor(DirectObject, NodePath):
             lodName = 'common'
             lodName = 'common'
         elif not lodName:
         elif not lodName:
             if self.switches:
             if self.switches:
-                lodName = str(self.switches.keys()[0])
+                lodName = str(next(iter(self.switches)))
             else:
             else:
                 lodName = 'lodRoot'
                 lodName = 'lodRoot'
 
 
@@ -1777,7 +1759,7 @@ class Actor(DirectObject, NodePath):
             # If we have the __subpartsComplete flag, and no partName
             # If we have the __subpartsComplete flag, and no partName
             # is specified, it really means to play the animation on
             # is specified, it really means to play the animation on
             # all subparts, not on the overall Actor.
             # all subparts, not on the overall Actor.
-            partName = self.__subpartDict.keys()
+            partName = list(self.__subpartDict.keys())
 
 
         controls = []
         controls = []
         # build list of lodNames and corresponding animControlDicts
         # build list of lodNames and corresponding animControlDicts
@@ -1805,7 +1787,7 @@ class Actor(DirectObject, NodePath):
 
 
             else:
             else:
                 # Get exactly the named part or parts.
                 # Get exactly the named part or parts.
-                if isinstance(partName, types.StringTypes):
+                if isinstance(partName, str):
                     partNameList = [partName]
                     partNameList = [partName]
                 else:
                 else:
                     partNameList = partName
                     partNameList = partName
@@ -1835,7 +1817,7 @@ class Actor(DirectObject, NodePath):
                             controls.append(anim.animControl)
                             controls.append(anim.animControl)
             else:
             else:
                 # get the named animation(s) only.
                 # get the named animation(s) only.
-                if isinstance(animName, types.StringTypes):
+                if isinstance(animName, str):
                     # A single animName
                     # A single animName
                     animNameList = [animName]
                     animNameList = [animName]
                 else:
                 else:
@@ -2107,7 +2089,7 @@ class Actor(DirectObject, NodePath):
             if lodName:
             if lodName:
                 partNames = self.__partBundleDict[lodName].keys()
                 partNames = self.__partBundleDict[lodName].keys()
             else:
             else:
-                partNames = self.__partBundleDict.values()[0].keys()
+                partNames = next(iter(self.__partBundleDict.values())).keys()
 
 
         for partName in partNames:
         for partName in partNames:
             subJoints = set()
             subJoints = set()
@@ -2133,9 +2115,9 @@ class Actor(DirectObject, NodePath):
             lodNames = ['common']
             lodNames = ['common']
         elif lodName == 'all':
         elif lodName == 'all':
             reload = False
             reload = False
-            lodNames = self.switches.keys()
+            lodNames = list(self.switches.keys())
             lodNames.sort()
             lodNames.sort()
-            for i in range(0,len(lodNames)):
+            for i in range(0, len(lodNames)):
                 lodNames[i] = str(lodNames[i])
                 lodNames[i] = str(lodNames[i])
         else:
         else:
             lodNames = [lodName]
             lodNames = [lodName]
@@ -2256,20 +2238,20 @@ class Actor(DirectObject, NodePath):
         assert Actor.notify.debug("in unloadAnims: %s, part: %s, lod: %s" %
         assert Actor.notify.debug("in unloadAnims: %s, part: %s, lod: %s" %
                                   (anims, partName, lodName))
                                   (anims, partName, lodName))
 
 
-        if lodName == None or self.mergeLODBundles:
+        if lodName is None or self.mergeLODBundles:
             lodNames = self.__animControlDict.keys()
             lodNames = self.__animControlDict.keys()
         else:
         else:
             lodNames = [lodName]
             lodNames = [lodName]
 
 
-        if (partName == None):
+        if partName is None:
             if len(lodNames) > 0:
             if len(lodNames) > 0:
-                partNames = self.__animControlDict[lodNames[0]].keys()
+                partNames = self.__animControlDict[next(iter(lodNames))].keys()
             else:
             else:
                 partNames = []
                 partNames = []
         else:
         else:
             partNames = [partName]
             partNames = [partName]
 
 
-        if (anims==None):
+        if anims is None:
             for lodName in lodNames:
             for lodName in lodNames:
                 for partName in partNames:
                 for partName in partNames:
                     for animDef in self.__animControlDict[lodName][partName].values():
                     for animDef in self.__animControlDict[lodName][partName].values():
@@ -2400,7 +2382,7 @@ class Actor(DirectObject, NodePath):
         Copy the part bundle dictionary from another actor as this
         Copy the part bundle dictionary from another actor as this
         instance's own. NOTE: this method does not actually copy geometry
         instance's own. NOTE: this method does not actually copy geometry
         """
         """
-        for lodName in other.__partBundleDict.keys():
+        for lodName in other.__partBundleDict:
             # find the lod Asad
             # find the lod Asad
             if lodName == 'lodRoot':
             if lodName == 'lodRoot':
                 partLod = self
                 partLod = self
@@ -2445,11 +2427,11 @@ class Actor(DirectObject, NodePath):
 
 
         assert(other.mergeLODBundles == self.mergeLODBundles)
         assert(other.mergeLODBundles == self.mergeLODBundles)
 
 
-        for lodName in other.__animControlDict.keys():
+        for lodName in other.__animControlDict:
             self.__animControlDict[lodName] = {}
             self.__animControlDict[lodName] = {}
-            for partName in other.__animControlDict[lodName].keys():
+            for partName in other.__animControlDict[lodName]:
                 self.__animControlDict[lodName][partName] = {}
                 self.__animControlDict[lodName][partName] = {}
-                for animName in other.__animControlDict[lodName][partName].keys():
+                for animName in other.__animControlDict[lodName][partName]:
                     anim = other.__animControlDict[lodName][partName][animName]
                     anim = other.__animControlDict[lodName][partName][animName]
                     anim = anim.makeCopy()
                     anim = anim.makeCopy()
                     self.__animControlDict[lodName][partName][animName] = anim
                     self.__animControlDict[lodName][partName][animName] = anim
@@ -2512,13 +2494,13 @@ class Actor(DirectObject, NodePath):
 
 
     def printAnimBlends(self, animName=None, partName=None, lodName=None):
     def printAnimBlends(self, animName=None, partName=None, lodName=None):
         for lodName, animList in self.getAnimBlends(animName, partName, lodName):
         for lodName, animList in self.getAnimBlends(animName, partName, lodName):
-            print 'LOD %s:' % (lodName)
+            print('LOD %s:' % (lodName))
             for animName, blendList in animList:
             for animName, blendList in animList:
 
 
                 list = []
                 list = []
                 for partName, effect in blendList:
                 for partName, effect in blendList:
                     list.append('%s:%.3f' % (partName, effect))
                     list.append('%s:%.3f' % (partName, effect))
-                print '  %s: %s' % (animName, ', '.join(list))
+                print('  %s: %s' % (animName, ', '.join(list)))
 
 
     def osdAnimBlends(self, animName=None, partName=None, lodName=None):
     def osdAnimBlends(self, animName=None, partName=None, lodName=None):
         if not onScreenDebug.enabled:
         if not onScreenDebug.enabled:
@@ -2565,5 +2547,5 @@ class Actor(DirectObject, NodePath):
     def renamePartBundles(self, partName, newBundleName):
     def renamePartBundles(self, partName, newBundleName):
         subpartDef = self.__subpartDict.get(partName, Actor.SubpartDef(partName))
         subpartDef = self.__subpartDict.get(partName, Actor.SubpartDef(partName))
         for partBundleDict in self.__partBundleDict.values():
         for partBundleDict in self.__partBundleDict.values():
-            partDef=partBundleDict.get(subpartDef.truePartName)
+            partDef = partBundleDict.get(subpartDef.truePartName)
             partDef.getBundle().setName(newBundleName)
             partDef.getBundle().setName(newBundleName)

+ 1 - 1
direct/src/actor/DistributedActor.py

@@ -4,7 +4,7 @@ __all__ = ['DistributedActor']
 
 
 from direct.distributed import DistributedNode
 from direct.distributed import DistributedNode
 
 
-import Actor
+from . import Actor
 
 
 class DistributedActor(DistributedNode.DistributedNode, Actor.Actor):
 class DistributedActor(DistributedNode.DistributedNode, Actor.Actor):
     def __init__(self, cr):
     def __init__(self, cr):

+ 8 - 10
direct/src/cluster/ClusterClient.py

@@ -1,8 +1,8 @@
 """ClusterClient: Master for mutli-piping or PC clusters.  """
 """ClusterClient: Master for mutli-piping or PC clusters.  """
 
 
 from panda3d.core import *
 from panda3d.core import *
-from ClusterMsgs import *
-from ClusterConfig import *
+from .ClusterMsgs import *
+from .ClusterConfig import *
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
 from direct.showbase import DirectObject
 from direct.showbase import DirectObject
 from direct.task import Task
 from direct.task import Task
@@ -44,10 +44,10 @@ class ClusterClient(DirectObject.DirectObject):
             self.daemon.tellServer(serverConfig.serverName,
             self.daemon.tellServer(serverConfig.serverName,
                                    serverConfig.serverDaemonPort,
                                    serverConfig.serverDaemonPort,
                                    serverCommand)
                                    serverCommand)
-        print 'Begin waitForServers'
+        print('Begin waitForServers')
         if not self.daemon.waitForServers(len(configList)):
         if not self.daemon.waitForServers(len(configList)):
-            print 'Cluster Client, no response from servers'
-        print 'End waitForServers'
+            print('Cluster Client, no response from servers')
+        print('End waitForServers')
         self.qcm=QueuedConnectionManager()
         self.qcm=QueuedConnectionManager()
         self.serverList = []
         self.serverList = []
         self.serverQueues = []
         self.serverQueues = []
@@ -262,9 +262,8 @@ class ClusterClient(DirectObject.DirectObject):
 
 
 
 
     def getNodePathFindCmd(self, nodePath):
     def getNodePathFindCmd(self, nodePath):
-        import string
         pathString = repr(nodePath)
         pathString = repr(nodePath)
-        index = string.find(pathString, '/')
+        index = pathString.find('/')
         if index != -1:
         if index != -1:
             rootName = pathString[:index]
             rootName = pathString[:index]
             searchString = pathString[index+1:]
             searchString = pathString[index+1:]
@@ -273,9 +272,8 @@ class ClusterClient(DirectObject.DirectObject):
             return rootName
             return rootName
 
 
     def getNodePathName(self, nodePath):
     def getNodePathName(self, nodePath):
-        import string
         pathString = repr(nodePath)
         pathString = repr(nodePath)
-        index = string.find(pathString, '/')
+        index = pathString.find('/')
         if index != -1:
         if index != -1:
             name = pathString[index+1:]
             name = pathString[index+1:]
             return name
             return name
@@ -409,7 +407,7 @@ class ClusterClientSync(ClusterClient):
         #I probably don't need this
         #I probably don't need this
         self.waitForSwap = 0
         self.waitForSwap = 0
         self.ready = 0
         self.ready = 0
-        print "creating synced client"
+        print("creating synced client")
         self.startSwapCoordinatorTask()
         self.startSwapCoordinatorTask()
 
 
     def startSwapCoordinatorTask(self):
     def startSwapCoordinatorTask(self):

+ 1 - 1
direct/src/cluster/ClusterConfig.py

@@ -1,5 +1,5 @@
 
 
-from ClusterClient import *
+from .ClusterClient import *
 
 
 # A dictionary of information for various cluster configurations.
 # A dictionary of information for various cluster configurations.
 # Dictionary is keyed on cluster-config string
 # Dictionary is keyed on cluster-config string

+ 2 - 2
direct/src/cluster/ClusterServer.py

@@ -1,5 +1,5 @@
 from panda3d.core import *
 from panda3d.core import *
-from ClusterMsgs import *
+from .ClusterMsgs import *
 from direct.distributed.MsgTypes import *
 from direct.distributed.MsgTypes import *
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
 from direct.showbase import DirectObject
 from direct.showbase import DirectObject
@@ -246,7 +246,7 @@ class ClusterServer(DirectObject.DirectObject):
         if (type == CLUSTER_NONE):
         if (type == CLUSTER_NONE):
             pass
             pass
         elif (type == CLUSTER_EXIT):
         elif (type == CLUSTER_EXIT):
-            print 'GOT EXIT'
+            print('GOT EXIT')
             import sys
             import sys
             sys.exit()
             sys.exit()
         elif (type == CLUSTER_CAM_OFFSET):
         elif (type == CLUSTER_CAM_OFFSET):

+ 3 - 3
direct/src/controls/BattleWalker.py

@@ -2,7 +2,7 @@
 from direct.showbase.InputStateGlobal import inputState
 from direct.showbase.InputStateGlobal import inputState
 from direct.task.Task import Task
 from direct.task.Task import Task
 from pandac.PandaModules import *
 from pandac.PandaModules import *
-import GravityWalker
+from . import GravityWalker
 
 
 BattleStrafe = 0
 BattleStrafe = 0
 
 
@@ -166,7 +166,7 @@ class BattleWalker(GravityWalker.GravityWalker):
             # Should fSlide be renamed slideButton?
             # Should fSlide be renamed slideButton?
             self.slideSpeed=.15*(turnLeft and -self.avatarControlForwardSpeed or
             self.slideSpeed=.15*(turnLeft and -self.avatarControlForwardSpeed or
                                  turnRight and self.avatarControlForwardSpeed)
                                  turnRight and self.avatarControlForwardSpeed)
-            print 'slideSpeed: ', self.slideSpeed
+            print('slideSpeed: %s' % self.slideSpeed)
             self.rotationSpeed=0
             self.rotationSpeed=0
             self.speed=0
             self.speed=0
 
 
@@ -233,7 +233,7 @@ class BattleWalker(GravityWalker.GravityWalker):
             if self.moving:
             if self.moving:
                 distance = dt * self.speed
                 distance = dt * self.speed
                 slideDistance = dt * self.slideSpeed
                 slideDistance = dt * self.slideSpeed
-                print 'slideDistance: ', slideDistance
+                print('slideDistance: %s' % slideDistance)
                 rotation = dt * self.rotationSpeed
                 rotation = dt * self.rotationSpeed
 
 
                 # Take a step in the direction of our previous heading.
                 # Take a step in the direction of our previous heading.

+ 1 - 1
direct/src/controls/GhostWalker.py

@@ -15,7 +15,7 @@ animations based on walker events.
 """
 """
 
 
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
-import NonPhysicsWalker
+from . import NonPhysicsWalker
 
 
 class GhostWalker(NonPhysicsWalker.NonPhysicsWalker):
 class GhostWalker(NonPhysicsWalker.NonPhysicsWalker):
 
 

+ 1 - 1
direct/src/controls/ObserverWalker.py

@@ -16,7 +16,7 @@ animations based on walker events.
 
 
 from panda3d.core import *
 from panda3d.core import *
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
-import NonPhysicsWalker
+from . import NonPhysicsWalker
 
 
 class ObserverWalker(NonPhysicsWalker.NonPhysicsWalker):
 class ObserverWalker(NonPhysicsWalker.NonPhysicsWalker):
     notify = DirectNotifyGlobal.directNotify.newCategory("ObserverWalker")
     notify = DirectNotifyGlobal.directNotify.newCategory("ObserverWalker")

+ 2 - 2
direct/src/controls/PhysicsWalker.py

@@ -324,7 +324,7 @@ class PhysicsWalker(DirectObject.DirectObject):
             indicator.instanceTo(contactIndicatorNode)
             indicator.instanceTo(contactIndicatorNode)
             self.physContactIndicator=contactIndicatorNode
             self.physContactIndicator=contactIndicatorNode
         else:
         else:
-            print "failed load of physics indicator"
+            print("failed load of physics indicator")
 
 
     def avatarPhysicsIndicator(self, task):
     def avatarPhysicsIndicator(self, task):
         #assert self.debugPrint("avatarPhysicsIndicator()")
         #assert self.debugPrint("avatarPhysicsIndicator()")
@@ -710,7 +710,7 @@ class PhysicsWalker(DirectObject.DirectObject):
     def setPriorParentVector(self):
     def setPriorParentVector(self):
         assert self.debugPrint("doDeltaPos()")
         assert self.debugPrint("doDeltaPos()")
 
 
-        print "self.__oldDt", self.__oldDt, "self.__oldPosDelta", self.__oldPosDelta
+        print("self.__oldDt %s self.__oldPosDelta %s" % (self.__oldDt, self.__oldPosDelta))
         if __debug__:
         if __debug__:
             onScreenDebug.add("__oldDt", "% 10.4f"%self.__oldDt)
             onScreenDebug.add("__oldDt", "% 10.4f"%self.__oldDt)
             onScreenDebug.add("self.__oldPosDelta",
             onScreenDebug.add("self.__oldPosDelta",

+ 1 - 1
direct/src/controls/TwoDWalker.py

@@ -2,7 +2,7 @@
 TwoDWalker.py is for controling the avatars in a 2D Scroller game environment.
 TwoDWalker.py is for controling the avatars in a 2D Scroller game environment.
 """
 """
 
 
-from GravityWalker import *
+from .GravityWalker import *
 from panda3d.core import ConfigVariableBool
 from panda3d.core import ConfigVariableBool
 
 
 
 

+ 1 - 1
direct/src/directbase/ThreeUpStart.py

@@ -1,5 +1,5 @@
 
 
-print 'ThreeUpStart: Starting up environment.'
+print('ThreeUpStart: Starting up environment.')
 
 
 from pandac.PandaModules import *
 from pandac.PandaModules import *
 
 

+ 1 - 1
direct/src/directdevices/DirectFastrak.py

@@ -1,7 +1,7 @@
 """ Class used to create and control radamec device """
 """ Class used to create and control radamec device """
 from math import *
 from math import *
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
-from DirectDeviceManager import *
+from .DirectDeviceManager import *
 
 
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
 
 

+ 1 - 1
direct/src/directdevices/DirectJoybox.py

@@ -1,6 +1,6 @@
 """ Class used to create and control joybox device """
 """ Class used to create and control joybox device """
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
-from DirectDeviceManager import *
+from .DirectDeviceManager import *
 from direct.directtools.DirectUtil import *
 from direct.directtools.DirectUtil import *
 from direct.gui import OnscreenText
 from direct.gui import OnscreenText
 from direct.task import Task
 from direct.task import Task

+ 1 - 1
direct/src/directdevices/DirectRadamec.py

@@ -1,7 +1,7 @@
 """ Class used to create and control radamec device """
 """ Class used to create and control radamec device """
 from math import *
 from math import *
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
-from DirectDeviceManager import *
+from .DirectDeviceManager import *
 
 
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
 
 

+ 4 - 4
direct/src/directnotify/DirectNotify.py

@@ -2,8 +2,8 @@
 DirectNotify module: this module contains the DirectNotify class
 DirectNotify module: this module contains the DirectNotify class
 """
 """
 
 
-import Notifier
-import Logger
+from . import Notifier
+from . import Logger
 
 
 class DirectNotify:
 class DirectNotify:
     """
     """
@@ -35,7 +35,7 @@ class DirectNotify:
         """
         """
         Return list of category dictionary keys
         Return list of category dictionary keys
         """
         """
-        return (self.__categories.keys())
+        return list(self.__categories.keys())
 
 
     def getCategory(self, categoryName):
     def getCategory(self, categoryName):
         """getCategory(self, string)
         """getCategory(self, string)
@@ -97,7 +97,7 @@ class DirectNotify:
             category.setInfo(1)
             category.setInfo(1)
             category.setDebug(1)
             category.setDebug(1)
         else:
         else:
-            print ("DirectNotify: unknown notify level: " + str(level)
+            print("DirectNotify: unknown notify level: " + str(level)
                    + " for category: " + str(categoryName))
                    + " for category: " + str(categoryName))
 
 
 
 

+ 1 - 1
direct/src/directnotify/DirectNotifyGlobal.py

@@ -2,7 +2,7 @@
 
 
 __all__ = ['directNotify', 'giveNotify']
 __all__ = ['directNotify', 'giveNotify']
 
 
-import DirectNotify
+from . import DirectNotify
 
 
 directNotify = DirectNotify.DirectNotify()
 directNotify = DirectNotify.DirectNotify()
 giveNotify = directNotify.giveNotify
 giveNotify = directNotify.giveNotify

+ 1 - 1
direct/src/directnotify/LoggerGlobal.py

@@ -1,5 +1,5 @@
 """instantiate global Logger object"""
 """instantiate global Logger object"""
 
 
-import Logger
+from . import Logger
 
 
 defaultLogger = Logger.Logger()
 defaultLogger = Logger.Logger()

+ 2 - 2
direct/src/directnotify/Notifier.py

@@ -2,7 +2,7 @@
 Notifier module: contains methods for handling information output
 Notifier module: contains methods for handling information output
 for the programmer/user
 for the programmer/user
 """
 """
-from LoggerGlobal import defaultLogger
+from .LoggerGlobal import defaultLogger
 from direct.showbase import PythonUtil
 from direct.showbase import PythonUtil
 from panda3d.core import ConfigVariableBool, NotifyCategory, StreamWriter, Notify
 from panda3d.core import ConfigVariableBool, NotifyCategory, StreamWriter, Notify
 import time
 import time
@@ -237,7 +237,7 @@ class Notifier:
         if self.streamWriter:
         if self.streamWriter:
             self.streamWriter.write(string + '\n')
             self.streamWriter.write(string + '\n')
         else:
         else:
-            print >> sys.stderr, string
+            sys.stderr.write(string + '\n')
 
 
     def debugStateCall(self, obj=None, fsmMemberName='fsm',
     def debugStateCall(self, obj=None, fsmMemberName='fsm',
             secondaryFsm='secondaryFSM'):
             secondaryFsm='secondaryFSM'):

+ 4 - 3
direct/src/directnotify/RotatingLog.py

@@ -91,7 +91,7 @@ class RotatingLog:
                 self.timeLimit=time.time()+self.timeInterval
                 self.timeLimit=time.time()+self.timeInterval
         else:
         else:
             # We'll keep writing to the old file, if available.
             # We'll keep writing to the old file, if available.
-            print "RotatingLog error: Unable to open new log file \"%s\"."%(path,)
+            print("RotatingLog error: Unable to open new log file \"%s\"." % (path,))
 
 
     def write(self, data):
     def write(self, data):
         """
         """
@@ -115,8 +115,9 @@ class RotatingLog:
     def isatty(self):
     def isatty(self):
         return self.file.isatty()
         return self.file.isatty()
 
 
-    def next(self):
-        return self.file.next()
+    def __next__(self):
+        return next(self.file)
+    next = __next__
 
 
     def read(self, size):
     def read(self, size):
         return self.file.read(size)
         return self.file.read(size)

+ 5 - 5
direct/src/directscripts/eggcacher.py

@@ -19,8 +19,8 @@ class EggCacher:
         self.pandaloader = Loader()
         self.pandaloader = Loader()
         self.loaderopts = LoaderOptions(LoaderOptions.LF_no_ram_cache)
         self.loaderopts = LoaderOptions(LoaderOptions.LF_no_ram_cache)
         if (self.bamcache.getActive() == 0):
         if (self.bamcache.getActive() == 0):
-            print "The model cache is not currently active."
-            print "You must set a model-cache-dir in your config file."
+            print("The model cache is not currently active.")
+            print("You must set a model-cache-dir in your config file.")
             sys.exit(1)
             sys.exit(1)
         self.parseArgs(args)
         self.parseArgs(args)
         files = self.scanPaths(self.paths)
         files = self.scanPaths(self.paths)
@@ -39,13 +39,13 @@ class EggCacher:
             else:
             else:
                 break
                 break
         if (len(args) < 1):
         if (len(args) < 1):
-            print "Usage: eggcacher options file-or-directory"
+            print("Usage: eggcacher options file-or-directory")
             sys.exit(1)
             sys.exit(1)
         self.paths = args
         self.paths = args
 
 
     def scanPath(self, eggs, path):
     def scanPath(self, eggs, path):
         if (os.path.exists(path)==0):
         if (os.path.exists(path)==0):
-            print "No such file or directory: "+path
+            print("No such file or directory: " + path)
             return
             return
         if (os.path.isdir(path)):
         if (os.path.isdir(path)):
             for f in os.listdir(path):
             for f in os.listdir(path):
@@ -78,7 +78,7 @@ class EggCacher:
             percent = (progress * 100) / total
             percent = (progress * 100) / total
             report = path
             report = path
             if (self.concise): report = os.path.basename(report)
             if (self.concise): report = os.path.basename(report)
-            print "Preprocessing Models %2d%% %s" % (percent, report)
+            print("Preprocessing Models %2d%% %s" % (percent, report))
             sys.stdout.flush()
             sys.stdout.flush()
             if (cached) and (cached.hasData()==0):
             if (cached) and (cached.hasData()==0):
                 self.pandaloader.loadSync(fn, self.loaderopts)
                 self.pandaloader.loadSync(fn, self.loaderopts)

+ 41 - 39
direct/src/directscripts/extract_docs.py

@@ -5,6 +5,8 @@ You need to run this before invoking Doxyfile.python.
 It requires a valid makepanda installation with interrogatedb .in
 It requires a valid makepanda installation with interrogatedb .in
 files in the lib/pandac/input directory. """
 files in the lib/pandac/input directory. """
 
 
+from __future__ import print_function
+
 __all__ = []
 __all__ = []
 
 
 import os
 import os
@@ -156,61 +158,61 @@ def translated_type_name(type, scoped=True):
 
 
 def processElement(handle, element):
 def processElement(handle, element):
     if interrogate_element_has_comment(element):
     if interrogate_element_has_comment(element):
-        print >>handle, comment(interrogate_element_comment(element))
+        print(comment(interrogate_element_comment(element)), file=handle)
 
 
-    print >>handle, translated_type_name(interrogate_element_type(element)),
-    print >>handle, interrogate_element_name(element) + ';'
+    print(translated_type_name(interrogate_element_type(element)), end=' ', file=handle)
+    print(interrogate_element_name(element) + ';', file=handle)
 
 
 def processFunction(handle, function, isConstructor = False):
 def processFunction(handle, function, isConstructor = False):
-    for i_wrapper in xrange(interrogate_function_number_of_python_wrappers(function)):
+    for i_wrapper in range(interrogate_function_number_of_python_wrappers(function)):
         wrapper = interrogate_function_python_wrapper(function, i_wrapper)
         wrapper = interrogate_function_python_wrapper(function, i_wrapper)
         if interrogate_wrapper_has_comment(wrapper):
         if interrogate_wrapper_has_comment(wrapper):
-            print >>handle, block_comment(interrogate_wrapper_comment(wrapper))
+            print(block_comment(interrogate_wrapper_comment(wrapper)), file=handle)
 
 
         if not isConstructor:
         if not isConstructor:
             if interrogate_function_is_method(function):
             if interrogate_function_is_method(function):
                 if not interrogate_wrapper_number_of_parameters(wrapper) > 0 or not interrogate_wrapper_parameter_is_this(wrapper, 0):
                 if not interrogate_wrapper_number_of_parameters(wrapper) > 0 or not interrogate_wrapper_parameter_is_this(wrapper, 0):
-                    print >>handle, "static",
+                    print("static", end=' ', file=handle)
 
 
             if interrogate_wrapper_has_return_value(wrapper):
             if interrogate_wrapper_has_return_value(wrapper):
-                print >>handle, translated_type_name(interrogate_wrapper_return_type(wrapper)),
+                print(translated_type_name(interrogate_wrapper_return_type(wrapper)), end=' ', file=handle)
             else:
             else:
                 pass#print >>handle, "void",
                 pass#print >>handle, "void",
 
 
-            print >>handle, translateFunctionName(interrogate_function_name(function)) + "(",
+            print(translateFunctionName(interrogate_function_name(function)) + "(", end=' ', file=handle)
         else:
         else:
-            print >>handle, "__init__(",
+            print("__init__(", end=' ', file=handle)
 
 
         first = True
         first = True
         for i_param in range(interrogate_wrapper_number_of_parameters(wrapper)):
         for i_param in range(interrogate_wrapper_number_of_parameters(wrapper)):
             if not interrogate_wrapper_parameter_is_this(wrapper, i_param):
             if not interrogate_wrapper_parameter_is_this(wrapper, i_param):
                 if not first:
                 if not first:
-                    print >>handle, ",",
-                print >>handle, translated_type_name(interrogate_wrapper_parameter_type(wrapper, i_param)),
+                    print(",", end=' ', file=handle)
+                print(translated_type_name(interrogate_wrapper_parameter_type(wrapper, i_param)), end=' ', file=handle)
                 if interrogate_wrapper_parameter_has_name(wrapper, i_param):
                 if interrogate_wrapper_parameter_has_name(wrapper, i_param):
-                    print >>handle, interrogate_wrapper_parameter_name(wrapper, i_param),
+                    print(interrogate_wrapper_parameter_name(wrapper, i_param), end=' ', file=handle)
                 first = False
                 first = False
 
 
-        print >>handle, ");"
+        print(");", file=handle)
 
 
 def processType(handle, type):
 def processType(handle, type):
     typename = translated_type_name(type, scoped=False)
     typename = translated_type_name(type, scoped=False)
     derivations = [ translated_type_name(interrogate_type_get_derivation(type, n)) for n in range(interrogate_type_number_of_derivations(type)) ]
     derivations = [ translated_type_name(interrogate_type_get_derivation(type, n)) for n in range(interrogate_type_number_of_derivations(type)) ]
 
 
     if interrogate_type_has_comment(type):
     if interrogate_type_has_comment(type):
-        print >>handle, block_comment(interrogate_type_comment(type))
+        print(block_comment(interrogate_type_comment(type)), file=handle)
 
 
     if interrogate_type_is_enum(type):
     if interrogate_type_is_enum(type):
-        print >>handle, "enum %s {" % typename
+        print("enum %s {" % typename, file=handle)
         for i_value in range(interrogate_type_number_of_enum_values(type)):
         for i_value in range(interrogate_type_number_of_enum_values(type)):
             docstring = comment(interrogate_type_enum_value_comment(type, i_value))
             docstring = comment(interrogate_type_enum_value_comment(type, i_value))
             if docstring:
             if docstring:
-                print >>handle, docstring
-            print >>handle, interrogate_type_enum_value_name(type, i_value), "=", interrogate_type_enum_value(type, i_value), ","
+                print(docstring, file=handle)
+            print(interrogate_type_enum_value_name(type, i_value), "=", interrogate_type_enum_value(type, i_value), ",", file=handle)
 
 
     elif interrogate_type_is_typedef(type):
     elif interrogate_type_is_typedef(type):
         wrapped_type = translated_type_name(interrogate_type_wrapped_type(type))
         wrapped_type = translated_type_name(interrogate_type_wrapped_type(type))
-        print >>handle, "typedef %s %s;" % (wrapped_type, typename)
+        print("typedef %s %s;" % (wrapped_type, typename), file=handle)
         return
         return
     else:
     else:
         if interrogate_type_is_struct(type):
         if interrogate_type_is_struct(type):
@@ -220,39 +222,39 @@ def processType(handle, type):
         elif interrogate_type_is_union(type):
         elif interrogate_type_is_union(type):
             classtype = "union"
             classtype = "union"
         else:
         else:
-            print "I don't know what type %s is" % interrogate_type_true_name(type)
+            print("I don't know what type %s is" % interrogate_type_true_name(type))
             return
             return
 
 
         if len(derivations) > 0:
         if len(derivations) > 0:
-            print >>handle, "%s %s : public %s {" % (classtype, typename, ", public ".join(derivations))
+            print("%s %s : public %s {" % (classtype, typename, ", public ".join(derivations)), file=handle)
         else:
         else:
-            print >>handle, "%s %s {" % (classtype, typename)
-        print >>handle, "public:"
+            print("%s %s {" % (classtype, typename), file=handle)
+        print("public:", file=handle)
 
 
-    for i_ntype in xrange(interrogate_type_number_of_nested_types(type)):
+    for i_ntype in range(interrogate_type_number_of_nested_types(type)):
         processType(handle, interrogate_type_get_nested_type(type, i_ntype))
         processType(handle, interrogate_type_get_nested_type(type, i_ntype))
 
 
-    for i_method in xrange(interrogate_type_number_of_constructors(type)):
+    for i_method in range(interrogate_type_number_of_constructors(type)):
         processFunction(handle, interrogate_type_get_constructor(type, i_method), True)
         processFunction(handle, interrogate_type_get_constructor(type, i_method), True)
 
 
-    for i_method in xrange(interrogate_type_number_of_methods(type)):
+    for i_method in range(interrogate_type_number_of_methods(type)):
         processFunction(handle, interrogate_type_get_method(type, i_method))
         processFunction(handle, interrogate_type_get_method(type, i_method))
 
 
-    for i_method in xrange(interrogate_type_number_of_make_seqs(type)):
-        print >>handle, "list", translateFunctionName(interrogate_make_seq_seq_name(interrogate_type_get_make_seq(type, i_method))), "();"
+    for i_method in range(interrogate_type_number_of_make_seqs(type)):
+        print("list", translateFunctionName(interrogate_make_seq_seq_name(interrogate_type_get_make_seq(type, i_method))), "();", file=handle)
 
 
-    for i_element in xrange(interrogate_type_number_of_elements(type)):
+    for i_element in range(interrogate_type_number_of_elements(type)):
         processElement(handle, interrogate_type_get_element(type, i_element))
         processElement(handle, interrogate_type_get_element(type, i_element))
 
 
-    print >>handle, "};"
+    print("};", file=handle)
 
 
 def processModule(handle, package):
 def processModule(handle, package):
-    print >>handle, "namespace %s {" % package
+    print("namespace %s {" % package, file=handle)
 
 
     if package != "core":
     if package != "core":
-        print >>handle, "using namespace core;"
+        print("using namespace core;", file=handle)
 
 
-    for i_type in xrange(interrogate_number_of_global_types()):
+    for i_type in range(interrogate_number_of_global_types()):
         type = interrogate_get_global_type(i_type)
         type = interrogate_get_global_type(i_type)
 
 
         if interrogate_type_has_module_name(type):
         if interrogate_type_has_module_name(type):
@@ -260,9 +262,9 @@ def processModule(handle, package):
             if "panda3d." + package == module_name:
             if "panda3d." + package == module_name:
                 processType(handle, type)
                 processType(handle, type)
         else:
         else:
-            print "Type %s has no module name" % typename
+            print("Type %s has no module name" % typename)
 
 
-    for i_func in xrange(interrogate_number_of_global_functions()):
+    for i_func in range(interrogate_number_of_global_functions()):
         func = interrogate_get_global_function(i_func)
         func = interrogate_get_global_function(i_func)
 
 
         if interrogate_function_has_module_name(func):
         if interrogate_function_has_module_name(func):
@@ -270,16 +272,16 @@ def processModule(handle, package):
             if "panda3d." + package == module_name:
             if "panda3d." + package == module_name:
                 processFunction(handle, func)
                 processFunction(handle, func)
         else:
         else:
-            print "Type %s has no module name" % typename
+            print("Type %s has no module name" % typename)
 
 
-    print >>handle, "}"
+    print("}", file=handle)
 
 
 
 
 if __name__ == "__main__":
 if __name__ == "__main__":
     handle = open("pandadoc.hpp", "w")
     handle = open("pandadoc.hpp", "w")
 
 
-    print >>handle, comment("Panda3D modules that are implemented in C++.")
-    print >>handle, "namespace panda3d {"
+    print(comment("Panda3D modules that are implemented in C++."), file=handle)
+    print("namespace panda3d {", file=handle)
 
 
     # Determine the path to the interrogatedb files
     # Determine the path to the interrogatedb files
     interrogate_add_search_directory(os.path.join(os.path.dirname(pandac.__file__), "..", "..", "etc"))
     interrogate_add_search_directory(os.path.join(os.path.dirname(pandac.__file__), "..", "..", "etc"))
@@ -295,5 +297,5 @@ if __name__ == "__main__":
             processModule(handle, module_name)
             processModule(handle, module_name)
 
 
 
 
-    print >>handle, "}"
+    print("}", file=handle)
     handle.close()
     handle.close()

+ 26 - 26
direct/src/directscripts/gendocs.py

@@ -48,7 +48,7 @@
 #
 #
 ########################################################################
 ########################################################################
 
 
-import os, sys, parser, symbol, token, types, re
+import os, sys, parser, symbol, token, re
 
 
 ########################################################################
 ########################################################################
 #
 #
@@ -103,7 +103,7 @@ def writeFileLines(wfile, lines):
         sys.exit("Cannot write "+wfile)
         sys.exit("Cannot write "+wfile)
 
 
 def findFiles(dirlist, ext, ign, list):
 def findFiles(dirlist, ext, ign, list):
-    if isinstance(dirlist, types.StringTypes):
+    if isinstance(dirlist, str):
         dirlist = [dirlist]
         dirlist = [dirlist]
     for dir in dirlist:
     for dir in dirlist:
         for file in os.listdir(dir):
         for file in os.listdir(dir):
@@ -195,8 +195,8 @@ class InterrogateTokenizer:
             neg = 1
             neg = 1
             self.pos += 1
             self.pos += 1
         if (self.data[self.pos].isdigit()==0):
         if (self.data[self.pos].isdigit()==0):
-            print "File position "+str(self.pos)
-            print "Text: "+self.data[self.pos:self.pos+50]
+            print("File position " + str(self.pos))
+            print("Text: " + self.data[self.pos:self.pos+50])
             sys.exit("Syntax error in interrogate file format 0")
             sys.exit("Syntax error in interrogate file format 0")
         value = 0
         value = 0
         while (self.data[self.pos].isdigit()):
         while (self.data[self.pos].isdigit()):
@@ -340,20 +340,20 @@ class InterrogateDatabase:
 
 
 def printTree(tree, indent):
 def printTree(tree, indent):
     spacing = "                                                        "[:indent]
     spacing = "                                                        "[:indent]
-    if isinstance(tree, types.TupleType) and isinstance(tree[0], types.IntType):
+    if isinstance(tree, tuple) and isinstance(tree[0], int):
         if tree[0] in symbol.sym_name:
         if tree[0] in symbol.sym_name:
             for i in range(len(tree)):
             for i in range(len(tree)):
                 if (i==0):
                 if (i==0):
-                    print spacing + "(symbol." + symbol.sym_name[tree[0]] + ","
+                    print(spacing + "(symbol." + symbol.sym_name[tree[0]] + ",")
                 else:
                 else:
                     printTree(tree[i], indent+1)
                     printTree(tree[i], indent+1)
-            print spacing + "),"
+            print(spacing + "),")
         elif tree[0] in token.tok_name:
         elif tree[0] in token.tok_name:
-            print spacing + "(token." + token.tok_name[tree[0]] + ", '" + tree[1] + "'),"
+            print(spacing + "(token." + token.tok_name[tree[0]] + ", '" + tree[1] + "'),")
         else:
         else:
-            print spacing + str(tree)
+            print(spacing + str(tree))
     else:
     else:
-        print spacing + str(tree)
+        print(spacing + str(tree))
 
 
 
 
 COMPOUND_STMT_PATTERN = (
 COMPOUND_STMT_PATTERN = (
@@ -447,7 +447,7 @@ class ParseTreeInfo:
         self.function_info = {}
         self.function_info = {}
         self.assign_info = {}
         self.assign_info = {}
         self.derivs = {}
         self.derivs = {}
-        if isinstance(tree, types.StringType):
+        if isinstance(tree, str):
             try:
             try:
                 tree = parser.suite(tree+"\n").totuple()
                 tree = parser.suite(tree+"\n").totuple()
                 if (tree):
                 if (tree):
@@ -455,8 +455,8 @@ class ParseTreeInfo:
                     if found:
                     if found:
                         self.docstring = vars["docstring"]
                         self.docstring = vars["docstring"]
             except:
             except:
-                print "CAUTION --- Parse failed: "+name
-        if isinstance(tree, types.TupleType):
+                print("CAUTION --- Parse failed: " + name)
+        if isinstance(tree, tuple):
             self.extract_info(tree)
             self.extract_info(tree)
 
 
     def match(self, pattern, data, vars=None):
     def match(self, pattern, data, vars=None):
@@ -480,10 +480,10 @@ class ParseTreeInfo:
         """
         """
         if vars is None:
         if vars is None:
             vars = {}
             vars = {}
-        if type(pattern) is types.ListType:       # 'variables' are ['varname']
+        if type(pattern) is list:       # 'variables' are ['varname']
             vars[pattern[0]] = data
             vars[pattern[0]] = data
             return 1, vars
             return 1, vars
-        if type(pattern) is not types.TupleType:
+        if type(pattern) is not tuple:
             return (pattern == data), vars
             return (pattern == data), vars
         if len(data) != len(pattern):
         if len(data) != len(pattern):
             return 0, vars
             return 0, vars
@@ -534,7 +534,7 @@ class ParseTreeInfo:
                     classinfo.derivs[vars["classname"]] = 1
                     classinfo.derivs[vars["classname"]] = 1
 
 
     def extract_tokens(self, str, tree):
     def extract_tokens(self, str, tree):
-        if (isinstance(tree, types.TupleType)):
+        if (isinstance(tree, tuple)):
             if tree[0] in token.tok_name:
             if tree[0] in token.tok_name:
                 str = str + tree[1]
                 str = str + tree[1]
                 if (tree[1]==","): str=str+" "
                 if (tree[1]==","): str=str+" "
@@ -564,7 +564,7 @@ class CodeDatabase:
         self.varExports = {}
         self.varExports = {}
         self.globalfn = []
         self.globalfn = []
         self.formattedprotos = {}
         self.formattedprotos = {}
-        print "Reading C++ source files"
+        print("Reading C++ source files")
         for cxx in cxxlist:
         for cxx in cxxlist:
             tokzr = InterrogateTokenizer(cxx)
             tokzr = InterrogateTokenizer(cxx)
             idb = InterrogateDatabase(tokzr)
             idb = InterrogateDatabase(tokzr)
@@ -583,7 +583,7 @@ class CodeDatabase:
                     self.funcExports.setdefault("pandac.PandaModules", []).append(func.pyname)
                     self.funcExports.setdefault("pandac.PandaModules", []).append(func.pyname)
                 else:
                 else:
                     self.funcs[type.scopedname+"."+func.pyname] = func
                     self.funcs[type.scopedname+"."+func.pyname] = func
-        print "Reading Python sources files"
+        print("Reading Python sources files")
         for py in pylist:
         for py in pylist:
             pyinf = ParseTreeInfo(readFile(py), py, py)
             pyinf = ParseTreeInfo(readFile(py), py, py)
             mod = pathToModule(py)
             mod = pathToModule(py)
@@ -602,7 +602,7 @@ class CodeDatabase:
                 self.varExports.setdefault(mod, []).append(var)
                 self.varExports.setdefault(mod, []).append(var)
 
 
     def getClassList(self):
     def getClassList(self):
-        return self.goodtypes.keys()
+        return list(self.goodtypes.keys())
 
 
     def getGlobalFunctionList(self):
     def getGlobalFunctionList(self):
         return self.globalfn
         return self.globalfn
@@ -625,7 +625,7 @@ class CodeDatabase:
                 parents.append(basetype.scopedname)
                 parents.append(basetype.scopedname)
             return parents
             return parents
         elif (isinstance(type, ParseTreeInfo)):
         elif (isinstance(type, ParseTreeInfo)):
-            return type.derivs.keys()
+            return list(type.derivs.keys())
         else:
         else:
             return []
             return []
 
 
@@ -767,7 +767,7 @@ CLASS_RENAME_DICT = {
 ########################################################################
 ########################################################################
 
 
 def makeCodeDatabase(indirlist, directdirlist):
 def makeCodeDatabase(indirlist, directdirlist):
-    if isinstance(directdirlist, types.StringTypes):
+    if isinstance(directdirlist, str):
         directdirlist = [directdirlist]
         directdirlist = [directdirlist]
     ignore = {}
     ignore = {}
     ignore["__init__.py"] = 1
     ignore["__init__.py"] = 1
@@ -820,7 +820,7 @@ def generate(pversion, indirlist, directdirlist, docdir, header, footer, urlpref
     classes = code.getClassList()[:]
     classes = code.getClassList()[:]
     classes.sort(None, str.lower)
     classes.sort(None, str.lower)
     xclasses = classes[:]
     xclasses = classes[:]
-    print "Generating HTML pages"
+    print("Generating HTML pages")
     for type in classes:
     for type in classes:
         body = "<h1>" + type + "</h1>\n"
         body = "<h1>" + type + "</h1>\n"
         comment = code.getClassComment(type)
         comment = code.getClassComment(type)
@@ -900,14 +900,14 @@ def generate(pversion, indirlist, directdirlist, docdir, header, footer, urlpref
 
 
     index = "<h1>List of Methods - Panda " + pversion + "</h1>\n"
     index = "<h1>List of Methods - Panda " + pversion + "</h1>\n"
 
 
-    prefixes = table.keys()
+    prefixes = list(table.keys())
     prefixes.sort(None, str.lower)
     prefixes.sort(None, str.lower)
     for prefix in prefixes:
     for prefix in prefixes:
         index = index + linkTo("#"+prefix, prefix) + " "
         index = index + linkTo("#"+prefix, prefix) + " "
     index = index + "<br><br>"
     index = index + "<br><br>"
     for prefix in prefixes:
     for prefix in prefixes:
         index = index + '<a name="' + prefix + '">' + "\n"
         index = index + '<a name="' + prefix + '">' + "\n"
-        names = table[prefix].keys()
+        names = list(table[prefix].keys())
         names.sort(None, str.lower)
         names.sort(None, str.lower)
         for name in names:
         for name in names:
             line = '<b>' + name + ":</b><ul>\n"
             line = '<b>' + name + ":</b><ul>\n"
@@ -968,9 +968,9 @@ def expandImports(indirlist, directdirlist, fixdirlist):
                 varExports = code.getVarExports(module)
                 varExports = code.getVarExports(module)
                 if (len(typeExports)+len(funcExports)+len(varExports)==0):
                 if (len(typeExports)+len(funcExports)+len(varExports)==0):
                     result.append(line)
                     result.append(line)
-                    print fixfile+" : "+module+" : no exports"
+                    print(fixfile + " : " + module + " : no exports")
                 else:
                 else:
-                    print fixfile+" : "+module+" : repairing"
+                    print(fixfile + " : " + module + " : repairing")
                     for x in funcExports:
                     for x in funcExports:
                         fn = code.getFunctionName(x)
                         fn = code.getFunctionName(x)
                         if fn in used:
                         if fn in used:

+ 28 - 28
direct/src/directscripts/packpanda.py

@@ -13,7 +13,7 @@
 #
 #
 ##############################################################################
 ##############################################################################
 
 
-import sys, os, getopt, string, shutil, py_compile, subprocess
+import sys, os, getopt, shutil, py_compile, subprocess
 
 
 OPTIONLIST = [
 OPTIONLIST = [
 ("dir",       1, "Name of directory containing game"),
 ("dir",       1, "Name of directory containing game"),
@@ -27,14 +27,14 @@ OPTIONLIST = [
 ]
 ]
 
 
 def ParseFailure():
 def ParseFailure():
-  print ""
-  print "packpanda usage:"
-  print ""
+  print("")
+  print("packpanda usage:")
+  print("")
   for (opt, hasval, explanation) in OPTIONLIST:
   for (opt, hasval, explanation) in OPTIONLIST:
     if (hasval):
     if (hasval):
-      print "  --%-10s    %s"%(opt+" x", explanation)
+      print("  --%-10s    %s"%(opt+" x", explanation))
     else:
     else:
-      print "  --%-10s    %s"%(opt+"  ", explanation)
+      print("  --%-10s    %s"%(opt+"  ", explanation))
   sys.exit(1)
   sys.exit(1)
 
 
 def ParseOptions(args):
 def ParseOptions(args):
@@ -75,7 +75,7 @@ for dir in sys.path:
         PANDA=os.path.abspath(dir)
         PANDA=os.path.abspath(dir)
 if (PANDA is None):
 if (PANDA is None):
   sys.exit("Cannot locate the panda root directory in the python path (cannot locate directory containing direct and pandac).")
   sys.exit("Cannot locate the panda root directory in the python path (cannot locate directory containing direct and pandac).")
-print "PANDA located at "+PANDA
+print("PANDA located at "+PANDA)
 
 
 if (os.path.exists(os.path.join(PANDA,"..","makepanda","makepanda.py"))) and (sys.platform != "win32" or os.path.exists(os.path.join(PANDA,"..","thirdparty","win-nsis","makensis.exe"))):
 if (os.path.exists(os.path.join(PANDA,"..","makepanda","makepanda.py"))) and (sys.platform != "win32" or os.path.exists(os.path.join(PANDA,"..","thirdparty","win-nsis","makensis.exe"))):
   PSOURCE=os.path.abspath(os.path.join(PANDA,".."))
   PSOURCE=os.path.abspath(os.path.join(PANDA,".."))
@@ -95,7 +95,7 @@ else:
 VER=OPTIONS["version"]
 VER=OPTIONS["version"]
 DIR=OPTIONS["dir"]
 DIR=OPTIONS["dir"]
 if (DIR==""):
 if (DIR==""):
-  print "You must specify the --dir option."
+  print("You must specify the --dir option.")
   ParseFailure()
   ParseFailure()
 DIR=os.path.abspath(DIR)
 DIR=os.path.abspath(DIR)
 MYDIR=os.path.abspath(os.getcwd())
 MYDIR=os.path.abspath(os.getcwd())
@@ -123,21 +123,21 @@ else: MAIN="main.py"
 
 
 def PrintFileStatus(label, file):
 def PrintFileStatus(label, file):
   if (os.path.exists(file)):
   if (os.path.exists(file)):
-    print "%-15s: %s"%(label, file)
+    print("%-15s: %s"%(label, file))
   else:
   else:
-    print "%-15s: %s (MISSING)"%(label, file)
+    print("%-15s: %s (MISSING)"%(label, file))
 
 
 PrintFileStatus("Dir", DIR)
 PrintFileStatus("Dir", DIR)
-print "%-15s: %s"%("Name", NAME)
-print "%-15s: %s"%("Start Menu", SMDIRECTORY)
+print("%-15s: %s"%("Name", NAME))
+print("%-15s: %s"%("Start Menu", SMDIRECTORY))
 PrintFileStatus("Main", os.path.join(DIR, MAIN))
 PrintFileStatus("Main", os.path.join(DIR, MAIN))
 if (sys.platform == "win32"):
 if (sys.platform == "win32"):
   PrintFileStatus("Icon", ICON)
   PrintFileStatus("Icon", ICON)
   PrintFileStatus("Bitmap", BITMAP)
   PrintFileStatus("Bitmap", BITMAP)
 PrintFileStatus("License", LICENSE)
 PrintFileStatus("License", LICENSE)
-print "%-15s: %s"%("Output", OUTFILE)
+print("%-15s: %s"%("Output", OUTFILE))
 if (sys.platform == "win32"):
 if (sys.platform == "win32"):
-  print "%-15s: %s"%("Install Dir", INSTALLDIR)
+  print("%-15s: %s"%("Install Dir", INSTALLDIR))
 
 
 if (os.path.isdir(DIR)==0):
 if (os.path.isdir(DIR)==0):
   sys.exit("Difficulty reading "+DIR+". Cannot continue.")
   sys.exit("Difficulty reading "+DIR+". Cannot continue.")
@@ -181,8 +181,8 @@ if (sys.platform == "win32"):
 else:
 else:
   TMPGAME=os.path.join(TMPDIR,"usr","share","games",BASENAME,"game")
   TMPGAME=os.path.join(TMPDIR,"usr","share","games",BASENAME,"game")
   TMPETC=os.path.join(TMPDIR,"usr","share","games",BASENAME,"etc")
   TMPETC=os.path.join(TMPDIR,"usr","share","games",BASENAME,"etc")
-print ""
-print "Copying the game to "+TMPDIR+"..."
+print("")
+print("Copying the game to "+TMPDIR+"...")
 if (os.path.exists(TMPDIR)):
 if (os.path.exists(TMPDIR)):
     try: shutil.rmtree(TMPDIR)
     try: shutil.rmtree(TMPDIR)
     except: sys.exit("Cannot delete "+TMPDIR)
     except: sys.exit("Cannot delete "+TMPDIR)
@@ -247,7 +247,7 @@ def egg2bam(file,bam):
     present = os.path.exists(bam)
     present = os.path.exists(bam)
     if (present): bam = "packpanda-TMP.bam";
     if (present): bam = "packpanda-TMP.bam";
     cmd = 'egg2bam -noabs -ps rel -pd . "'+file+'" -o "'+bam+'"'
     cmd = 'egg2bam -noabs -ps rel -pd . "'+file+'" -o "'+bam+'"'
-    print "Executing: "+cmd
+    print("Executing: "+cmd)
     if (sys.platform == "win32"):
     if (sys.platform == "win32"):
       res = os.spawnl(os.P_WAIT, EGG2BAM, cmd)
       res = os.spawnl(os.P_WAIT, EGG2BAM, cmd)
     else:
     else:
@@ -257,7 +257,7 @@ def egg2bam(file,bam):
         os.unlink(bam)
         os.unlink(bam)
 
 
 def py2pyc(file):
 def py2pyc(file):
-    print "Compiling python "+file
+    print("Compiling python "+file)
     pyc = file[:-3]+'.pyc'
     pyc = file[:-3]+'.pyc'
     pyo = file[:-3]+'.pyo'
     pyo = file[:-3]+'.pyo'
     if (os.path.exists(pyc)): os.unlink(pyc)
     if (os.path.exists(pyc)): os.unlink(pyc)
@@ -284,24 +284,24 @@ def CompileFiles(file):
             CompileFiles(os.path.join(file, x))
             CompileFiles(os.path.join(file, x))
 
 
 def DeleteFiles(file):
 def DeleteFiles(file):
-    base = string.lower(os.path.basename(file))
+    base = os.path.basename(file).lower()
     if (os.path.isdir(file)):
     if (os.path.isdir(file)):
         for pattern in OPTIONS["rmdir"]:
         for pattern in OPTIONS["rmdir"]:
-            if (string.lower(pattern) == base):
-                print "Deleting "+file
+            if pattern.lower() == base:
+                print("Deleting "+file)
                 shutil.rmtree(file)
                 shutil.rmtree(file)
                 return
                 return
         for x in os.listdir(file):
         for x in os.listdir(file):
             DeleteFiles(os.path.join(file, x))
             DeleteFiles(os.path.join(file, x))
     else:
     else:
         for ext in OPTIONS["rmext"]:
         for ext in OPTIONS["rmext"]:
-            if (base[-(len(ext)+1):] == string.lower("."+ext)):
-                print "Deleting "+file
+            if base[-(len(ext) + 1):] == ("." + ext).lower():
+                print("Deleting "+file)
                 os.unlink(file)
                 os.unlink(file)
                 return
                 return
 
 
-print ""
-print "Compiling BAM and PYC files..."
+print("")
+print("Compiling BAM and PYC files...")
 os.chdir(TMPGAME)
 os.chdir(TMPGAME)
 CompileFiles(".")
 CompileFiles(".")
 DeleteFiles(".")
 DeleteFiles(".")
@@ -371,9 +371,9 @@ if (sys.platform == "win32"):
     CMD=CMD+'/DPPICON="'+PPICON+'" '
     CMD=CMD+'/DPPICON="'+PPICON+'" '
     CMD=CMD+'"'+PSOURCE+'\\direct\\directscripts\\packpanda.nsi"'
     CMD=CMD+'"'+PSOURCE+'\\direct\\directscripts\\packpanda.nsi"'
 
 
-    print ""
-    print CMD
-    print "packing..."
+    print("")
+    print(CMD)
+    print("packing...")
     subprocess.call(CMD)
     subprocess.call(CMD)
 else:
 else:
     os.chdir(MYDIR)
     os.chdir(MYDIR)

+ 6 - 6
direct/src/directtools/DirectCameraControl.py

@@ -1,8 +1,8 @@
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
-from DirectUtil import *
-from DirectGeometry import *
-from DirectGlobals import *
-from DirectSelection import SelectionRay
+from .DirectUtil import *
+from .DirectGeometry import *
+from .DirectGlobals import *
+from .DirectSelection import SelectionRay
 from direct.interval.IntervalGlobal import Sequence, Func
 from direct.interval.IntervalGlobal import Sequence, Func
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
 from direct.task import Task
 from direct.task import Task
@@ -233,13 +233,13 @@ class DirectCameraControl(DirectObject):
         self.updateCoaMarkerSize()
         self.updateCoaMarkerSize()
 
 
     def mouseFlyStartTopWin(self):
     def mouseFlyStartTopWin(self):
-        print "Moving mouse 2 in new window"
+        print("Moving mouse 2 in new window")
         #altIsDown = base.getAlt()
         #altIsDown = base.getAlt()
         #if altIsDown:
         #if altIsDown:
         #    print "Alt is down"
         #    print "Alt is down"
 
 
     def mouseFlyStopTopWin(self):
     def mouseFlyStopTopWin(self):
-        print "Stopping mouse 2 in new window"
+        print("Stopping mouse 2 in new window")
 
 
     def spawnXZTranslateOrHPanYZoom(self):
     def spawnXZTranslateOrHPanYZoom(self):
         # Kill any existing tasks
         # Kill any existing tasks

+ 9 - 9
direct/src/directtools/DirectGeometry.py

@@ -1,7 +1,7 @@
 
 
 from panda3d.core import *
 from panda3d.core import *
-from DirectGlobals import *
-from DirectUtil import *
+from .DirectGlobals import *
+from .DirectUtil import *
 import math
 import math
 
 
 class LineNodePath(NodePath):
 class LineNodePath(NodePath):
@@ -28,10 +28,10 @@ class LineNodePath(NodePath):
         ls.setColor(colorVec)
         ls.setColor(colorVec)
 
 
     def moveTo(self, *_args):
     def moveTo(self, *_args):
-        apply(self.lineSegs.moveTo, _args)
+        self.lineSegs.moveTo(*_args)
 
 
     def drawTo(self, *_args):
     def drawTo(self, *_args):
-        apply(self.lineSegs.drawTo, _args)
+        self.lineSegs.drawTo(*_args)
 
 
     def create(self, frameAccurate = 0):
     def create(self, frameAccurate = 0):
         self.lineSegs.create(self.lineNode, frameAccurate)
         self.lineSegs.create(self.lineNode, frameAccurate)
@@ -47,13 +47,13 @@ class LineNodePath(NodePath):
         self.lineSegs.setThickness(thickness)
         self.lineSegs.setThickness(thickness)
 
 
     def setColor(self, *_args):
     def setColor(self, *_args):
-        apply(self.lineSegs.setColor, _args)
+        self.lineSegs.setColor(*_args)
 
 
     def setVertex(self, *_args):
     def setVertex(self, *_args):
-        apply(self.lineSegs.setVertex, _args)
+        self.lineSegs.setVertex(*_args)
 
 
     def setVertexColor(self, vertex, *_args):
     def setVertexColor(self, vertex, *_args):
-        apply(self.lineSegs.setVertexColor, (vertex,) + _args)
+        self.lineSegs.setVertexColor(*(vertex,) + _args)
 
 
     def getCurrentPosition(self):
     def getCurrentPosition(self):
         return self.lineSegs.getCurrentPosition()
         return self.lineSegs.getCurrentPosition()
@@ -119,9 +119,9 @@ class LineNodePath(NodePath):
         Given a list of lists of points, draw a separate line for each list
         Given a list of lists of points, draw a separate line for each list
         """
         """
         for pointList in lineList:
         for pointList in lineList:
-            apply(self.moveTo, pointList[0])
+            self.moveTo(*pointList[0])
             for point in pointList[1:]:
             for point in pointList[1:]:
-                apply(self.drawTo, point)
+                self.drawTo(*point)
 
 
 ##
 ##
 ## Given a point in space, and a direction, find the point of intersection
 ## Given a point in space, and a direction, find the point of intersection

+ 2 - 2
direct/src/directtools/DirectGlobals.py

@@ -51,12 +51,12 @@ LE_CAM_MASKS = {'persp':LE_PERSP_CAM_MASK,
                  'top':LE_TOP_CAM_MASK}
                  'top':LE_TOP_CAM_MASK}
 
 
 def LE_showInAllCam(nodePath):
 def LE_showInAllCam(nodePath):
-    for camName in LE_CAM_MASKS.keys():
+    for camName in LE_CAM_MASKS:
         nodePath.show(LE_CAM_MASKS[camName])
         nodePath.show(LE_CAM_MASKS[camName])
 
 
 def LE_showInOneCam(nodePath, thisCamName):
 def LE_showInOneCam(nodePath, thisCamName):
     LE_showInAllCam(nodePath)
     LE_showInAllCam(nodePath)
-    for camName in LE_CAM_MASKS.keys():
+    for camName in LE_CAM_MASKS:
         if camName != thisCamName:
         if camName != thisCamName:
             nodePath.hide(LE_CAM_MASKS[camName])
             nodePath.hide(LE_CAM_MASKS[camName])
 
 

+ 2 - 2
direct/src/directtools/DirectGrid.py

@@ -1,8 +1,8 @@
 
 
 from panda3d.core import *
 from panda3d.core import *
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
-from DirectUtil import *
-from DirectGeometry import *
+from .DirectUtil import *
+from .DirectGeometry import *
 
 
 class DirectGrid(NodePath, DirectObject):
 class DirectGrid(NodePath, DirectObject):
     def __init__(self,gridSize=100.0,gridSpacing=5.0,planeColor=(0.5,0.5,0.5,0.5),parent = None):
     def __init__(self,gridSize=100.0,gridSpacing=5.0,planeColor=(0.5,0.5,0.5,0.5),parent = None):

+ 1 - 1
direct/src/directtools/DirectLights.py

@@ -78,7 +78,7 @@ class DirectLights(NodePath):
             light.setColor(VBase4(1))
             light.setColor(VBase4(1))
             light.setLens(PerspectiveLens())
             light.setLens(PerspectiveLens())
         else:
         else:
-            print 'Invalid light type'
+            print('Invalid light type')
             return None
             return None
         # Add the new light
         # Add the new light
         directLight = DirectLight(light, self)
         directLight = DirectLight(light, self)

+ 6 - 7
direct/src/directtools/DirectManipulation.py

@@ -1,10 +1,9 @@
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
-from DirectGlobals import *
-from DirectUtil import *
-from DirectGeometry import *
-from DirectSelection import SelectionRay
+from .DirectGlobals import *
+from .DirectUtil import *
+from .DirectGeometry import *
+from .DirectSelection import SelectionRay
 from direct.task import Task
 from direct.task import Task
-import types
 from copy import deepcopy
 from copy import deepcopy
 
 
 class DirectManipulationControl(DirectObject):
 class DirectManipulationControl(DirectObject):
@@ -1207,7 +1206,7 @@ class ObjectHandles(NodePath, DirectObject):
         self.reparentTo(hidden)
         self.reparentTo(hidden)
 
 
     def enableHandles(self, handles):
     def enableHandles(self, handles):
-        if type(handles) == types.ListType:
+        if type(handles) == list:
             for handle in handles:
             for handle in handles:
                 self.enableHandle(handle)
                 self.enableHandle(handle)
         elif handles == 'x':
         elif handles == 'x':
@@ -1256,7 +1255,7 @@ class ObjectHandles(NodePath, DirectObject):
             self.zScaleGroup.reparentTo(self.zHandles)
             self.zScaleGroup.reparentTo(self.zHandles)
 
 
     def disableHandles(self, handles):
     def disableHandles(self, handles):
-        if type(handles) == types.ListType:
+        if type(handles) == list:
             for handle in handles:
             for handle in handles:
                 self.disableHandle(handle)
                 self.disableHandle(handle)
         elif handles == 'x':
         elif handles == 'x':

+ 6 - 6
direct/src/directtools/DirectSelection.py

@@ -1,7 +1,7 @@
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
-from DirectGlobals import *
-from DirectUtil import *
-from DirectGeometry import *
+from .DirectGlobals import *
+from .DirectUtil import *
+from .DirectGeometry import *
 
 
 COA_ORIGIN = 0
 COA_ORIGIN = 0
 COA_CENTER = 1
 COA_CENTER = 1
@@ -68,7 +68,7 @@ class SelectedNodePaths(DirectObject):
         """ Select the specified node path.  Multiselect as required """
         """ Select the specified node path.  Multiselect as required """
         # Do nothing if nothing selected
         # Do nothing if nothing selected
         if not nodePath:
         if not nodePath:
-            print 'Nothing selected!!'
+            print('Nothing selected!!')
             return None
             return None
 
 
         # Reset selected objects and highlight if multiSelect is false
         # Reset selected objects and highlight if multiSelect is false
@@ -160,7 +160,7 @@ class SelectedNodePaths(DirectObject):
             return None
             return None
 
 
     def getDeselectedAsList(self):
     def getDeselectedAsList(self):
-        return self.deselectedDict.values()[:]
+        return list(self.deselectedDict.values())
 
 
     def getDeselectedDict(self, id):
     def getDeselectedDict(self, id):
         """
         """
@@ -260,7 +260,7 @@ class SelectedNodePaths(DirectObject):
         return self.getDeselectedDict(id)
         return self.getDeselectedDict(id)
 
 
     def getNumSelected(self):
     def getNumSelected(self):
-        return len(self.selectedDict.keys())
+        return len(self.selectedDict)
 
 
 
 
 class DirectBoundingBox:
 class DirectBoundingBox:

+ 17 - 16
direct/src/directtools/DirectSession.py

@@ -1,27 +1,25 @@
 import math
 import math
-import types
-import string
+import sys
 
 
 from panda3d.core import *
 from panda3d.core import *
-from DirectUtil import *
+from .DirectUtil import *
 
 
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
 from direct.task import Task
 from direct.task import Task
 
 
-from DirectGlobals import DIRECT_NO_MOD
-from DirectCameraControl import DirectCameraControl
-from DirectManipulation import DirectManipulationControl
-from DirectSelection import SelectionRay, COA_ORIGIN, SelectedNodePaths
-from DirectGrid import DirectGrid
+from .DirectGlobals import DIRECT_NO_MOD
+from .DirectCameraControl import DirectCameraControl
+from .DirectManipulation import DirectManipulationControl
+from .DirectSelection import SelectionRay, COA_ORIGIN, SelectedNodePaths
+from .DirectGrid import DirectGrid
 #from DirectGeometry import *
 #from DirectGeometry import *
-from DirectLights import DirectLights
+from .DirectLights import DirectLights
 from direct.cluster.ClusterClient import createClusterClient, DummyClusterClient
 from direct.cluster.ClusterClient import createClusterClient, DummyClusterClient
 from direct.cluster.ClusterServer import ClusterServer
 from direct.cluster.ClusterServer import ClusterServer
 ## from direct.tkpanels import Placer
 ## from direct.tkpanels import Placer
 ## from direct.tkwidgets import Slider
 ## from direct.tkwidgets import Slider
 ## from direct.tkwidgets import SceneGraphExplorer
 ## from direct.tkwidgets import SceneGraphExplorer
 from direct.gui import OnscreenText
 from direct.gui import OnscreenText
-from direct.showbase import Loader
 from direct.interval.IntervalGlobal import *
 from direct.interval.IntervalGlobal import *
 
 
 class DirectSession(DirectObject):
 class DirectSession(DirectObject):
@@ -115,7 +113,7 @@ class DirectSession(DirectObject):
             if fastrak:
             if fastrak:
                 from direct.directdevices import DirectFastrak
                 from direct.directdevices import DirectFastrak
                 # parse string into format device:N where N is the sensor name
                 # parse string into format device:N where N is the sensor name
-                fastrak = string.split(fastrak)
+                fastrak = fastrak.split()
                 for i in range(len(fastrak))[1:]:
                 for i in range(len(fastrak))[1:]:
                     self.fastrak.append(DirectFastrak.DirectFastrak(fastrak[0] + ':' + fastrak[i]))
                     self.fastrak.append(DirectFastrak.DirectFastrak(fastrak[0] + ':' + fastrak[i]))
 
 
@@ -556,12 +554,12 @@ class DirectSession(DirectObject):
                     input = input[:-7]
                     input = input[:-7]
 
 
         # Deal with keyboard and mouse input
         # Deal with keyboard and mouse input
-        if input in self.hotKeyMap.keys():
+        if input in self.hotKeyMap:
             keyDesc = self.hotKeyMap[input]
             keyDesc = self.hotKeyMap[input]
             messenger.send(keyDesc[1])
             messenger.send(keyDesc[1])
-        elif input in self.speicalKeyMap.keys():
+        elif input in self.speicalKeyMap:
             messenger.send(self.speicalKeyMap[input])
             messenger.send(self.speicalKeyMap[input])
-        elif input in self.directOnlyKeyMap.keys():
+        elif input in self.directOnlyKeyMap:
             if self.fIgnoreDirectOnlyKeyMap:
             if self.fIgnoreDirectOnlyKeyMap:
                 return
                 return
             keyDesc = self.directOnlyKeyMap[input]
             keyDesc = self.directOnlyKeyMap[input]
@@ -808,7 +806,7 @@ class DirectSession(DirectObject):
 
 
     def isNotCycle(self, nodePath, parent):
     def isNotCycle(self, nodePath, parent):
         if nodePath == parent:
         if nodePath == parent:
-            print 'DIRECT.reparent: Invalid parent'
+            print('DIRECT.reparent: Invalid parent')
             return 0
             return 0
         elif parent.hasParent():
         elif parent.hasParent():
             return self.isNotCycle(nodePath, parent.getParent())
             return self.isNotCycle(nodePath, parent.getParent())
@@ -944,7 +942,10 @@ class DirectSession(DirectObject):
 
 
     def getAndSetName(self, nodePath):
     def getAndSetName(self, nodePath):
         """ Prompt user for new node path name """
         """ Prompt user for new node path name """
-        from tkSimpleDialog import askstring
+        if sys.version_info >= (3, 0):
+            from tkinter.simpledialog import askstring
+        else:
+            from tkSimpleDialog import askstring
         newName = askstring('Node Path: ' + nodePath.getName(),
         newName = askstring('Node Path: ' + nodePath.getName(),
                             'Enter new name:')
                             'Enter new name:')
         if newName:
         if newName:

+ 1 - 1
direct/src/directtools/DirectUtil.py

@@ -1,5 +1,5 @@
 
 
-from DirectGlobals import *
+from .DirectGlobals import *
 
 
 # Routines to adjust values
 # Routines to adjust values
 def ROUND_TO(value, divisor):
 def ROUND_TO(value, divisor):

+ 2 - 2
direct/src/directutil/DeltaProfiler.py

@@ -16,11 +16,11 @@ class DeltaProfiler:
     def printDeltaTime(self, label):
     def printDeltaTime(self, label):
         if self.active:
         if self.active:
             deltaTime=time()-self.priorTime
             deltaTime=time()-self.priorTime
-            print "%s DeltaTime %-25s to %-25s: %3.5f"%(
+            print("%s DeltaTime %-25s to %-25s: %3.5f"%(
                 self.name,
                 self.name,
                 self.priorLabel,
                 self.priorLabel,
                 label,
                 label,
-                deltaTime)
+                deltaTime))
             self.priorLabel=label
             self.priorLabel=label
             # The printing time is not included in the timing.
             # The printing time is not included in the timing.
             # This is intentional.
             # This is intentional.

+ 1 - 1
direct/src/directutil/DistributedLargeBlobSender.py

@@ -2,7 +2,7 @@
 
 
 from direct.distributed import DistributedObject
 from direct.distributed import DistributedObject
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
-import LargeBlobSenderConsts
+from . import LargeBlobSenderConsts
 
 
 class DistributedLargeBlobSender(DistributedObject.DistributedObject):
 class DistributedLargeBlobSender(DistributedObject.DistributedObject):
     """DistributedLargeBlobSender: for sending large chunks of data through
     """DistributedLargeBlobSender: for sending large chunks of data through

+ 1 - 1
direct/src/directutil/DistributedLargeBlobSenderAI.py

@@ -2,7 +2,7 @@
 
 
 from direct.distributed import DistributedObjectAI
 from direct.distributed import DistributedObjectAI
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
-import LargeBlobSenderConsts
+from . import LargeBlobSenderConsts
 
 
 class DistributedLargeBlobSenderAI(DistributedObjectAI.DistributedObjectAI):
 class DistributedLargeBlobSenderAI(DistributedObjectAI.DistributedObjectAI):
     """DistributedLargeBlobSenderAI: for sending large chunks of data through
     """DistributedLargeBlobSenderAI: for sending large chunks of data through

+ 1 - 1
direct/src/directutil/MemoryLeakHelpers.py

@@ -11,7 +11,7 @@
 import gc
 import gc
 gc.set_debug(gc.DEBUG_LEAK)
 gc.set_debug(gc.DEBUG_LEAK)
 gc.collect()
 gc.collect()
-print gc.garbage
+print(gc.garbage)
 
 
 # Inside DistributedObjectAI, you can uncomment the __del__ function to
 # Inside DistributedObjectAI, you can uncomment the __del__ function to
 # see when your objects are being deleted (or not)
 # see when your objects are being deleted (or not)

+ 6 - 6
direct/src/directutil/Mopath.py

@@ -29,7 +29,7 @@ class Mopath(DirectObject):
         elif isinstance( objectToLoad, str ):
         elif isinstance( objectToLoad, str ):
             self.loadFile( objectToLoad )
             self.loadFile( objectToLoad )
         elif objectToLoad is not None:
         elif objectToLoad is not None:
-            print "Mopath: Unable to load object '%s', objectToLoad must be a file name string or a NodePath" % objectToLoad
+            print("Mopath: Unable to load object '%s', objectToLoad must be a file name string or a NodePath" % objectToLoad)
 
 
     def getMaxT(self):
     def getMaxT(self):
         return self.maxT * self.timeScale
         return self.maxT * self.timeScale
@@ -40,7 +40,7 @@ class Mopath(DirectObject):
             self.loadNodePath(nodePath)
             self.loadNodePath(nodePath)
             nodePath.removeNode()
             nodePath.removeNode()
         else:
         else:
-            print 'Mopath: no data in file: %s' % filename
+            print('Mopath: no data in file: %s' % filename)
 
 
 
 
     def loadNodePath(self, nodePath, fReset = 1):
     def loadNodePath(self, nodePath, fReset = 1):
@@ -55,7 +55,7 @@ class Mopath(DirectObject):
         elif (self.hprNurbsCurve != None):
         elif (self.hprNurbsCurve != None):
             self.maxT = self.hprNurbsCurve.getMaxT()
             self.maxT = self.hprNurbsCurve.getMaxT()
         else:
         else:
-            print 'Mopath: no valid curves in nodePath: %s' % nodePath
+            print('Mopath: no valid curves in nodePath: %s' % nodePath)
 
 
 
 
     def reset(self):
     def reset(self):
@@ -77,7 +77,7 @@ class Mopath(DirectObject):
                 if (self.xyzNurbsCurve == None):
                 if (self.xyzNurbsCurve == None):
                     self.xyzNurbsCurve = node
                     self.xyzNurbsCurve = node
                 else:
                 else:
-                    print 'Mopath: got a PCT_NONE curve and an XYZ Curve in nodePath: %s' % nodePath
+                    print('Mopath: got a PCT_NONE curve and an XYZ Curve in nodePath: %s' % nodePath)
             elif (node.getCurveType() == PCTT):
             elif (node.getCurveType() == PCTT):
                 self.tNurbsCurve.append(node)
                 self.tNurbsCurve.append(node)
         else:
         else:
@@ -106,7 +106,7 @@ class Mopath(DirectObject):
 
 
     def goTo(self, node, time):
     def goTo(self, node, time):
         if (self.xyzNurbsCurve == None) and (self.hprNurbsCurve == None):
         if (self.xyzNurbsCurve == None) and (self.hprNurbsCurve == None):
-            print 'Mopath: Mopath has no curves'
+            print('Mopath: Mopath has no curves')
             return
             return
         time /= self.timeScale
         time /= self.timeScale
         self.playbackTime = self.calcTime(CLAMP(time, 0.0, self.maxT))
         self.playbackTime = self.calcTime(CLAMP(time, 0.0, self.maxT))
@@ -145,7 +145,7 @@ class Mopath(DirectObject):
 
 
     def play(self, node, time = 0.0, loop = 0):
     def play(self, node, time = 0.0, loop = 0):
         if (self.xyzNurbsCurve == None) and (self.hprNurbsCurve == None):
         if (self.xyzNurbsCurve == None) and (self.hprNurbsCurve == None):
-            print 'Mopath: Mopath has no curves'
+            print('Mopath: Mopath has no curves')
             return
             return
         self.node = node
         self.node = node
         self.loop = loop
         self.loop = loop

+ 3 - 3
direct/src/directutil/Verify.py

@@ -52,11 +52,11 @@ def verify(assertion):
     wish to have the assertion checked, even in release (-O) code.
     wish to have the assertion checked, even in release (-O) code.
     """
     """
     if not assertion:
     if not assertion:
-        print "\n\nverify failed:"
+        print("\n\nverify failed:")
         import sys
         import sys
-        print "    File \"%s\", line %d"%(
+        print("    File \"%s\", line %d"%(
                 sys._getframe(1).f_code.co_filename,
                 sys._getframe(1).f_code.co_filename,
-                sys._getframe(1).f_lineno)
+                sys._getframe(1).f_lineno))
         if wantVerifyPdb:
         if wantVerifyPdb:
             import pdb
             import pdb
             pdb.set_trace()
             pdb.set_trace()

+ 4 - 4
direct/src/distributed/AsyncRequest.py

@@ -1,7 +1,7 @@
 #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
-from ConnectionRepository import *
+from .ConnectionRepository import *
 from panda3d.core import ConfigVariableDouble, ConfigVariableInt, ConfigVariableBool
 from panda3d.core import ConfigVariableDouble, ConfigVariableInt, ConfigVariableBool
 
 
 ASYNC_REQUEST_DEFAULT_TIMEOUT_IN_SECONDS = 8.0
 ASYNC_REQUEST_DEFAULT_TIMEOUT_IN_SECONDS = 8.0
@@ -251,9 +251,9 @@ class AsyncRequest(DirectObject):
             if __debug__:
             if __debug__:
                 if _breakOnTimeout:
                 if _breakOnTimeout:
                     if hasattr(self, "avatarId"):
                     if hasattr(self, "avatarId"):
-                        print "\n\nself.avatarId =", self.avatarId
-                    print "\nself.neededObjects =", self.neededObjects
-                    print "\ntimed out after %s seconds.\n\n"%(task.delayTime,)
+                        print("\n\nself.avatarId =", self.avatarId)
+                    print("\nself.neededObjects =", self.neededObjects)
+                    print("\ntimed out after %s seconds.\n\n"%(task.delayTime,))
                     import pdb; pdb.set_trace()
                     import pdb; pdb.set_trace()
             self.delete()
             self.delete()
             return Task.done
             return Task.done

+ 1 - 1
direct/src/distributed/CRCache.py

@@ -1,7 +1,7 @@
 """CRCache module: contains the CRCache class"""
 """CRCache module: contains the CRCache class"""
 
 
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
-import DistributedObject
+from . import DistributedObject
 
 
 class CRCache:
 class CRCache:
     notify = DirectNotifyGlobal.directNotify.newCategory("CRCache")
     notify = DirectNotifyGlobal.directNotify.newCategory("CRCache")

+ 2 - 2
direct/src/distributed/CRDataCache.py

@@ -23,7 +23,7 @@ class CRDataCache:
             # cache is full, throw out a random doId's data
             # cache is full, throw out a random doId's data
             if self._junkIndex >= len(self._doId2name2data):
             if self._junkIndex >= len(self._doId2name2data):
                 self._junkIndex = 0
                 self._junkIndex = 0
-            junkDoId = self._doId2name2data.keys()[self._junkIndex]
+            junkDoId = list(self._doId2name2data.keys())[self._junkIndex]
             self._junkIndex += 1
             self._junkIndex += 1
             for name in self._doId2name2data[junkDoId]:
             for name in self._doId2name2data[junkDoId]:
                 self._doId2name2data[junkDoId][name].flush()
                 self._doId2name2data[junkDoId][name].flush()
@@ -96,7 +96,7 @@ if __debug__:
     assert 'testCachedData2' in data
     assert 'testCachedData2' in data
     assert data['testCachedData'].foo == 34
     assert data['testCachedData'].foo == 34
     assert data['testCachedData2'].bar == 45
     assert data['testCachedData2'].bar == 45
-    for cd in data.itervalues():
+    for cd in data.values():
         cd.flush()
         cd.flush()
     del data
     del data
     dc._checkMemLeaks()
     dc._checkMemLeaks()

+ 6 - 6
direct/src/distributed/ClientRepository.py

@@ -1,12 +1,12 @@
 """ClientRepository module: contains the ClientRepository class"""
 """ClientRepository module: contains the ClientRepository class"""
 
 
-from ClientRepositoryBase import ClientRepositoryBase
+from .ClientRepositoryBase import ClientRepositoryBase
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
-from MsgTypesCMU import *
-from PyDatagram import PyDatagram
-from PyDatagramIterator import PyDatagramIterator
+from .MsgTypesCMU import *
+from .PyDatagram import PyDatagram
+from .PyDatagramIterator import PyDatagramIterator
 from panda3d.core import UniqueIdAllocator
 from panda3d.core import UniqueIdAllocator
-import types
+
 
 
 class ClientRepository(ClientRepositoryBase):
 class ClientRepository(ClientRepositoryBase):
     """
     """
@@ -305,7 +305,7 @@ class ClientRepository(ClientRepositoryBase):
 
 
     def handleDatagram(self, di):
     def handleDatagram(self, di):
         if self.notify.getDebug():
         if self.notify.getDebug():
-            print "ClientRepository received datagram:"
+            print("ClientRepository received datagram:")
             di.getDatagram().dumpHex(ostream)
             di.getDatagram().dumpHex(ostream)
 
 
         msgType = self.getMsgType()
         msgType = self.getMsgType()

+ 13 - 15
direct/src/distributed/ClientRepositoryBase.py

@@ -1,18 +1,16 @@
 from pandac.PandaModules import *
 from pandac.PandaModules import *
-from MsgTypes import *
+from .MsgTypes import *
 from direct.task import Task
 from direct.task import Task
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
-import CRCache
+from . import CRCache
 from direct.distributed.CRDataCache import CRDataCache
 from direct.distributed.CRDataCache import CRDataCache
 from direct.distributed.ConnectionRepository import ConnectionRepository
 from direct.distributed.ConnectionRepository import ConnectionRepository
 from direct.showbase import PythonUtil
 from direct.showbase import PythonUtil
-import ParentMgr
-import RelatedObjectMgr
+from . import ParentMgr
+from . import RelatedObjectMgr
 import time
 import time
-from ClockDelta import *
-from PyDatagram import PyDatagram
-from PyDatagramIterator import PyDatagramIterator
-import types
+from .ClockDelta import *
+
 
 
 class ClientRepositoryBase(ConnectionRepository):
 class ClientRepositoryBase(ConnectionRepository):
     """
     """
@@ -190,7 +188,7 @@ class ClientRepositoryBase(ConnectionRepository):
                 for dg, di in updates:
                 for dg, di in updates:
                     # non-DC updates that need to be played back in-order are
                     # non-DC updates that need to be played back in-order are
                     # stored as (msgType, (dg, di))
                     # stored as (msgType, (dg, di))
-                    if type(di) is types.TupleType:
+                    if type(di) is tuple:
                         msgType = dg
                         msgType = dg
                         dg, di = di
                         dg, di = di
                         self.replayDeferredGenerate(msgType, (dg, di))
                         self.replayDeferredGenerate(msgType, (dg, di))
@@ -264,7 +262,7 @@ class ClientRepositoryBase(ConnectionRepository):
             distObj.setLocation(parentId, zoneId)
             distObj.setLocation(parentId, zoneId)
             distObj.updateRequiredFields(dclass, di)
             distObj.updateRequiredFields(dclass, di)
             # updateRequiredFields calls announceGenerate
             # updateRequiredFields calls announceGenerate
-            print "New DO:%s, dclass:%s"%(doId, dclass.getName())
+            print("New DO:%s, dclass:%s"%(doId, dclass.getName()))
         return distObj
         return distObj
 
 
     def generateWithRequiredOtherFields(self, dclass, doId, di,
     def generateWithRequiredOtherFields(self, dclass, doId, di,
@@ -602,8 +600,8 @@ class ClientRepositoryBase(ConnectionRepository):
         del self._delayDeletedDOs[key]
         del self._delayDeletedDOs[key]
 
 
     def printDelayDeletes(self):
     def printDelayDeletes(self):
-        print 'DelayDeletes:'
-        print '============='
-        for obj in self._delayDeletedDOs.itervalues():
-            print '%s\t%s (%s)\tdelayDeletes=%s' % (
-                obj.doId, safeRepr(obj), itype(obj), obj.getDelayDeleteNames())
+        print('DelayDeletes:')
+        print('=============')
+        for obj in self._delayDeletedDOs.values():
+            print('%s\t%s (%s)\tdelayDeletes=%s' % (
+                obj.doId, safeRepr(obj), itype(obj), obj.getDelayDeleteNames()))

+ 3 - 6
direct/src/distributed/ConnectionRepository.py

@@ -4,15 +4,12 @@ from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.distributed.DoInterestManager import DoInterestManager
 from direct.distributed.DoInterestManager import DoInterestManager
 from direct.distributed.DoCollectionManager import DoCollectionManager
 from direct.distributed.DoCollectionManager import DoCollectionManager
 from direct.showbase import GarbageReport
 from direct.showbase import GarbageReport
-from PyDatagram import PyDatagram
-from PyDatagramIterator import PyDatagramIterator
+from .PyDatagramIterator import PyDatagramIterator
 
 
 import types
 import types
-import imp
 import gc
 import gc
 
 
 
 
-
 class ConnectionRepository(
 class ConnectionRepository(
         DoInterestManager, DoCollectionManager, CConnectionRepository):
         DoInterestManager, DoCollectionManager, CConnectionRepository):
     """
     """
@@ -248,7 +245,7 @@ class ConnectionRepository(
         self.dclassesByNumber = {}
         self.dclassesByNumber = {}
         self.hashVal = 0
         self.hashVal = 0
 
 
-        if isinstance(dcFileNames, types.StringTypes):
+        if isinstance(dcFileNames, str):
             # If we were given a single string, make it a list.
             # If we were given a single string, make it a list.
             dcFileNames = [dcFileNames]
             dcFileNames = [dcFileNames]
 
 
@@ -514,7 +511,7 @@ class ConnectionRepository(
             if failureCallback:
             if failureCallback:
                 failureCallback(0, '', *failureArgs)
                 failureCallback(0, '', *failureArgs)
         else:
         else:
-            print "uh oh, we aren't using one of the tri-state CM variables"
+            print("uh oh, we aren't using one of the tri-state CM variables")
             failureCallback(0, '', *failureArgs)
             failureCallback(0, '', *failureArgs)
 
 
     def disconnect(self):
     def disconnect(self):

+ 6 - 6
direct/src/distributed/DistributedCamera.py

@@ -148,8 +148,8 @@ class Fixture(NodePath, FSM):
         # if added to the dc definition of the Fixture struct and
         # if added to the dc definition of the Fixture struct and
         # saved out to the Camera file.
         # saved out to the Camera file.
         lodNodes = render.findAllMatches('**/+LODNode')
         lodNodes = render.findAllMatches('**/+LODNode')
-        for i in xrange(0,lodNodes.getNumPaths()):
-            lodNodes[i].node().forceSwitch(lodNodes[i].node().getHighestSwitch())
+        for lodNode in lodNodes:
+            lodNode.node().forceSwitch(lodNode.node().getHighestSwitch())
 
 
 
 
     def exitUsing(self):
     def exitUsing(self):
@@ -183,13 +183,13 @@ class DistributedCamera(DistributedObject):
 
 
     def __str__(self):
     def __str__(self):
         out = ''
         out = ''
-        for fixture in self.fixtures.itervalues():
+        for fixture in self.fixtures.values():
             out = '%s\n%s' % (out, fixture)
             out = '%s\n%s' % (out, fixture)
         return out[1:]
         return out[1:]
 
 
     def pack(self):
     def pack(self):
         out = ''
         out = ''
-        for fixture in self.fixtures.itervalues():
+        for fixture in self.fixtures.values():
             out = '%s\n%s' % (out, fixture.pack())
             out = '%s\n%s' % (out, fixture.pack())
         return out[1:]
         return out[1:]
 
 
@@ -198,7 +198,7 @@ class DistributedCamera(DistributedObject):
 
 
         self.parent = None
         self.parent = None
 
 
-        for fixture in self.fixtures.itervalues():
+        for fixture in self.fixtures.values():
             fixture.cleanup()
             fixture.cleanup()
             fixture.detachNode()
             fixture.detachNode()
         self.fixtures = {}
         self.fixtures = {}
@@ -215,7 +215,7 @@ class DistributedCamera(DistributedObject):
             else:
             else:
                 self.parent = self.cr.getDo(doId)
                 self.parent = self.cr.getDo(doId)
 
 
-            for fix in self.fixtures.itervalues():
+            for fix in self.fixtures.values():
                 fix.reparentTo(self.parent)
                 fix.reparentTo(self.parent)
 
 
     def getCamParent(self):
     def getCamParent(self):

+ 1 - 1
direct/src/distributed/DistributedCartesianGrid.py

@@ -15,7 +15,7 @@ if __debug__:
     from direct.directtools.DirectGeometry import *
     from direct.directtools.DirectGeometry import *
     from direct.showbase.PythonUtil import randFloat
     from direct.showbase.PythonUtil import randFloat
 
 
-from CartesianGridBase import CartesianGridBase
+from .CartesianGridBase import CartesianGridBase
 
 
 # increase this number if you want to visualize the grid lines
 # increase this number if you want to visualize the grid lines
 # above water level
 # above water level

+ 2 - 2
direct/src/distributed/DistributedCartesianGridAI.py

@@ -2,8 +2,8 @@
 from pandac.PandaModules import *
 from pandac.PandaModules import *
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.task import Task
 from direct.task import Task
-from DistributedNodeAI import DistributedNodeAI
-from CartesianGridBase import CartesianGridBase
+from .DistributedNodeAI import DistributedNodeAI
+from .CartesianGridBase import CartesianGridBase
 
 
 class DistributedCartesianGridAI(DistributedNodeAI, CartesianGridBase):
 class DistributedCartesianGridAI(DistributedNodeAI, CartesianGridBase):
     notify = directNotify.newCategory("DistributedCartesianGridAI")
     notify = directNotify.newCategory("DistributedCartesianGridAI")

+ 5 - 6
direct/src/distributed/DistributedNode.py

@@ -1,10 +1,9 @@
 """DistributedNode module: contains the DistributedNode class"""
 """DistributedNode module: contains the DistributedNode class"""
 
 
 from panda3d.core import NodePath
 from panda3d.core import NodePath
-from direct.task import Task
-import GridParent
-import DistributedObject
-import types
+from . import GridParent
+from . import DistributedObject
+
 
 
 class DistributedNode(DistributedObject.DistributedObject, NodePath):
 class DistributedNode(DistributedObject.DistributedObject, NodePath):
     """Distributed Node class:"""
     """Distributed Node class:"""
@@ -77,7 +76,7 @@ class DistributedNode(DistributedObject.DistributedObject, NodePath):
     ### setParent ###
     ### setParent ###
 
 
     def b_setParent(self, parentToken):
     def b_setParent(self, parentToken):
-        if type(parentToken) == types.StringType:
+        if type(parentToken) == str:
             self.setParentStr(parentToken)
             self.setParentStr(parentToken)
         else:
         else:
             self.setParent(parentToken)
             self.setParent(parentToken)
@@ -85,7 +84,7 @@ class DistributedNode(DistributedObject.DistributedObject, NodePath):
         self.d_setParent(parentToken)
         self.d_setParent(parentToken)
 
 
     def d_setParent(self, parentToken):
     def d_setParent(self, parentToken):
-        if type(parentToken) == types.StringType:
+        if type(parentToken) == str:
             self.sendUpdate("setParentStr", [parentToken])
             self.sendUpdate("setParentStr", [parentToken])
         else:
         else:
             self.sendUpdate("setParent", [parentToken])
             self.sendUpdate("setParent", [parentToken])

+ 4 - 4
direct/src/distributed/DistributedNodeAI.py

@@ -1,7 +1,7 @@
 from pandac.PandaModules import NodePath
 from pandac.PandaModules import NodePath
-import DistributedObjectAI
-import GridParent
-import types
+from . import DistributedObjectAI
+from . import GridParent
+
 
 
 class DistributedNodeAI(DistributedObjectAI.DistributedObjectAI, NodePath):
 class DistributedNodeAI(DistributedObjectAI.DistributedObjectAI, NodePath):
     def __init__(self, air, name=None):
     def __init__(self, air, name=None):
@@ -47,7 +47,7 @@ class DistributedNodeAI(DistributedObjectAI.DistributedObjectAI, NodePath):
     ### setParent ###
     ### setParent ###
 
 
     def b_setParent(self, parentToken):
     def b_setParent(self, parentToken):
-        if type(parentToken) == types.StringType:
+        if type(parentToken) == str:
             self.setParentStr(parentToken)
             self.setParentStr(parentToken)
         else:
         else:
             self.setParent(parentToken)
             self.setParent(parentToken)

+ 2 - 2
direct/src/distributed/DistributedNodeUD.py

@@ -1,5 +1,5 @@
 #from otp.ai.AIBaseGlobal import *
 #from otp.ai.AIBaseGlobal import *
-from DistributedObjectUD import DistributedObjectUD
+from .DistributedObjectUD import DistributedObjectUD
 
 
 class DistributedNodeUD(DistributedObjectUD):
 class DistributedNodeUD(DistributedObjectUD):
     def __init__(self, air, name=None):
     def __init__(self, air, name=None):
@@ -13,7 +13,7 @@ class DistributedNodeUD(DistributedObjectUD):
                 name = self.__class__.__name__
                 name = self.__class__.__name__
 
 
     def b_setParent(self, parentToken):
     def b_setParent(self, parentToken):
-        if type(parentToken) == types.StringType:
+        if type(parentToken) == str:
             self.setParentStr(parentToken)
             self.setParentStr(parentToken)
         else:
         else:
             self.setParent(parentToken)
             self.setParent(parentToken)

+ 18 - 15
direct/src/distributed/DistributedObject.py

@@ -1,6 +1,7 @@
 """DistributedObject module: contains the DistributedObject class"""
 """DistributedObject module: contains the DistributedObject class"""
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.distributed.DistributedObjectBase import DistributedObjectBase
 from direct.distributed.DistributedObjectBase import DistributedObjectBase
 from direct.showbase.PythonUtil import StackTrace
 from direct.showbase.PythonUtil import StackTrace
@@ -80,14 +81,11 @@ class DistributedObject(DistributedObjectBase):
                 and conditionally show generated, disabled, neverDisable,
                 and conditionally show generated, disabled, neverDisable,
                 or cachable"
                 or cachable"
             """
             """
-            spaces=' '*(indent+2)
+            spaces = ' ' * (indent + 2)
             try:
             try:
-                print "%s%s:"%(
-                    ' '*indent, self.__class__.__name__)
-                print "%sfrom DistributedObject doId:%s, parent:%s, zone:%s"%(
-                    spaces,
-                    self.doId, self.parentId, self.zoneId),
-                flags=[]
+                print("%s%s:" % (' ' * indent, self.__class__.__name__))
+
+                flags = []
                 if self.activeState == ESGenerated:
                 if self.activeState == ESGenerated:
                     flags.append("generated")
                     flags.append("generated")
                 if self.activeState < ESGenerating:
                 if self.activeState < ESGenerating:
@@ -96,10 +94,15 @@ class DistributedObject(DistributedObjectBase):
                     flags.append("neverDisable")
                     flags.append("neverDisable")
                 if self.cacheable:
                 if self.cacheable:
                     flags.append("cacheable")
                     flags.append("cacheable")
+
+                flagStr = ""
                 if len(flags):
                 if len(flags):
-                    print "(%s)"%(" ".join(flags),),
-                print
-            except Exception, e: print "%serror printing status"%(spaces,), e
+                    flagStr = " (%s)" % (" ".join(flags))
+
+                print("%sfrom DistributedObject doId:%s, parent:%s, zone:%s%s" % (
+                    spaces, self.doId, self.parentId, self.zoneId, flagStr))
+            except Exception as e:
+                print("%serror printing status %s" % (spaces, e))
 
 
     def getAutoInterests(self):
     def getAutoInterests(self):
         # returns the sub-zones under this object that are automatically
         # returns the sub-zones under this object that are automatically
@@ -123,7 +126,7 @@ class DistributedObject(DistributedObjectBase):
                         p = DCPacker()
                         p = DCPacker()
                         p.setUnpackData(field.getDefaultValue())
                         p.setUnpackData(field.getDefaultValue())
                         len = p.rawUnpackUint16()/4
                         len = p.rawUnpackUint16()/4
-                        for i in xrange(len):
+                        for i in range(len):
                             zone = int(p.rawUnpackUint32())
                             zone = int(p.rawUnpackUint32())
                             autoInterests.add(zone)
                             autoInterests.add(zone)
                     autoInterests.update(autoInterests)
                     autoInterests.update(autoInterests)
@@ -247,7 +250,7 @@ class DistributedObject(DistributedObjectBase):
             # we are going to crash, output the destroyDo stacktrace
             # we are going to crash, output the destroyDo stacktrace
             self.notify.warning('self.cr is none in _deactivateDO %d' % self.doId)
             self.notify.warning('self.cr is none in _deactivateDO %d' % self.doId)
             if hasattr(self, 'destroyDoStackTrace'):
             if hasattr(self, 'destroyDoStackTrace'):
-                print self.destroyDoStackTrace
+                print(self.destroyDoStackTrace)
         self.__callbacks = {}
         self.__callbacks = {}
         self.cr.closeAutoInterests(self)
         self.cr.closeAutoInterests(self)
         self.setLocation(0,0)
         self.setLocation(0,0)
@@ -260,7 +263,7 @@ class DistributedObject(DistributedObjectBase):
         # check for leftover cached data that was not retrieved or flushed by this object
         # check for leftover cached data that was not retrieved or flushed by this object
         # this will catch typos in the data name in calls to get/setCachedData
         # this will catch typos in the data name in calls to get/setCachedData
         if hasattr(self, '_cachedData'):
         if hasattr(self, '_cachedData'):
-            for name, cachedData in self._cachedData.iteritems():
+            for name, cachedData in self._cachedData.items():
                 self.notify.warning('flushing unretrieved cached data: %s' % name)
                 self.notify.warning('flushing unretrieved cached data: %s' % name)
                 cachedData.flush()
                 cachedData.flush()
             del self._cachedData
             del self._cachedData
@@ -398,7 +401,7 @@ class DistributedObject(DistributedObjectBase):
     def getCurrentContexts(self):
     def getCurrentContexts(self):
         # Returns a list of the currently outstanding contexts created
         # Returns a list of the currently outstanding contexts created
         # by getCallbackContext().
         # by getCallbackContext().
-        return self.__callbacks.keys()
+        return list(self.__callbacks.keys())
 
 
     def getCallback(self, context):
     def getCallback(self, context):
         # Returns the callback that was passed in to the previous
         # Returns the callback that was passed in to the previous

+ 18 - 16
direct/src/distributed/DistributedObjectAI.py

@@ -3,7 +3,8 @@
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.distributed.DistributedObjectBase import DistributedObjectBase
 from direct.distributed.DistributedObjectBase import DistributedObjectBase
 from direct.showbase import PythonUtil
 from direct.showbase import PythonUtil
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 #from PyDatagram import PyDatagram
 #from PyDatagram import PyDatagram
 #from PyDatagramIterator import PyDatagramIterator
 #from PyDatagramIterator import PyDatagramIterator
 
 
@@ -56,25 +57,26 @@ class DistributedObjectAI(DistributedObjectBase):
         def status(self, indent=0):
         def status(self, indent=0):
             """
             """
             print out doId(parentId, zoneId) className
             print out doId(parentId, zoneId) className
-                and conditionally show generated, disabled, neverDisable,
-                or cachable
+                and conditionally show generated or deleted
             """
             """
-            spaces=' '*(indent+2)
+            spaces = ' ' * (indent + 2)
             try:
             try:
-                print "%s%s:"%(
-                    ' '*indent, self.__class__.__name__)
-                print "%sfrom DistributedObject doId:%s, parent:%s, zone:%s"%(
-                    spaces,
-                    self.doId, self.parentId, self.zoneId),
-                flags=[]
+                print("%s%s:" % (' ' * indent, self.__class__.__name__))
+
+                flags = []
                 if self.__generated:
                 if self.__generated:
                     flags.append("generated")
                     flags.append("generated")
                 if self.air == None:
                 if self.air == None:
                     flags.append("deleted")
                     flags.append("deleted")
+
+                flagStr = ""
                 if len(flags):
                 if len(flags):
-                    print "(%s)"%(" ".join(flags),),
-                print
-            except Exception, e: print "%serror printing status"%(spaces,), e
+                    flagStr = " (%s)" % (" ".join(flags))
+
+                print("%sfrom DistributedObject doId:%s, parent:%s, zone:%s%s" % (
+                    spaces, self.doId, self.parentId, self.zoneId, flagStr))
+            except Exception as e:
+                print("%serror printing status %s" % (spaces, e))
 
 
     def getDeleteEvent(self):
     def getDeleteEvent(self):
         # this is sent just before we get deleted
         # this is sent just before we get deleted
@@ -347,16 +349,16 @@ class DistributedObjectAI(DistributedObjectBase):
             self.air.sendUpdate(self, fieldName, args)
             self.air.sendUpdate(self, fieldName, args)
 
 
     def GetPuppetConnectionChannel(self, doId):
     def GetPuppetConnectionChannel(self, doId):
-        return doId + (1L << 32)
+        return doId + (1 << 32)
 
 
     def GetAccountConnectionChannel(self, doId):
     def GetAccountConnectionChannel(self, doId):
-        return doId + (3L << 32)
+        return doId + (3 << 32)
 
 
     def GetAccountIDFromChannelCode(self, channel):
     def GetAccountIDFromChannelCode(self, channel):
         return channel >> 32
         return channel >> 32
 
 
     def GetAvatarIDFromChannelCode(self, channel):
     def GetAvatarIDFromChannelCode(self, channel):
-        return channel & 0xffffffffL
+        return channel & 0xffffffff
 
 
     def sendUpdateToAvatarId(self, avId, fieldName, args):
     def sendUpdateToAvatarId(self, avId, fieldName, args):
         assert self.notify.debugStateCall(self)
         assert self.notify.debugStateCall(self)

+ 6 - 7
direct/src/distributed/DistributedObjectBase.py

@@ -22,14 +22,13 @@ class DistributedObjectBase(DirectObject):
             """
             """
             print out "doId(parentId, zoneId) className"
             print out "doId(parentId, zoneId) className"
             """
             """
-            spaces=' '*(indent+2)
+            spaces = ' ' * (indent + 2)
             try:
             try:
-                print "%s%s:"%(
-                    ' '*indent, self.__class__.__name__)
-                print "%sfrom DistributedObject doId:%s, parent:%s, zone:%s"%(
-                    spaces,
-                    self.doId, self.parentId, self.zoneId),
-            except Exception, e: print "%serror printing status"%(spaces,), e
+                print("%s%s:" % (' ' * indent, self.__class__.__name__))
+                print("%sfrom DistributedObject doId:%s, parent:%s, zone:%s" % (
+                    spaces, self.doId, self.parentId, self.zoneId))
+            except Exception as e:
+                print("%serror printing status %s" % (spaces, e))
 
 
     def getLocation(self):
     def getLocation(self):
         try:
         try:

+ 1 - 1
direct/src/distributed/DistributedObjectGlobalAI.py

@@ -1,5 +1,5 @@
 
 
-from DistributedObjectAI import DistributedObjectAI
+from .DistributedObjectAI import DistributedObjectAI
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify
 
 
 
 

+ 1 - 1
direct/src/distributed/DistributedObjectGlobalUD.py

@@ -1,6 +1,6 @@
 
 
 
 
-from DistributedObjectUD import DistributedObjectUD
+from .DistributedObjectUD import DistributedObjectUD
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify
 
 
 import sys
 import sys

+ 12 - 10
direct/src/distributed/DistributedObjectOV.py

@@ -40,22 +40,24 @@ class DistributedObjectOV(DistributedObjectBase):
             print out "doId(parentId, zoneId) className"
             print out "doId(parentId, zoneId) className"
                 and conditionally show generated, disabled
                 and conditionally show generated, disabled
             """
             """
-            spaces=' '*(indent+2)
+            spaces = ' ' * (indent + 2)
             try:
             try:
-                print "%s%s:"%(
-                    ' '*indent, self.__class__.__name__)
-                print "%sfrom DistributedObjectOV doId:%s, parent:%s, zone:%s"%(
-                    spaces,
-                    self.doId, self.parentId, self.zoneId),
-                flags=[]
+                print("%s%s:" % (' ' * indent, self.__class__.__name__))
+
+                flags = []
                 if self.activeState == ESGenerated:
                 if self.activeState == ESGenerated:
                     flags.append("generated")
                     flags.append("generated")
                 if self.activeState < ESGenerating:
                 if self.activeState < ESGenerating:
                     flags.append("disabled")
                     flags.append("disabled")
+
+                flagStr = ""
                 if len(flags):
                 if len(flags):
-                    print "(%s)"%(" ".join(flags),),
-                print
-            except Exception, e: print "%serror printing status"%(spaces,), e
+                    flagStr = " (%s)" % (" ".join(flags))
+
+                print("%sfrom DistributedObjectOV doId:%s, parent:%s, zone:%s%s" % (
+                    spaces, self.doId, self.parentId, self.zoneId, flagStr))
+            except Exception as e:
+                print("%serror printing status %s" % (spaces, e))
 
 
 
 
     def getDelayDeleteCount(self):
     def getDelayDeleteCount(self):

+ 14 - 12
direct/src/distributed/DistributedObjectUD.py

@@ -54,24 +54,26 @@ class DistributedObjectUD(DistributedObjectBase):
         def status(self, indent=0):
         def status(self, indent=0):
             """
             """
             print out doId(parentId, zoneId) className
             print out doId(parentId, zoneId) className
-                and conditionally show generated, disabled, neverDisable,
-                or cachable
+                and conditionally show generated or deleted
             """
             """
             spaces = ' ' * (indent + 2)
             spaces = ' ' * (indent + 2)
             try:
             try:
-                print "%s%s:" % (' ' * indent, self.__class__.__name__)
-                print ("%sfrom "
-                       "DistributedObject doId:%s, parent:%s, zone:%s" %
-                       (spaces, self.doId, self.parentId, self.zoneId)),
+                print("%s%s:" % (' ' * indent, self.__class__.__name__))
+
                 flags = []
                 flags = []
                 if self.__generated:
                 if self.__generated:
                     flags.append("generated")
                     flags.append("generated")
                 if self.air == None:
                 if self.air == None:
                     flags.append("deleted")
                     flags.append("deleted")
+
+                flagStr = ""
                 if len(flags):
                 if len(flags):
-                    print "(%s)" % (" ".join(flags),),
-                print
-            except Exception, e: print "%serror printing status" % (spaces,), e
+                    flagStr = " (%s)" % (" ".join(flags))
+
+                print("%sfrom DistributedObject doId:%s, parent:%s, zone:%s%s" % (
+                    spaces, self.doId, self.parentId, self.zoneId, flagStr))
+            except Exception as e:
+                print("%serror printing status %s" % (spaces, e))
 
 
     def getDeleteEvent(self):
     def getDeleteEvent(self):
         # this is sent just before we get deleted
         # this is sent just before we get deleted
@@ -267,16 +269,16 @@ class DistributedObjectUD(DistributedObjectBase):
             self.air.sendUpdate(self, fieldName, args)
             self.air.sendUpdate(self, fieldName, args)
 
 
     def GetPuppetConnectionChannel(self, doId):
     def GetPuppetConnectionChannel(self, doId):
-        return doId + (1L << 32)
+        return doId + (1 << 32)
 
 
     def GetAccountConnectionChannel(self, doId):
     def GetAccountConnectionChannel(self, doId):
-        return doId + (3L << 32)
+        return doId + (3 << 32)
 
 
     def GetAccountIDFromChannelCode(self, channel):
     def GetAccountIDFromChannelCode(self, channel):
         return channel >> 32
         return channel >> 32
 
 
     def GetAvatarIDFromChannelCode(self, channel):
     def GetAvatarIDFromChannelCode(self, channel):
-        return channel & 0xffffffffL
+        return channel & 0xffffffff
 
 
     def sendUpdateToAvatarId(self, avId, fieldName, args):
     def sendUpdateToAvatarId(self, avId, fieldName, args):
         assert self.notify.debugStateCall(self)
         assert self.notify.debugStateCall(self)

+ 3 - 3
direct/src/distributed/DistributedSmoothNode.py

@@ -1,9 +1,9 @@
 """DistributedSmoothNode module: contains the DistributedSmoothNode class"""
 """DistributedSmoothNode module: contains the DistributedSmoothNode class"""
 
 
 from pandac.PandaModules import *
 from pandac.PandaModules import *
-from ClockDelta import *
-import DistributedNode
-import DistributedSmoothNodeBase
+from .ClockDelta import *
+from . import DistributedNode
+from . import DistributedSmoothNodeBase
 from direct.task.Task import cont
 from direct.task.Task import cont
 
 
 # This number defines our tolerance for out-of-sync telemetry packets.
 # This number defines our tolerance for out-of-sync telemetry packets.

+ 2 - 2
direct/src/distributed/DistributedSmoothNodeAI.py

@@ -1,5 +1,5 @@
-import DistributedNodeAI
-import DistributedSmoothNodeBase
+from . import DistributedNodeAI
+from . import DistributedSmoothNodeBase
 
 
 class DistributedSmoothNodeAI(DistributedNodeAI.DistributedNodeAI,
 class DistributedSmoothNodeAI(DistributedNodeAI.DistributedNodeAI,
                               DistributedSmoothNodeBase.DistributedSmoothNodeBase):
                               DistributedSmoothNodeBase.DistributedSmoothNodeBase):

+ 1 - 1
direct/src/distributed/DistributedSmoothNodeBase.py

@@ -1,6 +1,6 @@
 """DistributedSmoothNodeBase module: contains the DistributedSmoothNodeBase class"""
 """DistributedSmoothNodeBase module: contains the DistributedSmoothNodeBase class"""
 
 
-from ClockDelta import *
+from .ClockDelta import *
 from direct.task import Task
 from direct.task import Task
 from direct.showbase.PythonUtil import randFloat, Enum
 from direct.showbase.PythonUtil import randFloat, Enum
 from panda3d.direct import CDistributedSmoothNodeBase
 from panda3d.direct import CDistributedSmoothNodeBase

+ 14 - 14
direct/src/distributed/DoCollectionManager.py

@@ -117,29 +117,29 @@ class DoCollectionManager:
         return 1
         return 1
 
 
     def dosByDistance(self):
     def dosByDistance(self):
-        objs = self.doId2do.values()
+        objs = list(self.doId2do.values())
         objs.sort(cmp=self._compareDistance)
         objs.sort(cmp=self._compareDistance)
         return objs
         return objs
 
 
     def doByDistance(self):
     def doByDistance(self):
         objs = self.dosByDistance()
         objs = self.dosByDistance()
         for obj in objs:
         for obj in objs:
-            print '%s\t%s\t%s' % (obj.doId, self._getDistanceFromLA(obj),
-                                  obj.dclass.getName())
+            print('%s\t%s\t%s' % (obj.doId, self._getDistanceFromLA(obj),
+                                  obj.dclass.getName()))
 
 
     if __debug__:
     if __debug__:
         def printObjects(self):
         def printObjects(self):
             format="%10s %10s %10s %30s %20s"
             format="%10s %10s %10s %30s %20s"
             title=format%("parentId", "zoneId", "doId", "dclass", "name")
             title=format%("parentId", "zoneId", "doId", "dclass", "name")
-            print title
-            print '-'*len(title)
+            print(title)
+            print('-'*len(title))
             for distObj in self.doId2do.values():
             for distObj in self.doId2do.values():
-                print format%(
+                print(format%(
                     distObj.__dict__.get("parentId"),
                     distObj.__dict__.get("parentId"),
                     distObj.__dict__.get("zoneId"),
                     distObj.__dict__.get("zoneId"),
                     distObj.__dict__.get("doId"),
                     distObj.__dict__.get("doId"),
                     distObj.dclass.getName(),
                     distObj.dclass.getName(),
-                    distObj.__dict__.get("name"))
+                    distObj.__dict__.get("name")))
 
 
     def _printObjects(self, table):
     def _printObjects(self, table):
         class2count = {}
         class2count = {}
@@ -148,14 +148,14 @@ class DoCollectionManager:
             class2count.setdefault(className, 0)
             class2count.setdefault(className, 0)
             class2count[className] += 1
             class2count[className] += 1
         count2classes = invertDictLossless(class2count)
         count2classes = invertDictLossless(class2count)
-        counts = count2classes.keys()
+        counts = list(count2classes.keys())
         counts.sort()
         counts.sort()
         counts.reverse()
         counts.reverse()
         for count in counts:
         for count in counts:
             count2classes[count].sort()
             count2classes[count].sort()
             for name in count2classes[count]:
             for name in count2classes[count]:
-                print '%s %s' % (count, name)
-        print ''
+                print('%s %s' % (count, name))
+        print('')
 
 
     def _returnObjects(self, table):
     def _returnObjects(self, table):
         class2count = {}
         class2count = {}
@@ -165,7 +165,7 @@ class DoCollectionManager:
             class2count.setdefault(className, 0)
             class2count.setdefault(className, 0)
             class2count[className] += 1
             class2count[className] += 1
         count2classes = invertDictLossless(class2count)
         count2classes = invertDictLossless(class2count)
-        counts = count2classes.keys()
+        counts = list(count2classes.keys())
         counts.sort()
         counts.sort()
         counts.reverse()
         counts.reverse()
         for count in counts:
         for count in counts:
@@ -189,12 +189,12 @@ class DoCollectionManager:
 
 
     def printObjectCount(self):
     def printObjectCount(self):
         # print object counts by distributed object type
         # print object counts by distributed object type
-        print '==== OBJECT COUNT ===='
+        print('==== OBJECT COUNT ====')
         if self.hasOwnerView():
         if self.hasOwnerView():
-            print '== doId2do'
+            print('== doId2do')
         self._printObjects(self.getDoTable(ownerView=False))
         self._printObjects(self.getDoTable(ownerView=False))
         if self.hasOwnerView():
         if self.hasOwnerView():
-            print '== doId2ownerView'
+            print('== doId2ownerView')
             self._printObjects(self.getDoTable(ownerView=True))
             self._printObjects(self.getDoTable(ownerView=True))
 
 
     def getDoList(self, parentId, zoneId=None, classType=None):
     def getDoList(self, parentId, zoneId=None, classType=None):

+ 26 - 26
direct/src/distributed/DoInterestManager.py

@@ -8,10 +8,10 @@ p.s. A great deal of this code is just code moved from ClientRepository.py.
 """
 """
 
 
 from pandac.PandaModules import *
 from pandac.PandaModules import *
-from MsgTypes import *
+from .MsgTypes import *
 from direct.showbase.PythonUtil import *
 from direct.showbase.PythonUtil import *
 from direct.showbase import DirectObject
 from direct.showbase import DirectObject
-from PyDatagram import PyDatagram
+from .PyDatagram import PyDatagram
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify
 import types
 import types
 from direct.showbase.PythonUtil import report
 from direct.showbase.PythonUtil import report
@@ -184,8 +184,8 @@ class DoInterestManager(DirectObject.DirectObject):
         DoInterestManager._interests[handle] = InterestState(
         DoInterestManager._interests[handle] = InterestState(
             description, InterestState.StateActive, contextId, event, parentId, zoneIdList, self._completeEventCount)
             description, InterestState.StateActive, contextId, event, parentId, zoneIdList, self._completeEventCount)
         if self.__verbose():
         if self.__verbose():
-            print 'CR::INTEREST.addInterest(handle=%s, parentId=%s, zoneIdList=%s, description=%s, event=%s)' % (
-                handle, parentId, zoneIdList, description, event)
+            print('CR::INTEREST.addInterest(handle=%s, parentId=%s, zoneIdList=%s, description=%s, event=%s)' % (
+                handle, parentId, zoneIdList, description, event))
         self._sendAddInterest(handle, contextId, parentId, zoneIdList, description)
         self._sendAddInterest(handle, contextId, parentId, zoneIdList, description)
         if event:
         if event:
             messenger.send(self._getAddInterestEvent(), [event])
             messenger.send(self._getAddInterestEvent(), [event])
@@ -218,8 +218,8 @@ class DoInterestManager(DirectObject.DirectObject):
         DoInterestManager._interests[handle] = InterestState(
         DoInterestManager._interests[handle] = InterestState(
             description, InterestState.StateActive, 0, None, parentId, zoneIdList, self._completeEventCount, True)
             description, InterestState.StateActive, 0, None, parentId, zoneIdList, self._completeEventCount, True)
         if self.__verbose():
         if self.__verbose():
-            print 'CR::INTEREST.addInterest(handle=%s, parentId=%s, zoneIdList=%s, description=%s)' % (
-                handle, parentId, zoneIdList, description)
+            print('CR::INTEREST.addInterest(handle=%s, parentId=%s, zoneIdList=%s, description=%s)' % (
+                handle, parentId, zoneIdList, description))
         assert self.printInterestsIfDebug()
         assert self.printInterestsIfDebug()
         return InterestHandle(handle)
         return InterestHandle(handle)
 
 
@@ -266,8 +266,8 @@ class DoInterestManager(DirectObject.DirectObject):
                 if not event:
                 if not event:
                     self._considerRemoveInterest(handle)
                     self._considerRemoveInterest(handle)
                 if self.__verbose():
                 if self.__verbose():
-                    print 'CR::INTEREST.removeInterest(handle=%s, event=%s)' % (
-                        handle, event)
+                    print('CR::INTEREST.removeInterest(handle=%s, event=%s)' % (
+                        handle, event))
         else:
         else:
             DoInterestManager.notify.warning(
             DoInterestManager.notify.warning(
                 "removeInterest: handle not found: %s" % (handle))
                 "removeInterest: handle not found: %s" % (handle))
@@ -302,7 +302,7 @@ class DoInterestManager(DirectObject.DirectObject):
                 intState.state = InterestState.StatePendingDel
                 intState.state = InterestState.StatePendingDel
                 self._considerRemoveInterest(handle)
                 self._considerRemoveInterest(handle)
                 if self.__verbose():
                 if self.__verbose():
-                    print 'CR::INTEREST.removeAutoInterest(handle=%s)' % (handle)
+                    print('CR::INTEREST.removeAutoInterest(handle=%s)' % (handle))
         else:
         else:
             DoInterestManager.notify.warning(
             DoInterestManager.notify.warning(
                 "removeInterest: handle not found: %s" % (handle))
                 "removeInterest: handle not found: %s" % (handle))
@@ -357,8 +357,8 @@ class DoInterestManager(DirectObject.DirectObject):
             DoInterestManager._interests[handle].addEvent(event)
             DoInterestManager._interests[handle].addEvent(event)
 
 
             if self.__verbose():
             if self.__verbose():
-                print 'CR::INTEREST.alterInterest(handle=%s, parentId=%s, zoneIdList=%s, description=%s, event=%s)' % (
-                    handle, parentId, zoneIdList, description, event)
+                print('CR::INTEREST.alterInterest(handle=%s, parentId=%s, zoneIdList=%s, description=%s, event=%s)' % (
+                    handle, parentId, zoneIdList, description, event))
             self._sendAddInterest(handle, contextId, parentId, zoneIdList, description, action='modify')
             self._sendAddInterest(handle, contextId, parentId, zoneIdList, description, action='modify')
             exists = True
             exists = True
             assert self.printInterestsIfDebug()
             assert self.printInterestsIfDebug()
@@ -445,24 +445,24 @@ class DoInterestManager(DirectObject.DirectObject):
                 DoInterestManager._debug_maxDescriptionLen, len(description))
                 DoInterestManager._debug_maxDescriptionLen, len(description))
 
 
         def printInterestHistory(self):
         def printInterestHistory(self):
-            print "***************** Interest History *************"
+            print("***************** Interest History *************")
             format = '%9s %' + str(DoInterestManager._debug_maxDescriptionLen) + 's %6s %6s %9s %s'
             format = '%9s %' + str(DoInterestManager._debug_maxDescriptionLen) + 's %6s %6s %9s %s'
-            print format % (
+            print(format % (
                 "Action", "Description", "Handle", "Context", "ParentId",
                 "Action", "Description", "Handle", "Context", "ParentId",
-                "ZoneIdList")
+                "ZoneIdList"))
             for i in DoInterestManager._debug_interestHistory:
             for i in DoInterestManager._debug_interestHistory:
-                print format % tuple(i)
-            print "Note: interests with a Context of 0 do not get" \
-                " done/finished notices."
+                print(format % tuple(i))
+            print("Note: interests with a Context of 0 do not get" \
+                " done/finished notices.")
 
 
         def printInterestSets(self):
         def printInterestSets(self):
-            print "******************* Interest Sets **************"
+            print("******************* Interest Sets **************")
             format = '%6s %' + str(DoInterestManager._debug_maxDescriptionLen) + 's %11s %11s %8s %8s %8s'
             format = '%6s %' + str(DoInterestManager._debug_maxDescriptionLen) + 's %11s %11s %8s %8s %8s'
-            print format % (
+            print(format % (
                 "Handle", "Description",
                 "Handle", "Description",
                 "ParentId", "ZoneIdList",
                 "ParentId", "ZoneIdList",
                 "State", "Context",
                 "State", "Context",
-                "Event")
+                "Event"))
             for id, state in DoInterestManager._interests.items():
             for id, state in DoInterestManager._interests.items():
                 if len(state.events) == 0:
                 if len(state.events) == 0:
                     event = ''
                     event = ''
@@ -470,11 +470,11 @@ class DoInterestManager(DirectObject.DirectObject):
                     event = state.events[0]
                     event = state.events[0]
                 else:
                 else:
                     event = state.events
                     event = state.events
-                print format % (id, state.desc,
+                print(format % (id, state.desc,
                                 state.parentId, state.zoneIdList,
                                 state.parentId, state.zoneIdList,
                                 state.state, state.context,
                                 state.state, state.context,
-                                event)
-            print "************************************************"
+                                event))
+            print("************************************************")
 
 
         def printInterests(self):
         def printInterests(self):
             self.printInterestHistory()
             self.printInterestHistory()
@@ -492,7 +492,7 @@ class DoInterestManager(DirectObject.DirectObject):
         """
         """
         assert DoInterestManager.notify.debugCall()
         assert DoInterestManager.notify.debugCall()
         if __debug__:
         if __debug__:
-            if isinstance(zoneIdList, types.ListType):
+            if isinstance(zoneIdList, list):
                 zoneIdList.sort()
                 zoneIdList.sort()
             if action is None:
             if action is None:
                 action = 'add'
                 action = 'add'
@@ -507,7 +507,7 @@ class DoInterestManager(DirectObject.DirectObject):
         datagram.addUint16(handle)
         datagram.addUint16(handle)
         datagram.addUint32(contextId)
         datagram.addUint32(contextId)
         datagram.addUint32(parentId)
         datagram.addUint32(parentId)
-        if isinstance(zoneIdList, types.ListType):
+        if isinstance(zoneIdList, list):
             vzl = list(zoneIdList)
             vzl = list(zoneIdList)
             vzl.sort()
             vzl.sort()
             uniqueElements(vzl)
             uniqueElements(vzl)
@@ -585,7 +585,7 @@ class DoInterestManager(DirectObject.DirectObject):
         handle = di.getUint16()
         handle = di.getUint16()
         contextId = di.getUint32()
         contextId = di.getUint32()
         if self.__verbose():
         if self.__verbose():
-            print 'CR::INTEREST.interestDone(handle=%s)' % handle
+            print('CR::INTEREST.interestDone(handle=%s)' % handle)
         DoInterestManager.notify.debug(
         DoInterestManager.notify.debug(
             "handleInterestDoneMessage--> Received handle %s, context %s" % (
             "handleInterestDoneMessage--> Received handle %s, context %s" % (
             handle, contextId))
             handle, contextId))

+ 1 - 1
direct/src/distributed/GridChild.py

@@ -106,7 +106,7 @@ class GridChild:
                 self._gridInterests[gridDoId] = [None,zoneId]
                 self._gridInterests[gridDoId] = [None,zoneId]
 
 
     def getGridInterestIds(self):
     def getGridInterestIds(self):
-        return self._gridInterests.keys()
+        return list(self._gridInterests.keys())
 
 
     def getGridInterestZoneId(self,gridDoId):
     def getGridInterestZoneId(self,gridDoId):
         return self._gridInterests.get(gridDoId,[None,None])[1]
         return self._gridInterests.get(gridDoId,[None,None])[1]

+ 6 - 2
direct/src/distributed/NetMessenger.py

@@ -1,10 +1,14 @@
 
 
-from cPickle import dumps, loads
-
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
 from direct.distributed.PyDatagram import PyDatagram
 from direct.distributed.PyDatagram import PyDatagram
 from direct.showbase.Messenger import Messenger
 from direct.showbase.Messenger import Messenger
 
 
+import sys
+if sys.version_info >= (3, 0):
+    from pickle import dumps, loads
+else:
+    from cPickle import dumps, loads
+
 
 
 # Messages do not need to be in the MESSAGE_TYPES list.
 # Messages do not need to be in the MESSAGE_TYPES list.
 # This is just an optimization.  If the message is found
 # This is just an optimization.  If the message is found

+ 2 - 2
direct/src/distributed/OldClientRepository.py

@@ -1,6 +1,6 @@
 """OldClientRepository module: contains the OldClientRepository class"""
 """OldClientRepository module: contains the OldClientRepository class"""
 
 
-from ClientRepositoryBase import *
+from .ClientRepositoryBase import *
 
 
 class OldClientRepository(ClientRepositoryBase):
 class OldClientRepository(ClientRepositoryBase):
     """
     """
@@ -126,7 +126,7 @@ class OldClientRepository(ClientRepositoryBase):
 
 
     def handleDatagram(self, di):
     def handleDatagram(self, di):
         if self.notify.getDebug():
         if self.notify.getDebug():
-            print "ClientRepository received datagram:"
+            print("ClientRepository received datagram:")
             di.getDatagram().dumpHex(ostream)
             di.getDatagram().dumpHex(ostream)
 
 
         msgType = self.getMsgType()
         msgType = self.getMsgType()

+ 2 - 2
direct/src/distributed/ParentMgr.py

@@ -2,7 +2,7 @@
 
 
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
 from direct.showbase.PythonUtil import isDefaultValue
 from direct.showbase.PythonUtil import isDefaultValue
-import types
+
 
 
 class ParentMgr:
 class ParentMgr:
     # This is now used on the AI as well.
     # This is now used on the AI as well.
@@ -90,7 +90,7 @@ class ParentMgr:
         if isDefaultValue(token):
         if isDefaultValue(token):
             self.notify.error('parent token (for %s) cannot be a default value (%s)' % (repr(parent), token))
             self.notify.error('parent token (for %s) cannot be a default value (%s)' % (repr(parent), token))
 
 
-        if type(token) is types.IntType:
+        if type(token) is int:
             if token > 0xFFFFFFFF:
             if token > 0xFFFFFFFF:
                 self.notify.error('parent token %s (for %s) is out of uint32 range' % (token, repr(parent)))
                 self.notify.error('parent token %s (for %s) is out of uint32 range' % (token, repr(parent)))
 
 

+ 6 - 8
direct/src/distributed/ServerRepository.py

@@ -5,9 +5,7 @@ from direct.distributed.MsgTypesCMU import *
 from direct.task import Task
 from direct.task import Task
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
 from direct.distributed.PyDatagram import PyDatagram
 from direct.distributed.PyDatagram import PyDatagram
-from direct.distributed.PyDatagramIterator import PyDatagramIterator
-import time
-import types
+
 
 
 class ServerRepository:
 class ServerRepository:
 
 
@@ -153,7 +151,7 @@ class ServerRepository:
         for client in flush:
         for client in flush:
             client.connection.flush()
             client.connection.flush()
 
 
-        return task.again
+        return Task.again
 
 
     def setTcpHeaderSize(self, headerSize):
     def setTcpHeaderSize(self, headerSize):
         """Sets the header size of TCP packets.  At the present, legal
         """Sets the header size of TCP packets.  At the present, legal
@@ -299,7 +297,7 @@ class ServerRepository:
             retVal = self.qcl.getNewConnection(rendezvous, netAddress,
             retVal = self.qcl.getNewConnection(rendezvous, netAddress,
                                                newConnection)
                                                newConnection)
             if not retVal:
             if not retVal:
-                return task.cont
+                return Task.cont
 
 
             # Crazy dereferencing
             # Crazy dereferencing
             newConnection = newConnection.p()
             newConnection = newConnection.p()
@@ -321,13 +319,13 @@ class ServerRepository:
             self.lastConnection = newConnection
             self.lastConnection = newConnection
             self.sendDoIdRange(client)
             self.sendDoIdRange(client)
 
 
-        return task.cont
+        return Task.cont
 
 
     def readerPollUntilEmpty(self, task):
     def readerPollUntilEmpty(self, task):
         """ continuously polls for new messages on the server """
         """ continuously polls for new messages on the server """
         while self.readerPollOnce():
         while self.readerPollOnce():
             pass
             pass
-        return task.cont
+        return Task.cont
 
 
     def readerPollOnce(self):
     def readerPollOnce(self):
         """ checks for available messages to the server """
         """ checks for available messages to the server """
@@ -691,7 +689,7 @@ class ServerRepository:
         for client in self.clientsByConnection.values():
         for client in self.clientsByConnection.values():
             if not self.qcr.isConnectionOk(client.connection):
             if not self.qcr.isConnectionOk(client.connection):
                 self.handleClientDisconnect(client)
                 self.handleClientDisconnect(client)
-        return task.cont
+        return Task.cont
 
 
     def sendToZoneExcept(self, zoneId, datagram, exceptionList):
     def sendToZoneExcept(self, zoneId, datagram, exceptionList):
         """sends a message to everyone who has interest in the
         """sends a message to everyone who has interest in the

+ 1 - 1
direct/src/distributed/TimeManagerAI.py

@@ -18,6 +18,6 @@ class TimeManagerAI(DistributedObjectAI.DistributedObjectAI):
         """
         """
         timestamp = globalClockDelta.getRealNetworkTime(bits=32)
         timestamp = globalClockDelta.getRealNetworkTime(bits=32)
         requesterId = self.air.getAvatarIdFromSender()
         requesterId = self.air.getAvatarIdFromSender()
-        print "requestServerTime from %s" % (requesterId)
+        print("requestServerTime from %s" % (requesterId))
         self.sendUpdateToAvatarId(requesterId, "serverTime",
         self.sendUpdateToAvatarId(requesterId, "serverTime",
                                   [context, timestamp])
                                   [context, timestamp])

+ 4 - 1
direct/src/doc/howto.adjust

@@ -52,7 +52,10 @@ of the slider to change settings.  Click on:
 
 
 You can pack multiple sliders into a single panel:
 You can pack multiple sliders into a single panel:
 
 
-from Tkinter import *
+if sys.version_info >= (3, 0):
+    from tkinter import *
+else:
+    from Tkinter import *
 
 
 def func1(x):
 def func1(x):
    print '1:', x
    print '1:', x

+ 19 - 16
direct/src/extensions_native/CInterval_extensions.py

@@ -63,14 +63,17 @@ def popupControls(self, tl = None):
         import math
         import math
         # Don't use a regular import, to prevent ModuleFinder from picking
         # Don't use a regular import, to prevent ModuleFinder from picking
         # it up as a dependency when building a .p3d package.
         # it up as a dependency when building a .p3d package.
-        import importlib
+        import importlib, sys
         EntryScale = importlib.import_module('direct.tkwidgets.EntryScale')
         EntryScale = importlib.import_module('direct.tkwidgets.EntryScale')
-        Tkinter = importlib.import_module('Tkinter')
+        if sys.version_info >= (3, 0):
+            tkinter = importlib.import_module('tkinter')
+        else:
+            tkinter = importlib.import_module('Tkinter')
 
 
         if tl == None:
         if tl == None:
-            tl = Tkinter.Toplevel()
+            tl = tkinter.Toplevel()
             tl.title('Interval Controls')
             tl.title('Interval Controls')
-        outerFrame = Tkinter.Frame(tl)
+        outerFrame = tkinter.Frame(tl)
         def entryScaleCommand(t, s=self):
         def entryScaleCommand(t, s=self):
             s.setT(t)
             s.setT(t)
             s.pause()
             s.pause()
@@ -79,8 +82,8 @@ def popupControls(self, tl = None):
             min = 0, max = math.floor(self.getDuration() * 100) / 100,
             min = 0, max = math.floor(self.getDuration() * 100) / 100,
             command = entryScaleCommand)
             command = entryScaleCommand)
         es.set(self.getT(), fCommand = 0)
         es.set(self.getT(), fCommand = 0)
-        es.pack(expand = 1, fill = Tkinter.X)
-        bf = Tkinter.Frame(outerFrame)
+        es.pack(expand = 1, fill = tkinter.X)
+        bf = tkinter.Frame(outerFrame)
         # Jump to start and end
         # Jump to start and end
         def toStart(s=self, es=es):
         def toStart(s=self, es=es):
             s.setT(0.0)
             s.setT(0.0)
@@ -88,23 +91,23 @@ def popupControls(self, tl = None):
         def toEnd(s=self):
         def toEnd(s=self):
             s.setT(s.getDuration())
             s.setT(s.getDuration())
             s.pause()
             s.pause()
-        jumpToStart = Tkinter.Button(bf, text = '<<', command = toStart)
+        jumpToStart = tkinter.Button(bf, text = '<<', command = toStart)
         # Stop/play buttons
         # Stop/play buttons
         def doPlay(s=self, es=es):
         def doPlay(s=self, es=es):
             s.resume(es.get())
             s.resume(es.get())
 
 
-        stop = Tkinter.Button(bf, text = 'Stop',
+        stop = tkinter.Button(bf, text = 'Stop',
                       command = lambda s=self: s.pause())
                       command = lambda s=self: s.pause())
-        play = Tkinter.Button(
+        play = tkinter.Button(
             bf, text = 'Play',
             bf, text = 'Play',
             command = doPlay)
             command = doPlay)
-        jumpToEnd = Tkinter.Button(bf, text = '>>', command = toEnd)
-        jumpToStart.pack(side = Tkinter.LEFT, expand = 1, fill = Tkinter.X)
-        play.pack(side = Tkinter.LEFT, expand = 1, fill = Tkinter.X)
-        stop.pack(side = Tkinter.LEFT, expand = 1, fill = Tkinter.X)
-        jumpToEnd.pack(side = Tkinter.LEFT, expand = 1, fill = Tkinter.X)
-        bf.pack(expand = 1, fill = Tkinter.X)
-        outerFrame.pack(expand = 1, fill = Tkinter.X)
+        jumpToEnd = tkinter.Button(bf, text = '>>', command = toEnd)
+        jumpToStart.pack(side = tkinter.LEFT, expand = 1, fill = tkinter.X)
+        play.pack(side = tkinter.LEFT, expand = 1, fill = tkinter.X)
+        stop.pack(side = tkinter.LEFT, expand = 1, fill = tkinter.X)
+        jumpToEnd.pack(side = tkinter.LEFT, expand = 1, fill = tkinter.X)
+        bf.pack(expand = 1, fill = tkinter.X)
+        outerFrame.pack(expand = 1, fill = tkinter.X)
         # Add function to update slider during setT calls
         # Add function to update slider during setT calls
         def update(t, es=es):
         def update(t, es=es):
             es.set(t, fCommand = 0)
             es.set(t, fCommand = 0)

+ 2 - 2
direct/src/extensions_native/NodePath_extensions.py

@@ -690,7 +690,7 @@ def subdivideCollisions(self, numSolidsInLeaves):
                 # this CollisionNode doesn't need to be split
                 # this CollisionNode doesn't need to be split
                 continue
                 continue
             solids = []
             solids = []
-            for i in xrange(numSolids):
+            for i in range(numSolids):
                 solids.append(node.getSolid(i))
                 solids.append(node.getSolid(i))
             # recursively subdivide the solids into a spatial binary tree
             # recursively subdivide the solids into a spatial binary tree
             solidTree = self.r_subdivideCollisions(solids, numSolidsInLeaves)
             solidTree = self.r_subdivideCollisions(solids, numSolidsInLeaves)
@@ -743,7 +743,7 @@ def r_subdivideCollisions(self, solids, numSolidsInLeaves):
                 midY += maxExtent
                 midY += maxExtent
         if extentZ < (maxExtent * .75) or extentZ > (maxExtent * 1.25):
         if extentZ < (maxExtent * .75) or extentZ > (maxExtent * 1.25):
                 midZ += maxExtent
                 midZ += maxExtent
-        for i in xrange(len(solids)):
+        for i in range(len(solids)):
                 origin = origins[i]
                 origin = origins[i]
                 x = origin.getX(); y = origin.getY(); z = origin.getZ()
                 x = origin.getX(); y = origin.getY(); z = origin.getZ()
                 if x < midX:
                 if x < midX:

+ 1 - 2
direct/src/extensions_native/extension_native_helpers.py

@@ -1,7 +1,6 @@
-###  Tools
 __all__ = ["Dtool_ObjectToDict", "Dtool_funcToMethod"]
 __all__ = ["Dtool_ObjectToDict", "Dtool_funcToMethod"]
 
 
-import imp, sys, os
+import sys
 
 
 def Dtool_ObjectToDict(cls, name, obj):
 def Dtool_ObjectToDict(cls, name, obj):
     cls.DtoolClassDict[name] = obj
     cls.DtoolClassDict[name] = obj

+ 1 - 1
direct/src/filter/CommonFilters.py

@@ -15,7 +15,7 @@ clunky approach.  - Josh
 
 
 """
 """
 
 
-from FilterManager import FilterManager
+from .FilterManager import FilterManager
 from panda3d.core import LVecBase4, LPoint2
 from panda3d.core import LVecBase4, LPoint2
 from panda3d.core import Filename
 from panda3d.core import Filename
 from panda3d.core import AuxBitplaneAttrib
 from panda3d.core import AuxBitplaneAttrib

+ 7 - 10
direct/src/fsm/ClassicFSM.py

@@ -10,18 +10,15 @@ existing code.  New code should use the FSM module instead.
 
 
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
-import types
 import weakref
 import weakref
 
 
 if __debug__:
 if __debug__:
-    _debugFsms={}
+    _debugFsms = {}
     def printDebugFsmList():
     def printDebugFsmList():
         global _debugFsms
         global _debugFsms
-        keys=_debugFsms.keys()
-        keys.sort()
-        for k in keys:
-            print k, _debugFsms[k]()
-    __builtins__['debugFsmList']=printDebugFsmList
+        for k in sorted(_debugFsms.keys()):
+            print("%s %s" % (k, _debugFsms[k]()))
+    __builtins__['debugFsmList'] = printDebugFsmList
 
 
 class ClassicFSM(DirectObject):
 class ClassicFSM(DirectObject):
     """
     """
@@ -123,7 +120,7 @@ class ClassicFSM(DirectObject):
         self.__name = name
         self.__name = name
 
 
     def getStates(self):
     def getStates(self):
-        return self.__states.values()
+        return list(self.__states.values())
 
 
     def setStates(self, states):
     def setStates(self, states):
         """setStates(self, State[])"""
         """setStates(self, State[])"""
@@ -251,7 +248,7 @@ class ClassicFSM(DirectObject):
                                (self.__name))
                                (self.__name))
             self.__currentState = self.__initialState
             self.__currentState = self.__initialState
 
 
-        if isinstance(aStateName, types.StringType):
+        if isinstance(aStateName, str):
             aState = self.getStateNamed(aStateName)
             aState = self.getStateNamed(aStateName)
         else:
         else:
             # Allow the caller to pass in a state in itself, not just
             # Allow the caller to pass in a state in itself, not just
@@ -342,7 +339,7 @@ class ClassicFSM(DirectObject):
                                (self.__name))
                                (self.__name))
             self.__currentState = self.__initialState
             self.__currentState = self.__initialState
 
 
-        if isinstance(aStateName, types.StringType):
+        if isinstance(aStateName, str):
             aState = self.getStateNamed(aStateName)
             aState = self.getStateNamed(aStateName)
         else:
         else:
             # Allow the caller to pass in a state in itself, not just
             # Allow the caller to pass in a state in itself, not just

+ 5 - 5
direct/src/fsm/FSM.py

@@ -9,7 +9,7 @@ from direct.showbase.DirectObject import DirectObject
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
 from direct.showbase import PythonUtil
 from direct.showbase import PythonUtil
 from direct.stdpy.threading import RLock
 from direct.stdpy.threading import RLock
-import types
+
 
 
 class FSMException(Exception):
 class FSMException(Exception):
     pass
     pass
@@ -238,7 +238,7 @@ class FSM(DirectObject):
 
 
         self.fsmLock.acquire()
         self.fsmLock.acquire()
         try:
         try:
-            assert isinstance(request, types.StringTypes)
+            assert isinstance(request, str)
             self.notify.debug("%s.forceTransition(%s, %s" % (
             self.notify.debug("%s.forceTransition(%s, %s" % (
                 self.name, request, str(args)[1:]))
                 self.name, request, str(args)[1:]))
 
 
@@ -266,7 +266,7 @@ class FSM(DirectObject):
 
 
         self.fsmLock.acquire()
         self.fsmLock.acquire()
         try:
         try:
-            assert isinstance(request, types.StringTypes)
+            assert isinstance(request, str)
             self.notify.debug("%s.demand(%s, %s" % (
             self.notify.debug("%s.demand(%s, %s" % (
                 self.name, request, str(args)[1:]))
                 self.name, request, str(args)[1:]))
             if not self.state:
             if not self.state:
@@ -305,14 +305,14 @@ class FSM(DirectObject):
 
 
         self.fsmLock.acquire()
         self.fsmLock.acquire()
         try:
         try:
-            assert isinstance(request, types.StringTypes)
+            assert isinstance(request, str)
             self.notify.debug("%s.request(%s, %s" % (
             self.notify.debug("%s.request(%s, %s" % (
                 self.name, request, str(args)[1:]))
                 self.name, request, str(args)[1:]))
 
 
             filter = self.getCurrentFilter()
             filter = self.getCurrentFilter()
             result = list(filter(request, args))
             result = list(filter(request, args))
             if result:
             if result:
-                if isinstance(result, types.StringTypes):
+                if isinstance(result, str):
                     # If the return value is a string, it's just the name
                     # If the return value is a string, it's just the name
                     # of the state.  Wrap it in a tuple for consistency.
                     # of the state.  Wrap it in a tuple for consistency.
                     result = (result,) + args
                     result = (result,) + args

+ 3 - 3
direct/src/fsm/FourState.py

@@ -6,8 +6,8 @@ __all__ = ['FourState']
 
 
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
 #import DistributedObject
 #import DistributedObject
-import ClassicFSM
-import State
+from . import ClassicFSM
+from . import State
 
 
 
 
 class FourState:
 class FourState:
@@ -122,7 +122,7 @@ class FourState:
             }
             }
         self.stateIndex = 0
         self.stateIndex = 0
         self.fsm = ClassicFSM.ClassicFSM('FourState',
         self.fsm = ClassicFSM.ClassicFSM('FourState',
-                           self.states.values(),
+                           list(self.states.values()),
                            # Initial State
                            # Initial State
                            names[0],
                            names[0],
                            # Final State
                            # Final State

+ 3 - 3
direct/src/fsm/FourStateAI.py

@@ -6,8 +6,8 @@ __all__ = ['FourStateAI']
 
 
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
 #import DistributedObjectAI
 #import DistributedObjectAI
-import ClassicFSM
-import State
+from . import ClassicFSM
+from . import State
 from direct.task import Task
 from direct.task import Task
 
 
 
 
@@ -128,7 +128,7 @@ class FourStateAI:
                            [names[1]]),
                            [names[1]]),
             }
             }
         self.fsm = ClassicFSM.ClassicFSM('FourState',
         self.fsm = ClassicFSM.ClassicFSM('FourState',
-                           self.states.values(),
+                           list(self.states.values()),
                            # Initial State
                            # Initial State
                            names[0],
                            names[0],
                            # Final State
                            # Final State

+ 20 - 21
direct/src/fsm/SampleFSM.py

@@ -2,9 +2,8 @@
 
 
 __all__ = ['ClassicStyle', 'NewStyle', 'ToonEyes']
 __all__ = ['ClassicStyle', 'NewStyle', 'ToonEyes']
 
 
-import FSM
+from . import FSM
 from direct.task import Task
 from direct.task import Task
-import string
 
 
 
 
 class ClassicStyle(FSM.FSM):
 class ClassicStyle(FSM.FSM):
@@ -19,61 +18,61 @@ class ClassicStyle(FSM.FSM):
             }
             }
 
 
     def enterRed(self):
     def enterRed(self):
-        print "enterRed(self, '%s', '%s')" % (self.oldState, self.newState)
+        print("enterRed(self, '%s', '%s')" % (self.oldState, self.newState))
 
 
     def exitRed(self):
     def exitRed(self):
-        print "exitRed(self, '%s', '%s')" % (self.oldState, self.newState)
+        print("exitRed(self, '%s', '%s')" % (self.oldState, self.newState))
 
 
     def enterYellow(self):
     def enterYellow(self):
-        print "enterYellow(self, '%s', '%s')" % (self.oldState, self.newState)
+        print("enterYellow(self, '%s', '%s')" % (self.oldState, self.newState))
 
 
     def exitYellow(self):
     def exitYellow(self):
-        print "exitYellow(self, '%s', '%s')" % (self.oldState, self.newState)
+        print("exitYellow(self, '%s', '%s')" % (self.oldState, self.newState))
 
 
     def enterGreen(self):
     def enterGreen(self):
-        print "enterGreen(self, '%s', '%s')" % (self.oldState, self.newState)
+        print("enterGreen(self, '%s', '%s')" % (self.oldState, self.newState))
 
 
     def exitGreen(self):
     def exitGreen(self):
-        print "exitGreen(self, '%s', '%s')" % (self.oldState, self.newState)
+        print("exitGreen(self, '%s', '%s')" % (self.oldState, self.newState))
 
 
 
 
 class NewStyle(FSM.FSM):
 class NewStyle(FSM.FSM):
 
 
     def enterRed(self):
     def enterRed(self):
-        print "enterRed(self, '%s', '%s')" % (self.oldState, self.newState)
+        print("enterRed(self, '%s', '%s')" % (self.oldState, self.newState))
 
 
     def filterRed(self, request, args):
     def filterRed(self, request, args):
-        print "filterRed(self, '%s', %s)" % (request, args)
+        print("filterRed(self, '%s', %s)" % (request, args))
         if request == 'advance':
         if request == 'advance':
             return 'Green'
             return 'Green'
         return self.defaultFilter(request, args)
         return self.defaultFilter(request, args)
 
 
     def exitRed(self):
     def exitRed(self):
-        print "exitRed(self, '%s', '%s')" % (self.oldState, self.newState)
+        print("exitRed(self, '%s', '%s')" % (self.oldState, self.newState))
 
 
     def enterYellow(self):
     def enterYellow(self):
-        print "enterYellow(self, '%s', '%s')" % (self.oldState, self.newState)
+        print("enterYellow(self, '%s', '%s')" % (self.oldState, self.newState))
 
 
     def filterYellow(self, request, args):
     def filterYellow(self, request, args):
-        print "filterYellow(self, '%s', %s)" % (request, args)
+        print("filterYellow(self, '%s', %s)" % (request, args))
         if request == 'advance':
         if request == 'advance':
             return 'Red'
             return 'Red'
         return self.defaultFilter(request, args)
         return self.defaultFilter(request, args)
 
 
     def exitYellow(self):
     def exitYellow(self):
-        print "exitYellow(self, '%s', '%s')" % (self.oldState, self.newState)
+        print("exitYellow(self, '%s', '%s')" % (self.oldState, self.newState))
 
 
     def enterGreen(self):
     def enterGreen(self):
-        print "enterGreen(self, '%s', '%s')" % (self.oldState, self.newState)
+        print("enterGreen(self, '%s', '%s')" % (self.oldState, self.newState))
 
 
     def filterGreen(self, request, args):
     def filterGreen(self, request, args):
-        print "filterGreen(self, '%s', %s)" % (request, args)
+        print("filterGreen(self, '%s', %s)" % (request, args))
         if request == 'advance':
         if request == 'advance':
             return 'Yellow'
             return 'Yellow'
         return self.defaultFilter(request, args)
         return self.defaultFilter(request, args)
 
 
     def exitGreen(self):
     def exitGreen(self):
-        print "exitGreen(self, '%s', '%s')" % (self.oldState, self.newState)
+        print("exitGreen(self, '%s', '%s')" % (self.oldState, self.newState))
 
 
 
 
 class ToonEyes(FSM.FSM):
 class ToonEyes(FSM.FSM):
@@ -88,14 +87,14 @@ class ToonEyes(FSM.FSM):
     def defaultFilter(self, request, args):
     def defaultFilter(self, request, args):
         # The default filter accepts any direct state request (these
         # The default filter accepts any direct state request (these
         # start with a capital letter).
         # start with a capital letter).
-        if request[0] in string.uppercase:
+        if request[0].isupper():
             return request
             return request
 
 
         # Unexpected command requests are quietly ignored.
         # Unexpected command requests are quietly ignored.
         return None
         return None
 
 
     def enterOpen(self):
     def enterOpen(self):
-        print "swap in eyes open model"
+        print("swap in eyes open model")
 
 
     def filterOpen(self, request, args):
     def filterOpen(self, request, args):
         if request == 'blink':
         if request == 'blink':
@@ -109,7 +108,7 @@ class ToonEyes(FSM.FSM):
         return Task.done
         return Task.done
 
 
     def enterClosed(self):
     def enterClosed(self):
-        print "swap in eyes closed model"
+        print("swap in eyes closed model")
 
 
     def filterClosed(self, request, args):
     def filterClosed(self, request, args):
         if request == 'unblink':
         if request == 'unblink':
@@ -117,7 +116,7 @@ class ToonEyes(FSM.FSM):
         return self.defaultFilter(request, args)
         return self.defaultFilter(request, args)
 
 
     def enterSurprised(self):
     def enterSurprised(self):
-        print "swap in eyes surprised model"
+        print("swap in eyes surprised model")
 
 
     def enterOff(self):
     def enterOff(self):
         taskMgr.remove(self.__unblinkName)
         taskMgr.remove(self.__unblinkName)

+ 2 - 2
direct/src/fsm/State.py

@@ -199,7 +199,7 @@ class State(DirectObject):
         self.__enterChildren(argList)
         self.__enterChildren(argList)
 
 
         if (self.__enterFunc != None):
         if (self.__enterFunc != None):
-            apply(self.__enterFunc, argList)
+            self.__enterFunc(*argList)
 
 
     def exit(self, argList=[]):
     def exit(self, argList=[]):
         """
         """
@@ -210,7 +210,7 @@ class State(DirectObject):
 
 
         # call exit function if it exists
         # call exit function if it exists
         if (self.__exitFunc != None):
         if (self.__exitFunc != None):
-            apply(self.__exitFunc, argList)
+            self.__exitFunc(*argList)
 
 
     def __str__(self):
     def __str__(self):
         return "State: name = %s, enter = %s, exit = %s, trans = %s, children = %s" %\
         return "State: name = %s, enter = %s, exit = %s, trans = %s, children = %s" %\

+ 0 - 1
direct/src/fsm/StateData.py

@@ -5,7 +5,6 @@ __all__ = ['StateData']
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
 
 
-from direct.directnotify import DirectNotifyGlobal
 
 
 class StateData(DirectObject):
 class StateData(DirectObject):
     """
     """

+ 5 - 6
direct/src/fsm/StatePush.py

@@ -16,8 +16,8 @@ class PushesStateChanges:
 
 
     def destroy(self):
     def destroy(self):
         if len(self._subscribers) != 0:
         if len(self._subscribers) != 0:
-            raise '%s object still has subscribers in destroy(): %s' % (
-                self.__class__.__name__, self._subscribers)
+            raise Exception('%s object still has subscribers in destroy(): %s' % (
+                self.__class__.__name__, self._subscribers))
         del self._subscribers
         del self._subscribers
         del self._value
         del self._value
 
 
@@ -154,7 +154,7 @@ class ReceivesMultipleStateChanges:
         self._source2key = {}
         self._source2key = {}
 
 
     def destroy(self):
     def destroy(self):
-        keys = self._key2source.keys()
+        keys = list(self._key2source.keys())
         for key in keys:
         for key in keys:
             self._unsubscribe(key)
             self._unsubscribe(key)
         del self._key2source
         del self._key2source
@@ -202,15 +202,14 @@ class FunctionCall(ReceivesMultipleStateChanges, PushesStateChanges):
         # the value of arguments that push state
         # the value of arguments that push state
         self._bakedArgs = []
         self._bakedArgs = []
         self._bakedKargs = {}
         self._bakedKargs = {}
-        for i in xrange(len(self._args)):
+        for i, arg in enumerate(self._args):
             key = i
             key = i
-            arg = self._args[i]
             if isinstance(arg, PushesStateChanges):
             if isinstance(arg, PushesStateChanges):
                 self._bakedArgs.append(arg.getState())
                 self._bakedArgs.append(arg.getState())
                 self._subscribeTo(arg, key)
                 self._subscribeTo(arg, key)
             else:
             else:
                 self._bakedArgs.append(self._args[i])
                 self._bakedArgs.append(self._args[i])
-        for key, arg in self._kArgs.iteritems():
+        for key, arg in self._kArgs.items():
             if isinstance(arg, PushesStateChanges):
             if isinstance(arg, PushesStateChanges):
                 self._bakedKargs[key] = arg.getState()
                 self._bakedKargs[key] = arg.getState()
                 self._subscribeTo(arg, key)
                 self._subscribeTo(arg, key)

+ 3 - 3
direct/src/gui/DirectButton.py

@@ -3,8 +3,8 @@
 __all__ = ['DirectButton']
 __all__ = ['DirectButton']
 
 
 from panda3d.core import *
 from panda3d.core import *
-import DirectGuiGlobals as DGG
-from DirectFrame import *
+from . import DirectGuiGlobals as DGG
+from .DirectFrame import *
 
 
 class DirectButton(DirectFrame):
 class DirectButton(DirectFrame):
     """
     """
@@ -100,7 +100,7 @@ class DirectButton(DirectFrame):
     def commandFunc(self, event):
     def commandFunc(self, event):
         if self['command']:
         if self['command']:
             # Pass any extra args to command
             # Pass any extra args to command
-            apply(self['command'], self['extraArgs'])
+            self['command'](*self['extraArgs'])
 
 
     def setClickSound(self):
     def setClickSound(self):
         clickSound = self['clickSound']
         clickSound = self['clickSound']

+ 1 - 1
direct/src/gui/DirectCheckBox.py

@@ -55,5 +55,5 @@ class DirectCheckBox(DirectButton):
 
 
         if self['command']:
         if self['command']:
             # Pass any extra args to command
             # Pass any extra args to command
-            apply(self['command'], [self['isChecked']] + self['extraArgs'])
+            self['command'](*[self['isChecked']] + self['extraArgs'])
 
 

+ 3 - 3
direct/src/gui/DirectCheckButton.py

@@ -3,8 +3,8 @@
 __all__ = ['DirectCheckButton']
 __all__ = ['DirectCheckButton']
 
 
 from panda3d.core import *
 from panda3d.core import *
-from DirectButton import *
-from DirectLabel import *
+from .DirectButton import *
+from .DirectLabel import *
 
 
 class DirectCheckButton(DirectButton):
 class DirectCheckButton(DirectButton):
     """
     """
@@ -169,7 +169,7 @@ class DirectCheckButton(DirectButton):
 
 
         if self['command']:
         if self['command']:
             # Pass any extra args to command
             # Pass any extra args to command
-            apply(self['command'], [self['indicatorValue']] + self['extraArgs'])
+            self['command'](*[self['indicatorValue']] + self['extraArgs'])
 
 
     def setIndicatorValue(self):
     def setIndicatorValue(self):
         self.component('indicator').guiItem.setState(self['indicatorValue'])
         self.component('indicator').guiItem.setState(self['indicatorValue'])

+ 9 - 9
direct/src/gui/DirectDialog.py

@@ -3,9 +3,9 @@
 __all__ = ['findDialog', 'cleanupDialog', 'DirectDialog', 'OkDialog', 'OkCancelDialog', 'YesNoDialog', 'YesNoCancelDialog', 'RetryCancelDialog']
 __all__ = ['findDialog', 'cleanupDialog', 'DirectDialog', 'OkDialog', 'OkCancelDialog', 'YesNoDialog', 'YesNoCancelDialog', 'RetryCancelDialog']
 
 
 from panda3d.core import *
 from panda3d.core import *
-import DirectGuiGlobals as DGG
-from DirectFrame import *
-from DirectButton import *
+from . import DirectGuiGlobals as DGG
+from .DirectFrame import *
+from .DirectButton import *
 import types
 import types
 
 
 def findDialog(uniqueName):
 def findDialog(uniqueName):
@@ -186,8 +186,8 @@ class DirectDialog(DirectFrame):
         bindList = zip(self.buttonList, self['buttonHotKeyList'],
         bindList = zip(self.buttonList, self['buttonHotKeyList'],
                        self['buttonValueList'])
                        self['buttonValueList'])
         for button, hotKey, value in bindList:
         for button, hotKey, value in bindList:
-            if ((type(hotKey) == types.ListType) or
-                (type(hotKey) == types.TupleType)):
+            if ((type(hotKey) == list) or
+                (type(hotKey) == tuple)):
                 for key in hotKey:
                 for key in hotKey:
                     button.bind('press-' + key + '-', self.buttonCommand,
                     button.bind('press-' + key + '-', self.buttonCommand,
                                 extraArgs = [value])
                                 extraArgs = [value])
@@ -274,12 +274,12 @@ class DirectDialog(DirectFrame):
             scale = self['button_scale']
             scale = self['button_scale']
             # Can either be a Vec3 or a tuple of 3 values
             # Can either be a Vec3 or a tuple of 3 values
             if (isinstance(scale, Vec3) or
             if (isinstance(scale, Vec3) or
-                (type(scale) == types.ListType) or
-                (type(scale) == types.TupleType)):
+                (type(scale) == list) or
+                (type(scale) == tuple)):
                 sx = scale[0]
                 sx = scale[0]
                 sz = scale[2]
                 sz = scale[2]
-            elif ((type(scale) == types.IntType) or
-                  (type(scale) == types.FloatType)):
+            elif ((type(scale) == int) or
+                  (type(scale) == float)):
                 sx = sz = scale
                 sx = sz = scale
             else:
             else:
                 sx = sz = 1
                 sx = sz = 1

+ 21 - 17
direct/src/gui/DirectEntry.py

@@ -3,10 +3,10 @@
 __all__ = ['DirectEntry']
 __all__ = ['DirectEntry']
 
 
 from panda3d.core import *
 from panda3d.core import *
-import DirectGuiGlobals as DGG
-from DirectFrame import *
-from OnscreenText import OnscreenText
-import string,types
+from . import DirectGuiGlobals as DGG
+from .DirectFrame import *
+from .OnscreenText import OnscreenText
+import sys
 # import this to make sure it gets pulled into the publish
 # import this to make sure it gets pulled into the publish
 import encodings.utf_8
 import encodings.utf_8
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
@@ -181,12 +181,12 @@ class DirectEntry(DirectFrame):
     def commandFunc(self, event):
     def commandFunc(self, event):
         if self['command']:
         if self['command']:
             # Pass any extra args to command
             # Pass any extra args to command
-            apply(self['command'], [self.get()] + self['extraArgs'])
+            self['command'](*[self.get()] + self['extraArgs'])
 
 
     def failedCommandFunc(self, event):
     def failedCommandFunc(self, event):
         if self['failedCommand']:
         if self['failedCommand']:
             # Pass any extra args
             # Pass any extra args
-            apply(self['failedCommand'], [self.get()] + self['failedExtraArgs'])
+            self['failedCommand'](*[self.get()] + self['failedExtraArgs'])
 
 
     def autoCapitalizeFunc(self):
     def autoCapitalizeFunc(self):
         if self['autoCapitalize']:
         if self['autoCapitalize']:
@@ -198,7 +198,7 @@ class DirectEntry(DirectFrame):
 
 
     def focusInCommandFunc(self):
     def focusInCommandFunc(self):
         if self['focusInCommand']:
         if self['focusInCommand']:
-            apply(self['focusInCommand'], self['focusInExtraArgs'])
+            self['focusInCommand'](*self['focusInExtraArgs'])
         if self['autoCapitalize']:
         if self['autoCapitalize']:
             self.accept(self.guiItem.getTypeEvent(), self._handleTyping)
             self.accept(self.guiItem.getTypeEvent(), self._handleTyping)
             self.accept(self.guiItem.getEraseEvent(), self._handleErasing)
             self.accept(self.guiItem.getEraseEvent(), self._handleErasing)
@@ -216,14 +216,13 @@ class DirectEntry(DirectFrame):
         wordSoFar = ''
         wordSoFar = ''
         # track whether the previous character was part of a word or not
         # track whether the previous character was part of a word or not
         wasNonWordChar = True
         wasNonWordChar = True
-        for i in xrange(len(name)):
-            character = name[i]
+        for i, character in enumerate(name):
             # test to see if we are between words
             # test to see if we are between words
             # - Count characters that can't be capitalized as a break between words
             # - Count characters that can't be capitalized as a break between words
             #   This assumes that string.lower and string.upper will return different
             #   This assumes that string.lower and string.upper will return different
             #   values for all unicode letters.
             #   values for all unicode letters.
             # - Don't count apostrophes as a break between words
             # - Don't count apostrophes as a break between words
-            if ((string.lower(character) == string.upper(character)) and (character != "'")):
+            if character.lower() == character.upper() and character != "'":
                 # we are between words
                 # we are between words
                 wordSoFar = ''
                 wordSoFar = ''
                 wasNonWordChar = True
                 wasNonWordChar = True
@@ -232,7 +231,7 @@ class DirectEntry(DirectFrame):
                 if wasNonWordChar:
                 if wasNonWordChar:
                     # first letter of a word, capitalize it unconditionally;
                     # first letter of a word, capitalize it unconditionally;
                     capitalize = True
                     capitalize = True
-                elif (character == string.upper(character) and
+                elif (character == character.upper() and
                       len(self.autoCapitalizeAllowPrefixes) and
                       len(self.autoCapitalizeAllowPrefixes) and
                       wordSoFar in self.autoCapitalizeAllowPrefixes):
                       wordSoFar in self.autoCapitalizeAllowPrefixes):
                     # first letter after one of the prefixes, allow it to be capitalized
                     # first letter after one of the prefixes, allow it to be capitalized
@@ -243,9 +242,9 @@ class DirectEntry(DirectFrame):
                     capitalize = True
                     capitalize = True
                 if capitalize:
                 if capitalize:
                     # allow this letter to remain capitalized
                     # allow this letter to remain capitalized
-                    character = string.upper(character)
+                    character = character.upper()
                 else:
                 else:
-                    character = string.lower(character)
+                    character = character.lower()
                 wordSoFar += character
                 wordSoFar += character
                 wasNonWordChar = False
                 wasNonWordChar = False
             capName += character
             capName += character
@@ -253,7 +252,7 @@ class DirectEntry(DirectFrame):
 
 
     def focusOutCommandFunc(self):
     def focusOutCommandFunc(self):
         if self['focusOutCommand']:
         if self['focusOutCommand']:
-            apply(self['focusOutCommand'], self['focusOutExtraArgs'])
+            self['focusOutCommand'](*self['focusOutExtraArgs'])
         if self['autoCapitalize']:
         if self['autoCapitalize']:
             self.ignore(self.guiItem.getTypeEvent())
             self.ignore(self.guiItem.getTypeEvent())
             self.ignore(self.guiItem.getEraseEvent())
             self.ignore(self.guiItem.getEraseEvent())
@@ -263,11 +262,16 @@ class DirectEntry(DirectFrame):
         does not change the current cursor position.  Also see
         does not change the current cursor position.  Also see
         enterText(). """
         enterText(). """
 
 
-        self.unicodeText = isinstance(text, types.UnicodeType)
-        if self.unicodeText:
+        if sys.version_info >= (3, 0):
+            assert not isinstance(text, bytes)
+            self.unicodeText = True
             self.guiItem.setWtext(text)
             self.guiItem.setWtext(text)
         else:
         else:
-            self.guiItem.setText(text)
+            self.unicodeText = isinstance(text, unicode)
+            if self.unicodeText:
+                self.guiItem.setWtext(text)
+            else:
+                self.guiItem.setText(text)
 
 
     def get(self, plain = False):
     def get(self, plain = False):
         """ Returns the text currently showing in the typable region.
         """ Returns the text currently showing in the typable region.

+ 4 - 4
direct/src/gui/DirectEntryScroll.py

@@ -1,10 +1,10 @@
 __all__ = ['DirectEntryScroll']
 __all__ = ['DirectEntryScroll']
 
 
 from panda3d.core import *
 from panda3d.core import *
-import DirectGuiGlobals as DGG
-from DirectScrolledFrame import *
-from DirectFrame import *
-from DirectEntry import *
+from . import DirectGuiGlobals as DGG
+from .DirectScrolledFrame import *
+from .DirectFrame import *
+from .DirectEntry import *
 
 
 class DirectEntryScroll(DirectFrame):
 class DirectEntryScroll(DirectFrame):
     def __init__(self, entry, parent = None, **kw):
     def __init__(self, entry, parent = None, **kw):

+ 17 - 11
direct/src/gui/DirectFrame.py

@@ -3,11 +3,17 @@
 __all__ = ['DirectFrame']
 __all__ = ['DirectFrame']
 
 
 from panda3d.core import *
 from panda3d.core import *
-import DirectGuiGlobals as DGG
-from DirectGuiBase import *
-from OnscreenImage import OnscreenImage
-from OnscreenGeom import OnscreenGeom
-import types
+from . import DirectGuiGlobals as DGG
+from .DirectGuiBase import *
+from .OnscreenImage import OnscreenImage
+from .OnscreenGeom import OnscreenGeom
+import sys
+
+if sys.version_info >= (3, 0):
+    stringTypes = (str,)
+else:
+    stringTypes = (str, unicode)
+
 
 
 class DirectFrame(DirectGuiWidget):
 class DirectFrame(DirectGuiWidget):
     DefDynGroups = ('text', 'geom', 'image')
     DefDynGroups = ('text', 'geom', 'image')
@@ -54,7 +60,7 @@ class DirectFrame(DirectGuiWidget):
         # Determine if user passed in single string or a sequence
         # Determine if user passed in single string or a sequence
         if self['text'] == None:
         if self['text'] == None:
             textList = (None,) * self['numStates']
             textList = (None,) * self['numStates']
-        elif isinstance(self['text'], types.StringTypes):
+        elif isinstance(self['text'], stringTypes):
             # If just passing in a single string, make a tuple out of it
             # If just passing in a single string, make a tuple out of it
             textList = (self['text'],) * self['numStates']
             textList = (self['text'],) * self['numStates']
         else:
         else:
@@ -80,7 +86,7 @@ class DirectFrame(DirectGuiWidget):
                 if text == None:
                 if text == None:
                     return
                     return
                 else:
                 else:
-                    from OnscreenText import OnscreenText
+                    from .OnscreenText import OnscreenText
                     self.createcomponent(
                     self.createcomponent(
                         component, (), 'text',
                         component, (), 'text',
                         OnscreenText,
                         OnscreenText,
@@ -97,7 +103,7 @@ class DirectFrame(DirectGuiWidget):
             # Passed in None
             # Passed in None
             geomList = (None,) * self['numStates']
             geomList = (None,) * self['numStates']
         elif isinstance(geom, NodePath) or \
         elif isinstance(geom, NodePath) or \
-             isinstance(geom, types.StringTypes):
+             isinstance(geom, stringTypes):
             # Passed in a single node path, make a tuple out of it
             # Passed in a single node path, make a tuple out of it
             geomList = (geom,) * self['numStates']
             geomList = (geom,) * self['numStates']
         else:
         else:
@@ -139,14 +145,14 @@ class DirectFrame(DirectGuiWidget):
             imageList = (None,) * self['numStates']
             imageList = (None,) * self['numStates']
         elif isinstance(arg, NodePath) or \
         elif isinstance(arg, NodePath) or \
              isinstance(arg, Texture) or \
              isinstance(arg, Texture) or \
-             isinstance(arg, types.StringTypes):
+             isinstance(arg, stringTypes):
             # Passed in a single node path, make a tuple out of it
             # Passed in a single node path, make a tuple out of it
             imageList = (arg,) * self['numStates']
             imageList = (arg,) * self['numStates']
         else:
         else:
             # Otherwise, hope that the user has passed in a tuple/list
             # Otherwise, hope that the user has passed in a tuple/list
             if ((len(arg) == 2) and
             if ((len(arg) == 2) and
-                isinstance(arg[0], types.StringTypes) and
-                isinstance(arg[1], types.StringTypes)):
+                isinstance(arg[0], stringTypes) and
+                isinstance(arg[1], stringTypes)):
                 # Its a model/node pair of strings
                 # Its a model/node pair of strings
                 imageList = (arg,) * self['numStates']
                 imageList = (arg,) * self['numStates']
             else:
             else:

+ 19 - 19
direct/src/gui/DirectGui.py

@@ -1,9 +1,9 @@
-"""Undocumented Module"""
+""" Imports all of the DirectGUI classes. """
 
 
-import DirectGuiGlobals as DGG
-from OnscreenText import *
-from OnscreenGeom import *
-from OnscreenImage import *
+from . import DirectGuiGlobals as DGG
+from .OnscreenText import *
+from .OnscreenGeom import *
+from .OnscreenImage import *
 
 
 # MPG DirectStart should call this?
 # MPG DirectStart should call this?
 # Set up default font
 # Set up default font
@@ -12,17 +12,17 @@ from OnscreenImage import *
 #    PGItem.getTextNode().setFont(defaultFont)
 #    PGItem.getTextNode().setFont(defaultFont)
 
 
 # Direct Gui Classes
 # Direct Gui Classes
-from DirectFrame import *
-from DirectButton import *
-from DirectEntry import *
-from DirectEntryScroll import *
-from DirectLabel import *
-from DirectScrolledList import *
-from DirectDialog import *
-from DirectWaitBar import *
-from DirectSlider import *
-from DirectScrollBar import *
-from DirectScrolledFrame import *
-from DirectCheckButton import *
-from DirectOptionMenu import *
-from DirectRadioButton import *
+from .DirectFrame import *
+from .DirectButton import *
+from .DirectEntry import *
+from .DirectEntryScroll import *
+from .DirectLabel import *
+from .DirectScrolledList import *
+from .DirectDialog import *
+from .DirectWaitBar import *
+from .DirectSlider import *
+from .DirectScrollBar import *
+from .DirectScrolledFrame import *
+from .DirectCheckButton import *
+from .DirectOptionMenu import *
+from .DirectRadioButton import *

+ 22 - 23
direct/src/gui/DirectGuiBase.py

@@ -5,14 +5,13 @@ __all__ = ['DirectGuiBase', 'DirectGuiWidget']
 
 
 from panda3d.core import *
 from panda3d.core import *
 from panda3d.direct import get_config_showbase
 from panda3d.direct import get_config_showbase
-import DirectGuiGlobals as DGG
-from OnscreenText import *
-from OnscreenGeom import *
-from OnscreenImage import *
+from . import DirectGuiGlobals as DGG
+from .OnscreenText import *
+from .OnscreenGeom import *
+from .OnscreenImage import *
 from direct.directtools.DirectUtil import ROUND_TO
 from direct.directtools.DirectUtil import ROUND_TO
 from direct.showbase import DirectObject
 from direct.showbase import DirectObject
 from direct.task import Task
 from direct.task import Task
-import types
 
 
 guiObjectCollector = PStatCollector("Client::GuiObjects")
 guiObjectCollector = PStatCollector("Client::GuiObjects")
 
 
@@ -243,7 +242,7 @@ class DirectGuiBase(DirectObject.DirectObject):
             # Now check if anything is left over
             # Now check if anything is left over
             unusedOptions = []
             unusedOptions = []
             keywords = self._constructorKeywords
             keywords = self._constructorKeywords
-            for name in keywords.keys():
+            for name in keywords:
                 used = keywords[name][1]
                 used = keywords[name][1]
                 if not used:
                 if not used:
                     # This keyword argument has not been used.  If it
                     # This keyword argument has not been used.  If it
@@ -350,8 +349,8 @@ class DirectGuiBase(DirectObject.DirectObject):
                 # This is one of the options of this gui item.
                 # This is one of the options of this gui item.
                 # Check it is an initialisation option.
                 # Check it is an initialisation option.
                 if optionInfo[option][FUNCTION] is DGG.INITOPT:
                 if optionInfo[option][FUNCTION] is DGG.INITOPT:
-                    print 'Cannot configure initialisation option "' \
-                          + option + '" for ' + self.__class__.__name__
+                    print('Cannot configure initialisation option "' \
+                          + option + '" for ' + self.__class__.__name__)
                     break
                     break
                     #raise KeyError, \
                     #raise KeyError, \
                 #           'Cannot configure initialisation option "' \
                 #           'Cannot configure initialisation option "' \
@@ -506,7 +505,7 @@ class DirectGuiBase(DirectObject.DirectObject):
             # with corresponding keys beginning with *component*.
             # with corresponding keys beginning with *component*.
             alias = alias + '_'
             alias = alias + '_'
             aliasLen = len(alias)
             aliasLen = len(alias)
-            for option in keywords.keys():
+            for option in keywords:
                 if len(option) > aliasLen and option[:aliasLen] == alias:
                 if len(option) > aliasLen and option[:aliasLen] == alias:
                     newkey = component + '_' + option[aliasLen:]
                     newkey = component + '_' + option[aliasLen:]
                     keywords[newkey] = keywords[option]
                     keywords[newkey] = keywords[option]
@@ -519,7 +518,7 @@ class DirectGuiBase(DirectObject.DirectObject):
         # First, walk through the option list looking for arguments
         # First, walk through the option list looking for arguments
         # than refer to this component's group.
         # than refer to this component's group.
 
 
-        for option in keywords.keys():
+        for option in keywords:
             # Check if this keyword argument refers to the group
             # Check if this keyword argument refers to the group
             # of this component.  If so, add this to the options
             # of this component.  If so, add this to the options
             # to use when constructing the widget.  Mark the
             # to use when constructing the widget.  Mark the
@@ -538,7 +537,7 @@ class DirectGuiBase(DirectObject.DirectObject):
         # specific than the group arguments, above; we walk through
         # specific than the group arguments, above; we walk through
         # the list afterwards so they will override.
         # the list afterwards so they will override.
 
 
-        for option in keywords.keys():
+        for option in keywords:
             if len(option) > nameLen and option[:nameLen] == componentPrefix:
             if len(option) > nameLen and option[:nameLen] == componentPrefix:
                 # The keyword argument refers to this component, so add
                 # The keyword argument refers to this component, so add
                 # this to the options to use when constructing the widget.
                 # this to the options to use when constructing the widget.
@@ -550,7 +549,7 @@ class DirectGuiBase(DirectObject.DirectObject):
         if widgetClass is None:
         if widgetClass is None:
             return None
             return None
         # Get arguments for widget constructor
         # Get arguments for widget constructor
-        if len(widgetArgs) == 1 and type(widgetArgs[0]) == types.TupleType:
+        if len(widgetArgs) == 1 and type(widgetArgs[0]) == tuple:
             # Arguments to the constructor can be specified as either
             # Arguments to the constructor can be specified as either
             # multiple trailing arguments to createcomponent() or as a
             # multiple trailing arguments to createcomponent() or as a
             # single tuple argument.
             # single tuple argument.
@@ -600,7 +599,7 @@ class DirectGuiBase(DirectObject.DirectObject):
 
 
     def components(self):
     def components(self):
         # Return a list of all components.
         # Return a list of all components.
-        names = self.__componentInfo.keys()
+        names = list(self.__componentInfo.keys())
         names.sort()
         names.sort()
         return names
         return names
 
 
@@ -631,8 +630,8 @@ class DirectGuiBase(DirectObject.DirectObject):
         gEvent = event + self.guiId
         gEvent = event + self.guiId
         if get_config_showbase().GetBool('debug-directgui-msgs', False):
         if get_config_showbase().GetBool('debug-directgui-msgs', False):
             from direct.showbase.PythonUtil import StackTrace
             from direct.showbase.PythonUtil import StackTrace
-            print gEvent
-            print StackTrace()
+            print(gEvent)
+            print(StackTrace())
         self.accept(gEvent, command, extraArgs = extraArgs)
         self.accept(gEvent, command, extraArgs = extraArgs)
 
 
     def unbind(self, event):
     def unbind(self, event):
@@ -944,7 +943,7 @@ class DirectGuiWidget(DirectGuiBase, NodePath):
         # Convert None, and string arguments
         # Convert None, and string arguments
         if relief == None:
         if relief == None:
             relief = PGFrameStyle.TNone
             relief = PGFrameStyle.TNone
-        elif isinstance(relief, types.StringTypes):
+        elif isinstance(relief, str):
             # Convert string to frame style int
             # Convert string to frame style int
             relief = DGG.FrameStyleDict[relief]
             relief = DGG.FrameStyleDict[relief]
         # Set style
         # Set style
@@ -969,8 +968,8 @@ class DirectGuiWidget(DirectGuiBase, NodePath):
     def setFrameColor(self):
     def setFrameColor(self):
         # this might be a single color or a list of colors
         # this might be a single color or a list of colors
         colors = self['frameColor']
         colors = self['frameColor']
-        if type(colors[0]) == types.IntType or \
-           type(colors[0]) == types.FloatType:
+        if type(colors[0]) == int or \
+           type(colors[0]) == float:
             colors = (colors,)
             colors = (colors,)
         for i in range(self['numStates']):
         for i in range(self['numStates']):
             if i >= len(colors):
             if i >= len(colors):
@@ -985,14 +984,14 @@ class DirectGuiWidget(DirectGuiBase, NodePath):
         textures = self['frameTexture']
         textures = self['frameTexture']
         if textures == None or \
         if textures == None or \
            isinstance(textures, Texture) or \
            isinstance(textures, Texture) or \
-           isinstance(textures, types.StringTypes):
+           isinstance(textures, str):
             textures = (textures,) * self['numStates']
             textures = (textures,) * self['numStates']
         for i in range(self['numStates']):
         for i in range(self['numStates']):
             if i >= len(textures):
             if i >= len(textures):
                 texture = textures[-1]
                 texture = textures[-1]
             else:
             else:
                 texture = textures[i]
                 texture = textures[i]
-            if isinstance(texture, types.StringTypes):
+            if isinstance(texture, str):
                 texture = loader.loadTexture(texture)
                 texture = loader.loadTexture(texture)
             if texture:
             if texture:
                 self.frameStyle[i].setTexture(texture)
                 self.frameStyle[i].setTexture(texture)
@@ -1057,9 +1056,9 @@ class DirectGuiWidget(DirectGuiBase, NodePath):
 
 
     def printConfig(self, indent = 0):
     def printConfig(self, indent = 0):
         space = ' ' * indent
         space = ' ' * indent
-        print space + self.guiId, '-', self.__class__.__name__
-        print space + 'Pos:   %s' % tuple(self.getPos())
-        print space + 'Scale: %s' % tuple(self.getScale())
+        print('%s%s - %s' % (space, self.guiId, self.__class__.__name__))
+        print('%sPos:   %s' % (space, tuple(self.getPos())))
+        print('%sScale: %s' % (space, tuple(self.getScale())))
         # Print out children info
         # Print out children info
         for child in self.getChildren():
         for child in self.getChildren():
             messenger.send(DGG.PRINT + child.getName(), [indent + 2])
             messenger.send(DGG.PRINT + child.getName(), [indent + 2])

+ 9 - 9
direct/src/gui/DirectGuiTest.py

@@ -5,8 +5,8 @@ __all__ = []
 
 
 if __name__ == "__main__":
 if __name__ == "__main__":
     from direct.showbase.ShowBase import ShowBase
     from direct.showbase.ShowBase import ShowBase
-    import DirectGuiGlobals
-    from DirectGui import *
+    from . import DirectGuiGlobals
+    from .DirectGui import *
     #from whrandom import *
     #from whrandom import *
     from random import *
     from random import *
 
 
@@ -18,7 +18,7 @@ if __name__ == "__main__":
 
 
     # Here we specify the button's command
     # Here we specify the button's command
     def dummyCmd(index):
     def dummyCmd(index):
-        print 'Button %d POW!!!!' % index
+        print('Button %d POW!!!!' % index)
 
 
     # Define some commands to bind to enter, exit and click events
     # Define some commands to bind to enter, exit and click events
     def shrink(db):
     def shrink(db):
@@ -94,7 +94,7 @@ if __name__ == "__main__":
 
 
     # DIRECT ENTRY EXAMPLE
     # DIRECT ENTRY EXAMPLE
     def printEntryText(text):
     def printEntryText(text):
-        print 'Text:', text
+        print('Text: %s' % (text))
 
 
     # Here we create an entry, and specify everything up front
     # Here we create an entry, and specify everything up front
     # CALL de1.get() and de1.set('new text') to get and set entry contents
     # CALL de1.get() and de1.set('new text') to get and set entry contents
@@ -110,7 +110,7 @@ if __name__ == "__main__":
 
 
     # DIRECT DIALOG EXAMPLE
     # DIRECT DIALOG EXAMPLE
     def printDialogValue(value):
     def printDialogValue(value):
-        print 'Value:', value
+        print('Value: %s' % (value))
 
 
     simpleDialog = YesNoDialog(text = 'Simple',
     simpleDialog = YesNoDialog(text = 'Simple',
                                command = printDialogValue)
                                command = printDialogValue)
@@ -136,9 +136,9 @@ if __name__ == "__main__":
     # NOTE: There are some utility functions which help you get size
     # NOTE: There are some utility functions which help you get size
     # of a direct gui widget.  These can be used to position and scale an
     # of a direct gui widget.  These can be used to position and scale an
     # image after you've created the entry.  scale = (width/2, 1, height/2)
     # image after you've created the entry.  scale = (width/2, 1, height/2)
-    print 'BOUNDS:', de1.getBounds()
-    print 'WIDTH:', de1.getWidth()
-    print 'HEIGHT:', de1.getHeight()
-    print 'CENTER:', de1.getCenter()
+    print('BOUNDS: %s' % de1.getBounds())
+    print('WIDTH: %s' % de1.getWidth())
+    print('HEIGHT: %s' % de1.getHeight())
+    print('CENTER: %s' % (de1.getCenter(),))
 
 
     base.run()
     base.run()

+ 1 - 1
direct/src/gui/DirectLabel.py

@@ -3,7 +3,7 @@
 __all__ = ['DirectLabel']
 __all__ = ['DirectLabel']
 
 
 from panda3d.core import *
 from panda3d.core import *
-from DirectFrame import *
+from .DirectFrame import *
 
 
 class DirectLabel(DirectFrame):
 class DirectLabel(DirectFrame):
     """
     """

+ 6 - 8
direct/src/gui/DirectOptionMenu.py

@@ -2,13 +2,11 @@
 
 
 __all__ = ['DirectOptionMenu']
 __all__ = ['DirectOptionMenu']
 
 
-import types
-
 from panda3d.core import *
 from panda3d.core import *
-import DirectGuiGlobals as DGG
-from DirectButton import *
-from DirectLabel import *
-from DirectFrame import *
+from . import DirectGuiGlobals as DGG
+from .DirectButton import *
+from .DirectLabel import *
+from .DirectFrame import *
 
 
 class DirectOptionMenu(DirectButton):
 class DirectOptionMenu(DirectButton):
     """
     """
@@ -252,7 +250,7 @@ class DirectOptionMenu(DirectButton):
 
 
     def index(self, index):
     def index(self, index):
         intIndex = None
         intIndex = None
-        if isinstance(index, types.IntType):
+        if isinstance(index, int):
             intIndex = index
             intIndex = index
         elif index in self['items']:
         elif index in self['items']:
             i = 0
             i = 0
@@ -272,7 +270,7 @@ class DirectOptionMenu(DirectButton):
             self['text'] = item
             self['text'] = item
             if fCommand and self['command']:
             if fCommand and self['command']:
                 # Pass any extra args to command
                 # Pass any extra args to command
-                apply(self['command'], [item] + self['extraArgs'])
+                self['command'](*[item] + self['extraArgs'])
 
 
     def get(self):
     def get(self):
         """ Get currently selected item """
         """ Get currently selected item """

+ 4 - 4
direct/src/gui/DirectRadioButton.py

@@ -3,9 +3,9 @@
 __all__ = ['DirectRadioButton']
 __all__ = ['DirectRadioButton']
 
 
 from panda3d.core import *
 from panda3d.core import *
-import DirectGuiGlobals as DGG
-from DirectButton import *
-from DirectLabel import *
+from . import DirectGuiGlobals as DGG
+from .DirectButton import *
+from .DirectLabel import *
 
 
 class DirectRadioButton(DirectButton):
 class DirectRadioButton(DirectButton):
     """
     """
@@ -205,7 +205,7 @@ class DirectRadioButton(DirectButton):
 
 
         if self['command']:
         if self['command']:
             # Pass any extra args to command
             # Pass any extra args to command
-            apply(self['command'], self['extraArgs'])
+            self['command'](*self['extraArgs'])
 
 
     def setOthers(self, others):
     def setOthers(self, others):
         self['others'] = others
         self['others'] = others

+ 4 - 4
direct/src/gui/DirectScrollBar.py

@@ -3,9 +3,9 @@
 __all__ = ['DirectScrollBar']
 __all__ = ['DirectScrollBar']
 
 
 from panda3d.core import *
 from panda3d.core import *
-import DirectGuiGlobals as DGG
-from DirectFrame import *
-from DirectButton import *
+from . import DirectGuiGlobals as DGG
+from .DirectFrame import *
+from .DirectButton import *
 
 
 """
 """
 import DirectScrollBar
 import DirectScrollBar
@@ -164,5 +164,5 @@ class DirectScrollBar(DirectFrame):
         self._optionInfo['value'][DGG._OPT_VALUE] = self.guiItem.getValue()
         self._optionInfo['value'][DGG._OPT_VALUE] = self.guiItem.getValue()
 
 
         if self['command']:
         if self['command']:
-            apply(self['command'], self['extraArgs'])
+            self['command'](*self['extraArgs'])
 
 

+ 4 - 4
direct/src/gui/DirectScrolledFrame.py

@@ -3,9 +3,9 @@
 __all__ = ['DirectScrolledFrame']
 __all__ = ['DirectScrolledFrame']
 
 
 from panda3d.core import *
 from panda3d.core import *
-import DirectGuiGlobals as DGG
-from DirectFrame import *
-from DirectScrollBar import *
+from . import DirectGuiGlobals as DGG
+from .DirectFrame import *
+from .DirectScrollBar import *
 
 
 """
 """
 import DirectScrolledFrame
 import DirectScrolledFrame
@@ -87,7 +87,7 @@ class DirectScrolledFrame(DirectFrame):
 
 
     def commandFunc(self):
     def commandFunc(self):
         if self['command']:
         if self['command']:
-            apply(self['command'], self['extraArgs'])
+            self['command'](*self['extraArgs'])
 
 
     def destroy(self):
     def destroy(self):
         # Destroy children of the canvas
         # Destroy children of the canvas

+ 7 - 8
direct/src/gui/DirectScrolledList.py

@@ -3,11 +3,11 @@
 __all__ = ['DirectScrolledListItem', 'DirectScrolledList']
 __all__ = ['DirectScrolledListItem', 'DirectScrolledList']
 
 
 from panda3d.core import *
 from panda3d.core import *
-import DirectGuiGlobals as DGG
+from . import DirectGuiGlobals as DGG
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
 from direct.task.Task import Task
 from direct.task.Task import Task
-from DirectFrame import *
-from DirectButton import *
+from .DirectFrame import *
+from .DirectButton import *
 import types
 import types
 
 
 
 
@@ -39,7 +39,7 @@ class DirectScrolledListItem(DirectButton):
 
 
     def select(self):
     def select(self):
         assert self.notify.debugStateCall(self)
         assert self.notify.debugStateCall(self)
-        apply(self.nextCommand, self.nextCommandExtraArgs)
+        self.nextCommand(*self.nextCommandExtraArgs)
         self.parent.selectListItem(self)
         self.parent.selectListItem(self)
 
 
 
 
@@ -251,7 +251,7 @@ class DirectScrolledList(DirectFrame):
             if item.__class__.__name__ == 'str':
             if item.__class__.__name__ == 'str':
                 if self['itemMakeFunction']:
                 if self['itemMakeFunction']:
                     # If there is a function to create the item
                     # If there is a function to create the item
-                    item = apply(self['itemMakeFunction'], (item, i, self['itemMakeExtraArgs']))
+                    item = self['itemMakeFunction'](item, i, self['itemMakeExtraArgs'])
                 else:
                 else:
                     item = DirectFrame(text = item,
                     item = DirectFrame(text = item,
                                        text_align = self['itemsAlign'],
                                        text_align = self['itemsAlign'],
@@ -269,7 +269,7 @@ class DirectScrolledList(DirectFrame):
 
 
         if self['command']:
         if self['command']:
             # Pass any extra args to command
             # Pass any extra args to command
-            apply(self['command'], self['extraArgs'])
+            self['command'](*self['extraArgs'])
         return ret
         return ret
 
 
     def makeAllItems(self):
     def makeAllItems(self):
@@ -283,8 +283,7 @@ class DirectScrolledList(DirectFrame):
             if item.__class__.__name__ == 'str':
             if item.__class__.__name__ == 'str':
                 if self['itemMakeFunction']:
                 if self['itemMakeFunction']:
                     # If there is a function to create the item
                     # If there is a function to create the item
-                    item = apply(self['itemMakeFunction'],
-                                 (item, i, self['itemMakeExtraArgs']))
+                    item = self['itemMakeFunction'](item, i, self['itemMakeExtraArgs'])
                 else:
                 else:
                     item = DirectFrame(text = item,
                     item = DirectFrame(text = item,
                                        text_align = self['itemsAlign'],
                                        text_align = self['itemsAlign'],

+ 4 - 4
direct/src/gui/DirectSlider.py

@@ -3,9 +3,9 @@
 __all__ = ['DirectSlider']
 __all__ = ['DirectSlider']
 
 
 from panda3d.core import *
 from panda3d.core import *
-import DirectGuiGlobals as DGG
-from DirectFrame import *
-from DirectButton import *
+from . import DirectGuiGlobals as DGG
+from .DirectFrame import *
+from .DirectButton import *
 
 
 """
 """
 import DirectSlider
 import DirectSlider
@@ -124,4 +124,4 @@ class DirectSlider(DirectFrame):
         self._optionInfo['value'][DGG._OPT_VALUE] = self.guiItem.getValue()
         self._optionInfo['value'][DGG._OPT_VALUE] = self.guiItem.getValue()
 
 
         if self['command']:
         if self['command']:
-            apply(self['command'], self['extraArgs'])
+            self['command'](*self['extraArgs'])

+ 3 - 3
direct/src/gui/DirectWaitBar.py

@@ -3,8 +3,8 @@
 __all__ = ['DirectWaitBar']
 __all__ = ['DirectWaitBar']
 
 
 from panda3d.core import *
 from panda3d.core import *
-import DirectGuiGlobals as DGG
-from DirectFrame import *
+from . import DirectGuiGlobals as DGG
+from .DirectFrame import *
 import types
 import types
 
 
 """
 """
@@ -93,7 +93,7 @@ class DirectWaitBar(DirectFrame):
         """Updates the bar texture, which you can set using bar['barTexture']."""
         """Updates the bar texture, which you can set using bar['barTexture']."""
         # this must be a single texture (or a string).
         # this must be a single texture (or a string).
         texture = self['barTexture']
         texture = self['barTexture']
-        if isinstance(texture, types.StringTypes):
+        if isinstance(texture, str):
             texture = loader.loadTexture(texture)
             texture = loader.loadTexture(texture)
         if texture:
         if texture:
             self.barStyle.setTexture(texture)
             self.barStyle.setTexture(texture)

+ 18 - 18
direct/src/gui/OnscreenGeom.py

@@ -4,7 +4,7 @@ __all__ = ['OnscreenGeom']
 
 
 from panda3d.core import *
 from panda3d.core import *
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
-import types
+
 
 
 class OnscreenGeom(DirectObject, NodePath):
 class OnscreenGeom(DirectObject, NodePath):
     def __init__(self, geom = None,
     def __init__(self, geom = None,
@@ -49,25 +49,25 @@ class OnscreenGeom(DirectObject, NodePath):
 
 
         # Adjust pose
         # Adjust pose
         # Set pos
         # Set pos
-        if (isinstance(pos, types.TupleType) or
-            isinstance(pos, types.ListType)):
-            apply(self.setPos, pos)
+        if (isinstance(pos, tuple) or
+            isinstance(pos, list)):
+            self.setPos(*pos)
         elif isinstance(pos, VBase3):
         elif isinstance(pos, VBase3):
             self.setPos(pos)
             self.setPos(pos)
         # Hpr
         # Hpr
-        if (isinstance(hpr, types.TupleType) or
-            isinstance(hpr, types.ListType)):
-            apply(self.setHpr, hpr)
+        if (isinstance(hpr, tuple) or
+            isinstance(hpr, list)):
+            self.setHpr(*hpr)
         elif isinstance(hpr, VBase3):
         elif isinstance(hpr, VBase3):
             self.setPos(hpr)
             self.setPos(hpr)
         # Scale
         # Scale
-        if (isinstance(scale, types.TupleType) or
-            isinstance(scale, types.ListType)):
-            apply(self.setScale, scale)
+        if (isinstance(scale, tuple) or
+            isinstance(scale, list)):
+            self.setScale(*scale)
         elif isinstance(scale, VBase3):
         elif isinstance(scale, VBase3):
             self.setPos(scale)
             self.setPos(scale)
-        elif (isinstance(scale, types.FloatType) or
-              isinstance(scale, types.IntType)):
+        elif (isinstance(scale, float) or
+              isinstance(scale, int)):
             self.setScale(scale)
             self.setScale(scale)
 
 
     def setGeom(self, geom,
     def setGeom(self, geom,
@@ -93,7 +93,7 @@ class OnscreenGeom(DirectObject, NodePath):
         # Assign geometry
         # Assign geometry
         if isinstance(geom, NodePath):
         if isinstance(geom, NodePath):
             self.assign(geom.copyTo(parent, sort))
             self.assign(geom.copyTo(parent, sort))
-        elif isinstance(geom, types.StringTypes):
+        elif isinstance(geom, str):
             self.assign(loader.loadModel(geom))
             self.assign(loader.loadModel(geom))
             self.reparentTo(parent, sort)
             self.reparentTo(parent, sort)
 
 
@@ -116,17 +116,17 @@ class OnscreenGeom(DirectObject, NodePath):
                 if (((setter == self.setPos) or
                 if (((setter == self.setPos) or
                      (setter == self.setHpr) or
                      (setter == self.setHpr) or
                      (setter == self.setScale)) and
                      (setter == self.setScale)) and
-                    (isinstance(value, types.TupleType) or
-                     isinstance(value, types.ListType))):
-                    apply(setter, value)
+                    (isinstance(value, tuple) or
+                     isinstance(value, list))):
+                    setter(*value)
                 else:
                 else:
                     setter(value)
                     setter(value)
             except AttributeError:
             except AttributeError:
-                print 'OnscreenText.configure: invalid option:', option
+                print('OnscreenText.configure: invalid option: %s' % option)
 
 
     # Allow index style references
     # Allow index style references
     def __setitem__(self, key, value):
     def __setitem__(self, key, value):
-        apply(self.configure, (), {key: value})
+        self.configure(*(), **{key: value})
 
 
     def cget(self, option):
     def cget(self, option):
         # Get current configuration setting.
         # Get current configuration setting.

Some files were not shown because too many files changed in this diff