tags:

views:

644

answers:

2

Hi All,

I'm trying to compile a pyw file into a pyc without console. When I try a straight compile with it, the result is a pywc file, but it seems that pythonw.exe doesn't register that extension as one of it's files like python.exe does for a pyc.

The result of course is that it has no double click handler when you try to just execute, or if you change the extension to pyc, you get the console.

Does anybody know a way around this issue? Something to the affect of a .pyc with no console?

Thanks!

Update: Since running this through execfile or by double clicking on the icon in windows soesn't generate a compiled version of this file, I start python in command line, then :

import py_compile
py_compile.compile("[FileName].pyw")

This is where I get the .pywc extension from. My Python version is 2.5.4

+1  A: 

You can use the FTYPE and ASSOC commands to associate .pywc files with pythonw.exe.

ASSOC is used to associate an extension with a file type, and FTYPE associates a file type with the command used to open it. The following commands show existing assocations on my machine:

C:\Python26>assoc .py
.py=Python.File

C:\Python26>assoc .pyc
.pyc=Python.CompiledFile

C:\Python26>assoc .pyw
.pyw=Python.NoConFile

C:\Python26>assoc .pywc
File association not found for extension .pywc

These commands show what programs the extensions are associated with through their file types:

C:\Python26>ftype Python.CompiledFile
Python.CompiledFile="C:\Python26\python.exe" "%1" %*

C:\Python26>ftype Python.NoConFile
Python.NoConFile="C:\Python26\pythonw.exe" "%1" %*

So it looks like you could just associate .pywc files with Python.NoConFile like this:

assoc .pywc=Python.NoConFile
Todd
This may be useful if I can't find an alternative, but I really don't want to have to set the associations.
Fry
Okay, but something like this is how the three existing assocations are set for you to begin with by the Python installer. It can also be done by making registry entries under HKEY_CLASSES, which could be done from a remote machine. It sounds like you're trying to use this method to distribute compiled Python modules to other users, and you don't want to have to make this change on each machine. Is that the case?
Todd
Hi Todd, that is the case, I'd rather edit the file handling on user's machines as little as possible.
Fry
Understood, but it seems it's either one or the other: have them double-click .pyc files and get a console window, or make this one association and have it work the way you want. You technically already change file handling on their machine when you install Python. You could distribute one additional python script that makes this change and have them run that first, then all of your other compiled scripts will work as you wish. Or include it in a logon script or group policy. The main point is that it can be made to do what you want, you just need to choose which way you want to do it.
Todd
A: 

(following a little discussion in the OP's post)

If what you need is provide clients or users with the compiled application in form of *.pyc or *.pyo, and avoid opening the console at the execution, a good option is to leave a *.pyw wrapper that calls the main application.

Let's assume the main application is in main.pyc, and the entry point main, and let's call the wrapper top.pyw, which would typically look like:

# top.pyw file
import main
if __name__ == "__main__":
    import sys
    main.main(*sys.argv[1:])

Your main.py file would then look like this:

# main.py file
"""
Main module documentation (optional)
"""
# import modules

# function and class definitions

def main(*argv):
    # Parses the options (optional)
    import optparse
    parser = optparse.OptionParser(usage="%prog [<options>]\n" + __doc__)
    parser.add_option(...)
    parser.add_option(...)
    opt, args = parser.parse_args(list(argv))
    # Calls the appropriate function:
    my_function(...)

Note also that *.pyc tend to be version-specific. You can check whether the solution above would be compatible with pyInstaller and similar "independent" distribution methods.

Edit => In fact, if you use pyInstaller, you can simply include all your scripts and produce an executable which will be independent of the Python installation, and starts with no console (-w option when you create the specs). You don't even need to use a wrapper or change your extensions. While it will be a larger file, that could be what you were looking for.

Finally, just in case that's where you are headed: if you don't want someone else to extract source code from the compiled bytecode, don't forget that you will need additional precautions. This is called code obfuscation and there are other threads on SO about that (for example this one). Don't hesitate to post a new question if you only come up with old answers on that one, those things can change fast.

RedGlyph