Re: .pyc files...

Guido.van.Rossum@cwi.nl
Fri, 04 Mar 1994 10:48:40 +0100

> .pyc files... Are they susposed to be portable? If not, why not?

Yes, they are supposed to be portable.

> They don't look like they are..
> I created a .pyc file on the SCO machine and one on a SPARCstation..
> the files were different sizes...

A .pyc file is an 8-byte header followed by a code object marshalled
by marshal.dump(). Since the code object contains the pathname of the
.py file from which it was created, .pyc files on different systems
may be different unless the pathname used on both systems is identical.

The header format is trivial: the first 4 bytes are a magic number
used to distinguish incompatible interpreters (currently 0x999902L --
see the definition of MAGIC in Python/import.c) followed by 4 bytes
which give the mtime of the .py file from which the .pyc file was
generated. Byte order is LITTLE-ENDIAN (lsb first). If the .py file
exists (in the same directory) and its mtime does not match, the .pyc
file is ignored and rewritten (silently). Note that the filename from
the code object is not used for the comparison -- in order to match,
the .py and .pyc file must have the same name and live in the same
directory.

Note that before Python 1.0, .pyc files without .py files were ignored
-- currently they are used, so you can make a "binary" distribution of
a Python program by deleting the .py files after generating .pyc files.

> But I thought the creation routines used the same routines in
> the marshal module and these look like they are system independent...
>
> What am I doing wrong?

You're not doing anything wrong -- if .pyc turn out to be non-portable
between SCO and Sparc, *I* have done something wrong.

To try this out, use tar or cpio (to preserve mtimes) to transfer
*both* the .py and the .pyc file from one system to another and then
use "python -v" (which prints details about importing files and tells
you whether the .pyc file was found correctly).

Here's a small session showing how to check a code object manually:

>>> import sys
>>> sys.path
['.', '/ufs/guido/lib/python', '/ufs/guido/lib/python/test', '/ufs/guido/lib/python/sgi', '/ufs/guido/lib/python/stdwin']
>>> file = sys.path[1] + '/string.pyc'
>>> f = open(file, 'r')
>>> import marshal
>>> magic = f.read(4)
>>> magic
'\002\231\231\000'
>>> mtime = f.read(4)
>>> mtime
'\326\360`-'
>>> c = marshal.load(f)
>>> c
<code object ? at 100e2c74, file "/ufs/guido/lib/python/string.py", line 0>
>>>

--Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl>
URL: <http://www.cwi.nl/cwi/people/Guido.van.Rossum.html>