[Distutils] Access to Python config info
Fred L. Drake
Fred L. Drake, Jr." <fdrake@acm.org
Thu, 17 Dec 1998 12:37:59 -0500 (EST)
--udwOQwHuZC
Content-Type: text/plain; charset=us-ascii
Content-Description: message body text
Content-Transfer-Encoding: 7bit
Greg Stein writes:
> I don't see much of a rationale for *not* doing this at install time.
> The file is a bunch of constants that are easily determined when you
> build/install Python.
Yes. It can include code to regenerate the "right stuff" when run
as a script as well. Running it as a script can be done at the end of
installation.
> There is a caveat for trying to get it to function with 1.5.2, but I
> don't believe that changes the long-term interface, which I maintain are
> simple names/values.
What's the caveat?
> Note that these files are always installed at
> $(exec_prefix)/lib/python$(version)/config/ (as far as I can tell,
> that's fixed).
I think you're right.
I've attached a sysconfig.py that works on Unix. Someone familiar
with other platforms will need to make it work there as well by adding
additional _init_<name>() functions; <name> should be os.name. When
run as a script, it rewrites itself with the discovered information.
-Fred
--
Fred L. Drake, Jr. <fdrake@acm.org>
Corporation for National Research Initiatives
1895 Preston White Dr. Reston, VA 20191
--udwOQwHuZC
Content-Type: text/plain
Content-Description: preliminary sysconfig.py
Content-Disposition: inline;
filename="sysconfig.py"
Content-Transfer-Encoding: 7bit
"""Prototype sysconfig module that loads information when run as a script,
but only defines constants when imported.
This should be run as a script as one of the last steps of the Python
installation process.
"""
# START DATA
# END DATA
def _init_posix():
import os
import re
import sys
g = globals()
version = sys.version[:3]
config_dir = os.path.join(
sys.exec_prefix, "lib", "python" + version, "config")
# load the installed config.h:
define_rx = re.compile("#define ([A-Z][A-Z0-9_]+) (.*)\n")
undef_rx = re.compile("/[*] #undef ([A-Z][A-Z0-9_]+) [*]/\n")
fp = open(os.path.join(config_dir, "config.h"))
while 1:
line = fp.readline()
if not line:
break
m = define_rx.match(line)
if m:
n, v = m.group(1, 2)
if v == "1":
g[n] = 1
else:
g[n] = v
else:
m = undef_rx.match(line)
if m:
g[m.group(1)] = 0
# load the installed Makefile.pre.in:
variable_rx = re.compile("([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)\n")
done = {}
notdone = {}
fp = open(os.path.join(config_dir, "Makefile"))
while 1:
line = fp.readline()
if not line:
break
m = variable_rx.match(line)
if m:
n, v = m.group(1, 2)
if "$" in v:
notdone[n] = v
else:
done[n] = v
# do variable interpolation here
findvar1_rx = re.compile(r"\$.([A-Za-z][A-Za-z0-9_]*).")
findvar2_rx = re.compile(r"\$.([A-Za-z][A-Za-z0-9_]*)}")
while notdone:
for name in notdone.keys():
value = notdone[name]
m = findvar1_rx.search(value)
if not m:
m = findvar2_rx.search(value)
if m:
n = m.group(1)
if done.has_key(n):
after = value[m.end():]
value = value[:m.start()] + done[n] + after
if "$" in after:
notdone[name] = value
else:
done[name] = value
del notdone[name]
elif notdone.has_key(n):
# get it on a subsequent round
pass
else:
done[n] = ""
after = value[m.end():]
value = value[:m.start()] + after
if "$" in after:
notdone[name] = value
else:
done[name] = value
del notdone[name]
else:
del notdone[name]
# save the results in the global dictionary
g.update(done)
# save the results in the source file
filename = os.path.splitext(sys.argv[0])[0] + ".py"
lines = open(filename).readlines()
start = lines.index("# START DATA\n")
end = lines.index("# END DATA\n")
newdata = []
items = g.items()
items.sort()
for name, value in items:
if name[0] != "_":
newdata.append("%s = %s\n" % (name, `value`))
lines[start+1:end] = newdata
open(filename, "w").writelines(lines)
if __name__ == "__main__":
import os
exec "_init_%s()" % os.name
del _init_posix
--udwOQwHuZC--