6

From the python book:

Learning Python. 5th edition, page #727

I read the following:

if Python finds only a byte code file on the search path and no source, it simply loads the byte code directly; this means you can ship a program as just byte code files and avoid sending source

But when attempting the same on Python 3.5, it doesn't work:

~/Python/Module_Test$ cat a.py
a = "abc"
l = [1,2,3]

importing module 'a' created the byte-code file as:

~/Python/Module_Test/__pycache__$ ls
a.cpython-35.pyc

Now I removed the 'a.py' file and from the byte-code directory, I'm importing the module 'a':

~/Python/Module_Test/__pycache__$ python
Python 3.5.2 |Anaconda 4.2.0 (64-bit)| (default, Jul  2 2016, 17:53:06) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named 'a'

I even tried to add the byte-code directory to the search path, still it fails to load the module:

>>> import sys
>>> sys.path.append('/home/pradeep/Python/Module_Test/__pycache__')
>>> import a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named 'a'

What I am doing wrong? Can we import module from the byte code without the source? Is my understanding of the statement of the book wrong?

4
  • I don't use Anaconda, but when using the standard CPython interpreter the bytecode file name is the same as the source file name with a "c" appended, i.e. "a.py" compiles to "a.pyc". Try making a link named "a.pyc" to "a.cpython-35.pyc", or simply rename "a.cpython-35.pyc" to "a.pyc" and see what happens. Commented Nov 24, 2016 at 7:28
  • That's standard Python behavior from what I know @PM2Ring, mangling the name so you can have different bytecode versions depending on interpreter version. Commented Nov 24, 2016 at 7:34
  • Shipping just byte code without the source is asking for trouble. Byte-code is not guaranteed to be portable between platforms, python implementations, or versions. Commented Nov 24, 2016 at 7:39
  • @PM2Ring Python 3.x byte code is moved to 'pycache' directory directory with python version appended pradeep@ubuntu:~/Python/Module_Test$ ls __pycache__/ a.cpython-34.pyc a.cpython-35.pyc Commented Nov 24, 2016 at 8:07

2 Answers 2

3

After you remove 'a.py', you need to put 'a.pyc' in its place. The import mechanism will see it (when it interprets 'import a'), and will import it successfully. It does this without referring to the cache.

To get 'a.pyc', look in the pycache and copy-to-folder/rename 'a.xxxx.pyc' to 'a.pyc' There is a python function to compile to bytecodes too, so you don't have to work with the pycache

So long as your installation of python does not change, this should work. I believe the format of '.pyc' files can differ between installations. I believe this is a way to ship bytecodes instead of source. However, you must preserve the directory structure and the placement of the 'pyc' files in the same directories as the corresponding 'py' files. Of course the target machine must have an appropriate installation of python.

Sign up to request clarification or add additional context in comments.

Comments

1

Your understanding is not wrong; you can but, it isn't the best idea to do this. Afaik the default behavior of the import statement doesn't do this on its own, you'll either need to use a deprecated function from imp, write your own, or customize the import process to do it.

With imp, you'd use load_compiled as so:

from imp import load_compiled

mod = load_compiled('a', '__pycache__/a.cpython-35.pyc')

To get your module imported. The notable thing that I'm aware that Python does, is that it doesn't re-compile a module a.py if it's corresponding *.pyc is around and is still valid.

2 Comments

I dint intend to do this at production level. I am trying to make sense what the author is saying about importing modules with bytecode without source.
@Pradeep_Evol ah, I see, that's fine then :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.