Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compile a .pyw file so it can be run like .pyc without console

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

like image 600
Fry Avatar asked Dec 09 '22 18:12

Fry


1 Answers

(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.

like image 173
RedGlyph Avatar answered Jan 25 '23 23:01

RedGlyph