Panda and Python 2.5

No, the problem is this: you have modified your PYTHONPATH environment variable to point at your copy of Python 2.5. This has caused python 2.4 to try to load code out of the Python 2.5 directory, which doesn’t work.

To avoid this problem, either don’t set the PYTHONPATH environment variable like that, or if you must, then use the -E option to python to ignore the PYTHONPATH.

Thanks Josh. That worked although it is a handful to type all of that in at the commandline and get it typed correctly.

An easy workaround for complex command lines is to create a batch file that contains the full command and simply run the batch file. I’ve used such an approach when I could not install Panda3D in the normal location on a Linux system because of conflicts with some shared libraries which used the same names as Panda libs.

On Windows I believe you can just create a text file with the command and change the extension to .bat and then you can run it either from a prompt or by clicking a shortcut.

I think I can help here. :slight_smile:

The trick is to use imp.load_dynamic for loading the Panda3D .dll files. If you place the following file in pandac and add “#import pandac.preload” before any other Panda3D import, then you can use Panda3D with Python 2.5.

pandac/preload.py:

import imp
import os
import sys

modules = [ 'libp3direct',
            'libpandafx',
            'libpanda',
            'libpandaphysics',
            'libpandaskel',
            'libpandaegg',
            'libp3heapq',
            'libpandaexpress',
            ]

for name in modules:

    here = os.path.dirname( __file__ )
    path = os.path.join( here, '../bin/%s.dll' % name )
    path = os.path.normpath( path )

    module = imp.load_dynamic( name, path )

    sys.modules[ name ] = module

Example for how to preload the dll files:

import pandac.preload # <--- required

import direct.directbase.DirectStart
from direct.showbase.DirectObject import DirectObject
from pandac.PandaModules import Vec4
import sys

base.setBackgroundColor( Vec4( 0, 0, 0.3, 1 ) )

np = loader.loadModel( 'models/box.bam' )
np.reparentTo( render )
np.setPos( 0, 6, 0 )

o = DirectObject( )
o.accept( 'escape', sys.exit )

run( )

This evening I compiled Panda3D 1.4.2 for Python 2.5.1, and checked the above script plus three tutorial files (chessboard, roaming ralph, motion trails), and it seems to work fine.

Building Panda3D: makepanda.py crashes a little bit before the end, when creating the content of built/pandac. Reason is that the build process is not able to import the already created dll files in bin directory. But I think it is possible to adapt the build process to import the above preload.py script before this makepanda step.

Another idea: Maybe it is possible to use the Python ihook builtin-module to catch Panda3D dll imports and handle them with imp.load_dynamic. Then we could get rid of this additional preload import too.

enn0x

good work enn0x! I rarely use windows other wise i would help you! But its in every ones interest that python2.5-panda3d runs on window.

So now we need to ask David Rose whether or not he wants to integrate this solution into Panda3D. The other alternative is to split each panda DLL into two parts: the “real code”, and the python wrappers. Rename the python wrappers to PYD.

This solution is a lot easier to implement, but a little hackier.

Thank you. I agree, having two separate files (.pyd for the python wrapper and .dll for the C++ core) would be a better solution, but I guess this would require some work.

I have modified makepanda, and now I can create an installer. It still needs testing though.

And I no longer need this additional import line. The trick has been quite easy again, I simply placed “import preload” in pandac/init.py. I feel a bit silly, but perhaps it has been too late at night yesterday.

I have to run now, and won’t be here tomorrow, but end of this week I will post a detailed building description, and if the installer works fine and people are interested I could upload it to e.g. panda projects.

enn0x

Well, I don’t have any problem philosophically with implementing this somewhat hacky solution to get people going with Python 2.5. We can still plan to do the “right” thing later, but this is a fine stopgap.

Thanks for the excellent research!

David

OK then. I will proceed to integrate this into the distribution. I’ll even upgrade the daily builds to python 2.5. This will probably take several days before I get around to it (finals week, ya know.)

As promised two days ago here are the detailed building instructions. I hope I didn’t forget something:

(1)
Download Panda3D 1.4.2 source code and unpacked to C:\Libraries\panda3d-1.4.2\

(2)
New, clean install of Python 2.5.1 in C:\Programme\Python. Because I already had some dozen Python modules in my old Python 2.5 installation, and I didn’t want to include a messed up Python directory in Panda3D.

(3)
I replaced the Panda3D folder C:\Libraries\panda3d-1.4.2\thirdparty\win-python with the new Python installation.

