P4python files

I’m running into the irritating problem of installing p4Python on a new setup. Perforce only gives you an MSI, which installs according to some rules of it’s own (not documented, naturally) about where it will find your python.

For whatever reason it never finds my python installs (neither my maya ones nor conventional ones). So I can never install the !*$^(!^#(!( thing. I’ve tried taking apart the MSI with z7ip and extracting it from the command line, but neither of these gives me working pieces.

Does anybody have a good trick to just get p4.py and p4api.pyd without building from scratch? I need a python 2.7 friendly version, which is I believe is 2012.3

Try symlinking to your python install location from the location the installer expects it?

I’m using the p4.py and p4api.pyd that Jason Parks posted on his site for Maya 2014 (using Python 2.7, VS2010). His site currently down but I could rehost them if that’s what you want.

That would be great, thanks

Realized I don’t have any hosting space but gdrive.
p4.py and p4api.pyd
https://drive.google.com/folderview?id=0B5Lo_ykYMO2hdkt2RDZ2RkRGUjA&usp=sharing

We use custom builds of Python 2.6.4 x64 for each game project, and have project-change scripts that reassociate everything with the correct Python build. That includes fixing up registry to think that Python build was actually installed, so extension installers find it. Below is the function I wrote to handle most of those details. It probably won’t run as-is, but it should be clear what it’s doing.

def set_python_file_associations( python_dir ):
    """
    Changes default Python interpreter/file associations in Windows Registry.

    *Arguments:*
        * ``python_dir`` Path to root Python directory to use, ie "C:\Python26"

    *Keyword Arguments:*
        * none

    *Returns:*
        * none

    *Author:*
        * Adam Pletcher, [email][email protected][/email], 7/31/2012 7:35:04 AM
    """

    # Change file associations in registry
    reg_entries = [
        ( r'HKEY_CLASSES_ROOT\Python.CompiledFile\DefaultIcon',                         r'{python_dir}\DLLs\pyc.ico' ),
        ( r'HKEY_CLASSES_ROOT\Python.CompiledFile\shell\open\command',             r'"{python_dir}\python.exe" "%1" %*' ),
        ( r'HKEY_CLASSES_ROOT\Python.File\DefaultIcon',                                    r'{python_dir}\DLLs\py.ico' ),
        ( r'HKEY_CLASSES_ROOT\Python.File\shell\Edit with IDLE\command',            r'"{python_dir}\pythonw.exe" "{python_dir}\Lib\idlelib\idle.pyw" -n -e "%1"' ),
        ( r'HKEY_CLASSES_ROOT\Python.File\shell\open\command',                        r'"{python_dir}\python.exe" "%1" %*' ),
        ( r'HKEY_CLASSES_ROOT\Python.NoConFile\DefaultIcon',                            r'{python_dir}\DLLs\py.ico' ),
        ( r'HKEY_CLASSES_ROOT\Python.NoConFile\shell\Edit with IDLE\command',    r'"{python_dir}\pythonw.exe" "{python_dir}\idlelib\idle.pyw" -n -e "%1"' ),
        ( r'HKEY_CLASSES_ROOT\Python.NoConFile\shell\open\command',                r'"{python_dir}\pythonw.exe" "%1" %*' ),
    ]

    for reg_entry in reg_entries:
        key = reg_entry[ 0 ].rstrip( '\\' )
        value = reg_entry[ 1 ].format( python_dir = python_dir )

        set_registry_value( key, VALUE_DEFAULT, value )

    # Set file associations for .py and .pyc to their respective file types, since this sometimes goes missing.
    proc = subprocess.Popen( 'assoc .py=Python.File', shell = True ).wait( )
    proc = subprocess.Popen( 'assoc .pyw=Python.NoConFile', shell = True ).wait( )

    # Add the new Python path to the system PATH, also via registry.  Requires user to log in again to take effect(?)
    old_path_value = get_registry_value( r'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'Path' )
    old_paths = old_path_value.split( ';' )

    new_paths = [ ]
    old_python_dirs = [ ]

    for old_path in old_paths:
        # If a "python.exe" exists in this dir, it's the old Python path, so add it to list of dirs to omit.
        python_exe = os.path.join( old_path, 'python.exe' )

        if os.path.exists( python_exe ):
            # found it, add to skip list
            old_python_dirs.append( old_path.lower( ) )

    if old_python_dirs:
        # Build new paths list, leaving out any old ones underneath an old python dir
        for old_path in old_paths:
            skip = False

            for old_python_dir in old_python_dirs:
                if old_path.lower( ).startswith( old_python_dir ):
                    skip = True
                    break

            if not skip:
                new_paths.append( old_path )
    else:
        # No changes necessary
        new_paths = old_paths

    # Add new Python dir, if it's not in there already
    if python_dir not in new_paths:
        new_paths.append( python_dir )

    # Add a subdir required by pywin32 extensions
    pywin32_dir = os.path.join( python_dir, 'lib\site-packages\pywin32_system32' )

    if pywin32_dir not in new_paths:
        new_paths.append( pywin32_dir )

    # Add separators
    new_path_value = ';'.join( new_paths )

    if new_path_value == old_path_value:
        # No changes made, return
        return

    # Make it official
    set_registry_value( r'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'Path', new_path_value )

    # Finally, restart Windows Explorer.  This is often required for changes to stick without requiring logging out/in again
    subprocess.Popen( 'taskkill /f /IM explorer.exe', shell = True ).wait( )

    explorer_filename = os.path.join( os.getenv( 'windir' ), 'explorer.exe' )
    subprocess.Popen( explorer_filename, shell = True )

Thanks Adam.

If they just put the two files in a zip archive on their website things would be so much easier… sigh…

Feel free to grab the latest version of p4python available (2015.1.1062785) here, along with other python packages compiled to play nice with Maya 2014-2015-2016 Windows 64 bit, like scipy, numexpr, scikit-learn, etc…

enjoy!