Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Executable .pyc, patches enclosed

4 views
Skip to first unread message

Jeff Epler

unread,
Mar 23, 1997, 3:00:00 AM3/23/97
to

Hi.

A few days ago, someone lamented that it wasn't allowed to make a .pyc
file executable using the unix '#!' notation.

I hacked up the following changes, allowing this to be the case.

Python/pythonrun.c:run_pyc_file was modified so that if the file
begins with '#!', the file is read through the first \n and then
the magic is tested again. This allows the unix executable magic to
be prepended to the .pyc file.

Lib/py_compile.py was modified so that a new parameter to compile() is
allowed, 'executable'. If it is unspecified, compile() will guess
that the script is to be executable if the source .py begins '#!'. If
'executable' is true, the script will be executable, otherwise it will
not be. It prepends '#!/usr/bin/env python' to the output, and will
chmod +x it if the os module has chmod and stat.

Also, a main function was added to Lib/py_compile.py and it was made
executable. I am unhappy with the choice of the command-line
switches, but
-x make scripts executable
-X do not make scripts executable
-0 guess (default)
so you might type in your shell
./py_compile.py py_compile.py
./py_compile.pyc *.py
to compile all .py files in the current directory

These patches are against Python 1.4. Apply with patch -p0 from the
top-level Python directory.

Let me know if you like this. The obvious drawback is that executable
.pyc files are not understood by an unpatched Python. It seems to work,
but I've tested it very minimally.

Jeff
--
\/ jep...@inetnebr.com http://incolor.inetnebr.com/jepler/ (0|1(01*0)*1)+
One good reason why computers can do more work than people is that they
never have to stop and answer the phone.

--- Lib/py_compile.py.orig Sun Mar 23 09:31:02 1997
+++ Lib/py_compile.py Sun Mar 23 09:40:13 1997
@@ -1,3 +1,4 @@
+#!/usr/bin/env python
# Routine to "compile" a .py file to a .pyc file.
# This has intimate knowledge of how Python/import.c does it.
# By Sjoerd Mullender (I forced him to write it :-).
@@ -11,21 +12,40 @@
f.write(chr((x >> 16) & 0xff))
f.write(chr((x >> 24) & 0xff))

-def compile(file, cfile = None):
+def compile(file, cfile = None, executable=None):
import os, marshal, __builtin__
f = open(file)
codestring = f.read()
+ if executable==None and codestring[:2]=="#!": executable=1
f.close()
timestamp = long(os.stat(file)[8])
codeobject = __builtin__.compile(codestring, file, 'exec')
if not cfile:
cfile = file + 'c'
fc = open(cfile, 'wb')
+ if executable:
+ fc.write("#!/usr/bin/env python\n")
fc.write(MAGIC)
wr_long(fc, timestamp)
marshal.dump(codeobject, fc)
fc.close()
+ if executable and hasattr(os,'chmod'):
+ os.chmod(cfile, os.stat(cfile)[0] | 0111)
if os.name == 'mac':
import macfs
macfs.FSSpec(cfile).SetCreatorType('Pyth', 'PYC ')
macfs.FSSpec(file).SetCreatorType('Pyth', 'TEXT')
+
+def main(args):
+ import getopt
+ (switches, args) = getopt.getopt(args, 'Xx0')
+ executable=None
+ for i in switches:
+ if i=='-X': executable=0
+ if i=='-x': executable=1
+ if i=='-0': executable=None
+ for i in args: compile(i, executable=executable)
+
+if __name__=='__main__':
+ import sys
+ main(sys.argv[1:])
--- Python/pythonrun.c.orig Sun Mar 23 09:43:30 1997
+++ Python/pythonrun.c Sun Mar 23 09:28:58 1997
@@ -447,9 +447,13 @@
long get_pyc_magic();

magic = rd_long(fp);
+ if ((magic & 0xffff) == ('#'+('!' << 8))) {
+ while (fgetc(fp)!='\n') 0;
+ magic = rd_long(fp);
+ }
if (magic != get_pyc_magic()) {
err_setstr(RuntimeError,
"Bad magic number in .pyc file");
return NULL;
}
(void) rd_long(fp);

0 new messages