(4)
From C:\Windows\system32 I copied these two files to C:\Libraries\panda3d-1.4.2\thirdparty\win-python:

  • python25.dll
  • pywintypes25.dll

(5)
Edit C:\Libraries\panda3d-1.4.2\makepanda\makepanda.py:

  • renamed python24.dll to python25.dll.
  • added a line to copy pywintypes25.dll too.
    For details see below.

(6)
Edit C:\Libraries\panda3d-1.4.2\direct\src\ffi\DoGenPyCode.py:

  • added code to create the new file pandac\preload.py.
  • modified code for creation of pandac_init_.py.
  • added some code which preloads the Panda3D dlls before auto-generating the other files in pandac.
    For details see below.

(7)
Run makepanda:
C:\Libraries\panda3d-1.4.2> makepanda\makepanda.bat --everything --installer

Makepanda did run without crash and created an installer (~70M). The only tests I had time to do so far are the tutorials included in Panda3D 1.4.2. I think that the Python 2.5 builds will need a lot of further testing.

enn0x

Modifications in makepanda/makepanda.py:

Line 1885ff:

if (sys.platform == "win32"):
    if (OMIT.count("PYTHON")==0):
        # >>>>>
        CopyFile('built/bin/python25.dll', 'thirdparty/win-python/python25.dll')
        CopyFile('built/bin/pywintypes25.dll', 'thirdparty/win-python/pywintypes25.dll')
        # <<<<<
        CopyTree('built/python', 'thirdparty/win-python')
        ConditionalWriteFile('built/python/panda.pth',"..\n../bin\n")

Modifications in direct\src\ffi\DoGenPyCode.py:

Line 11ff:

import time
# >>>>>
import imp
# <<<<<
from direct.ffi import FFIConstants

Line 237ff:

    # Generate __init__.py
    initFilename = os.path.join(outputCodeDir, '__init__.py')
    init = open(initFilename, 'w')

    # >>>>>
    init.write( 'import preload\n' )
    init.close( )

    # Generate preload script
    preloadCode = '''
import imp
import os
import sys

modules = [ 'libp3direct',
            'libpandafx',
            'libpanda',
            'libpandaphysics',
            'libpandaskel',
            'libpandaegg',
            'libp3heapq',
            'libpandaexpress',
            ]

for name in modules:
    if sys.modules.get( name ): continue

    here = os.path.dirname( __file__ )
    path = os.path.join( here, '../bin/%s.dll' % name )
    path = os.path.normpath( path )

    module = imp.load_dynamic( name, path )

    sys.modules[ name ] = module
'''

    preloadFilename = os.path.join(outputCodeDir, '__init__.py')
    preload = open(initFilename, 'w')
    preload.write( preloadCode )
    preload.close( )
    # <<<<<

    # Generate PandaModules.py

Line 296ff:

    for moduleName in FFIConstants.CodeModuleNameList:
        print 'Importing code library: ' + moduleName

        # >>>>>
        exec('modulePath = os.path.normpath( __file__ + "../../../built/bin/" + moduleName + ".dll" )')
        #exec('modulePath = os.path.abspath( os.getcwd( ) + "/built/bin/" + moduleName + ".dll" )')
        exec('module = imp.load_dynamic( moduleName, modulePath )' )
        #exec('import %s as module' % moduleName)
        # <<<<<

        pandaModules.write('from %sModules import *\n' % (moduleName))

Thank you! I’m actually looking into doing a little simplification in genpycode, as long as I’m digging around in there.

as long as you are digging around there:

maybe: discourse.panda3d.org/viewtopic.php?t=2870

monkey patch to add new properties based on the existing getters and setters?

import pandac.PandaModules as panda

def fix(clsName,cls):
    try: cls.__dict__
    except: return
    #print clsName
    getters = {}
    setters = {}
    for name,fun in cls.__dict__.items():
        if "__" not in name and len(name) > 3:
            if "set" == name[0:3]:
                name = name[3].lower() + name[4:]
                #print "\tset:",name
                setters[name] = fun
            elif "get" == name[0:3]:
                name = name[3].lower() + name[4:]
                #print "\tget:",name
                getters[name] = fun
    for name in getters.keys():
        if name in setters:
            cls.DtoolClassDict[name] = property(getters[name], setters[name])
            del setters[name]
        else:
            cls.DtoolClassDict[name] = property(getters[name])
    for name in setters.keys():
        print name
        cls.DtoolClassDict[name] = property(fset=setters[name])
    globals()[clsName] = cls
     
for clsName,cls in panda.__dict__.items():
    fix(clsName,cls)

so that code like this can be written:

