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 """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