2

I'm writing an application that loads byte-compiled *.pyc files under Python 3.3. I am distributing the *.pyc files without their corresponding *.py files to (try to) protect my source code. (Yes, as noted here, trying to deter decompilation by byte-compiling Python isn't the most secure option, but I can always add other code-security measures if I find I need to.)

However, I have found that Python isn't loading the *.pyc files without their original *.py files in place. (According to PEP 3147, the *.pyc files are kept in a subdirectory called __pycache__ in the directory where the *.py file would be. I am following this convention with my own code.)

Under an earlier iteration of my project that used Python 2.7, I byte-compiled the Python sources and placed the generated *.pyc files into the same directory as the *.py files; that worked just fine. Clearly, there is a problem with how Python is finding the __pycache__ folder. What am I doing wrong? (And yes, I have set sys.path appropriately; otherwise it would not be finding the *.py file when I insert it as a debugging measure.)

Community
  • 1
  • 1
wjk
  • 1,219
  • 11
  • 27
  • Do the `.pyc` files thus generated have an extra `.cpython-33.` inserted? If so, you can simply try renaming them to have the same name as the module. [This just worked for me, anyhow.] – DSM Feb 10 '13 at 16:24
  • @DSM: Did not work. Still can't find the module. – wjk Feb 10 '13 at 17:09
  • Hmm. Works on this end -- I'm looking at a `hello, world!` message generated by importing a `fred.pyc` file I copied from `fred.cpython-33.pyc` from a directory `tmp` I added to `sys.path` after removing every other file. – DSM Feb 10 '13 at 17:12
  • 1
    Are you ensuring that both the `__pycache__` directory and its content have appropriate permissions? – Ned Deily Feb 10 '13 at 18:00

2 Answers2

4

From PEP 3147:

If the py source file is missing, the pyc file inside __pycache__ will be ignored. This eliminates the problem of accidental stale pyc file imports.

For backward compatibility, Python will still support pyc-only distributions, however it will only do so when the pyc file lives in the directory where the py file would have been, i.e. not in the __pycache__ directory. pyc file outside of __pycache__ will only be imported if the py source file is missing.

So, if you want to make pyc-only distributions, you will have to put your compiled files in the same place as the .py files would have gone. According to the PEP, compileall has the option of creating this exact layout so you don't have to go copying things out of __pycache__, so check it out.

Community
  • 1
  • 1
nneonneo
  • 171,345
  • 36
  • 312
  • 383
2

I copied the *.pyc file out of the __pycache__ dir and removed .cpython-33 from its filename; Python then found it as expected. Thanks, DSM!

wjk
  • 1,219
  • 11
  • 27