v = Vec3()
v.x = 3
v.y = v.x + 3
v.z += 1

print v
n = NodePath("node path")
n.pos = v
n.hpr = Vec3(30,40,50)

print n.pos, n.hpr , n 

EEEEKKKK! No, PLEASE save me this pythonic stuff.
I’m happy with getters and setters.

pro-rsoft, but they will still be there
you can use your getters and setters and i can be cool with my pythonizm :slight_smile:

Haven’t you done speed comparision yet then? Im sure getters and setters will turn out faster.

If properties will be implemented, it will probably be done in interrogate, not implemented in python.

pro-rsoft, yes you are right getters and setters are faster by about 1-4%
but then why are you using python?

Hello all,

This is my first post to these forums however I have been reading them for a couple of weeks now.

I have been looking for a solution to using python win32 tools with panda3D. I hope to use Active state’s active python for some security stuff with an application I am developing.

My problem however is unrelated to python it has to do with the last stage of enn0x’s tutorial. I had visual c++ 2008 installed and using C:\Libraries\panda3d-1.4.2> makepanda\makepanda.bat --everything --installer gave me an error that it couldn’t find visual studio 2005 or visual studio 2005 express.

Not to worry I uninstalled 2008 and installed 2005. Fixed the error. However noe I get an error “Found VC toolkit”(yay)“, but cannot locate MS Platform SDK” :frowning:

I followed a tutorial here
http://www.codeproject.com/KB/applications/FreeVS2005Win32.aspx?df=100&forumid=343491&exp=0&select=2025409
regarding linking the libraries and what not to VS C++ but… it didn’t help.

Any thoughts?

Robert[/url]

AHAAAA solved it…

I did a find “VCDIR” on the makepanda.py file. Found the line of code

platsdk=GetRegistryKey("SOFTWARE\\Microsoft\\MicrosoftSDK\\InstalledSDKs\\D2FF9F89-8AA2-4373-8A31-C838BF4DBBE1", "Install Dir")

went Hmmmmmmm…

Opened regedit and found that my SDK actually has the value of B44C7E10-89BD-4A32-A3BF-D9D0BC4C9A05 not the one above…

I downloaded the SDK from http://www.microsoft.com/msdownload/platformsdk/sdkupdate/XPSP2FULLInstall.htm

hmm it is building now… I am getting a whole lot of warning C4005’s… we shal see if it works or not…

ok so it is not working as yet. When it says to copy a fresh install of python 2.5.1 into the source win-python, does that mean delete everything in there first, or just over write it?

Also I am using a fresh install of active python so that may be why…

Will try it with plain python 2.5.1 if this build fails… (the first build took nearly an hour (53 mins) but the following ones have only taken 3-5mins…

Robert

(1) Build time

when makepanda starts building Panda3D it creates a ./build directory. A lot of things are copied there, as you can see in the build log. If you change something else than C code (e.g. replace the Python directory) then you should remove the ./build directory by hand before you run makepanda. Otherwise you might get a mix of old and new files, and build errors are bound to happen. I removed ./build every time before building. A full build takes 1-2 hour, depending on hardware.

(2) Active Python

I don’t have Active Python on my computers, but A.F.A.I.K. Active Python is binary compatible with standard Python. I think otherwise we would see extension module downloads which offer both “normal python 25” and “active python 25” versions. So I guess it is ok to RUN Panda3D with Active Python and not standard Python.

By the way: to RUN a Panda3D script you don’t need to use the Python interpreter that is distributed with Panda3D. Every one will do, as long as the major version is the same (2.5.x). Just add a .pth file to the Python interpreter of your choice. About BUILDING with Active Python: don’t know if there are any differences, since never have done this.

Suggestion: build Panda3D with standard Python 2.5.1, and then use it with Active Python 2.5.x

(3) SDK reg key

Well, this is a common problem not related to Panda3D. Just search the web for both keys, and you will find dozens of hits. I don’t know why there are different keys, but perhaps it would be good to check for both keys like this guy does: http://developer.flock.com/wiki/Build_setup_on_MSWin.

Suggestion: build Panda3D without any modifications (that is for Python 2.4), then fix all build problems, remove the ./build directory, and only then modify for Python 2.5, and then build again.

enn0x

BTW, removing the built directory is not necessary if you’re making the kind of change that the makefile understands — ie, editing a source file, or adding a source file, or that sort of thing. It’s only needed if you do something that’s beyond the comprehension of the makefile (ie, switching python versions.)

PS. I hate the way microsoft doesn’t provide a predictable registry location for the SDK. They change it in every SDK release.