A hack to let Pyrex 0.3.x users build extension classes on Win32
Graham Fawcett
gmfawcett at operamail.com
Thu Jul 4 15:13:33 EDT 2002
Hi folks,
I downloaded and am using version 0.3.2 of the fantastic Pyrex
extension language (
http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/ ) and am happily
speeding up some crucial code using this marvellous product.
However, I ran into a hitch when trying to build an extension class on
my Win32 machine: the compiler complained with "initializer not a
constant" errors. This is a known issue in Python; see the FAQ at
http://www.python.org/cgi-bin/faqw.py?req=show&file=faq03.024.htp .
So I did a very ugly little hack on the pyrexc.py script to fix the
problem. (The hacked script just runs pyrexc as usual, but then
traverses each C file that pyrexc builds and applies the advice given
in the Python FAQ.
This is a brute-force and brittle approach. I expect it will break
against a release of Pyrex > 0.3.2. (I should have taken the time to
read Greg's compiler code and fix it there, but I've a temporary
shortage of Copious Free Time.)
Here's the revised script.
#!/usr/bin/env python
#
# Pyrex -- Main Program, Unix
#
import Pyrex.Compiler.Main
Pyrex.Compiler.Main.main(c_only = 1, use_listing_file = 0)
# ---- added by Graham Fawcett <fawcett at uwindsor.ca>
# ---- fixes "Initializer not a constant" while building DLL on
MS-Windows
# ---- http://www.python.org/cgi-bin/faqw.py?req=show&file=faq03.024.htp
HEAD_INIT = 'PyObject_HEAD_INIT(0)'
TYPESTART = 'statichere PyTypeObject __pyx_type_'
GETATTR = 'PyObject_GenericGetAttr, /*tp_getattro*/'
SETATTR = 'PyObject_GenericSetAttr, /*tp_setattro*/'
ALLOC = 'PyType_GenericAlloc, /*tp_alloc*/'
FREE = '_PyObject_Del, /*tp_free*/'
TYPEINIT ='''__pyx_type_%(typename)s.ob_type = &PyType_Type;
__pyx_type_%(typename)s.tp_getattro = PyObject_GenericGetAttr;
/*tp_getattro*/
__pyx_type_%(typename)s.tp_setattro = PyObject_GenericSetAttr;
/*tp_setattro*/
__pyx_type_%(typename)s.tp_alloc = PyType_GenericAlloc; /*tp_alloc*/
__pyx_type_%(typename)s.tp_free = _PyObject_Del; /*tp_free*/
'''
def fix_c_file(pyx_filename):
filename = pyx_filename.split('.')[0] + '.c'
f = open(filename, 'r')
lines = f.readlines()
f.close()
lines = [line.rstrip() for line in lines]
types = []
f = open(filename, 'w')
for line in lines:
# strip the injurious assignments from the PyTypeObject def'n
if line.startswith(HEAD_INIT):
print >> f, 'PyObject_HEAD_INIT(NULL)'
elif line.startswith(TYPESTART):
typename = line[len(TYPESTART):].split(' ')[0]
types.append(typename)
print >> f, line
elif line.startswith(GETATTR):
print >> f, 'NULL,' + GETATTR.split(',')[1]
elif line.startswith(SETATTR):
print >> f, 'NULL,' + SETATTR.split(',')[1]
elif line.startswith(ALLOC):
print >> f, 'NULL,' + ALLOC.split(',')[1]
elif line.startswith(FREE):
print >> f, 'NULL,' + FREE.split(',')[1]
elif line.startswith('void init') and line.endswith('(void)
{'):
print >> f, line
# put the assignments in the module init function
for typename in types:
print >> f, TYPEINIT % locals()
else:
pass
print >> f, line
f.close()
import sys
if sys.platform == 'win32':
for pyx_filename in sys.argv[1:]:
fix_c_file(pyx_filename)
# ---- end of addition
Best wishes,
-- Graham
More information about the Python-list
mailing list