Re: [Distutils] Access to Python config info

At 01:40 23/12/98 +1000, John Skaller wrote: Duh, sorry for replying to my own post again but:
This depends on knowing where the makefile and the config file are. Which suggest a further factorisation: def parse_config_h(filename) def parse_makefile(filename) which would be generally useful! And truly statless. Now, provide: def get_config_h_filename() def get_makefile_filename() and we can wrap them up to get: def get_config(): dict = parse_config_h(get_config_h_filename()) dict.update(parse_config_h(get_makefile_filename())) return dict Again, this factorisation simplifies the design, and also creates added functionality. ------------------------------------------------------- John Skaller email: skaller@maxtal.com.au http://www.maxtal.com.au/~skaller phone: 61-2-96600850 snail: 10/1 Toxteth Rd, Glebe NSW 2037, Australia

John Skaller writes:
This depends on knowing where the makefile and the config file are. Which suggest a further factorisation:
Ok, I've modified distutils.sysconfig to contain: get_config_h_filename() get_makefile_filename() parse_config_h(fileobject, g=None) parse_makefile(fileobject, g=None) Note that the parse_*() routines take a file object instead of a filename, and the dictionary to update may be passed in. If no dictionary is provided a new one is used. However the dict is obtained, it is returned by the function. Equivalents for non-Unix platforms are still needed; has anyone thought about Windows or Mac platforms? I think the current implementation is fine for BeOS; can someone who uses the BeOS port confirm? NeXT users might want to pipe up as well!
I passed on this for now. I think the cross-platform issues need to be explored more.
Again, this factorisation simplifies the design, and also creates added functionality.
This I agree with. -Fred -- Fred L. Drake, Jr. <fdrake@acm.org> Corporation for National Research Initiatives 1895 Preston White Dr. Reston, VA 20191

Fred L. Drake wrote:
The Windows platform has a hardcoded "makefile" and a hardcoded config.h. If the sysconfig interface is simply a flat of list of names, then the Windows platform can ship a simple sysconfig module defining those names as appropriate (rather than trying to query them). This is partly why I advocate making sysocnfig as simple as possible. Preferably, it would be generate by the build process and shipped that way. NO functions. If you want functions/classes/whatever, then they go in the distutils package, consuming information from sysconfig.py as needed. Cheers, -g -- Greg Stein, http://www.lyra.org/

Oops, I forgot the patch. It should be below. If I don't forget again. ;-) Greg, please integrate with the CVS repo. -Fred -- Fred L. Drake, Jr. <fdrake@acm.org> Corporation for National Research Initiatives 1895 Preston White Dr. Reston, VA 20191 Index: sysconfig.py =================================================================== RCS file: /projects/cvsroot/distutils/distutils/sysconfig.py,v retrieving revision 1.1 diff -c -c -r1.1 sysconfig.py *** sysconfig.py 1998/12/18 23:46:33 1.1 --- sysconfig.py 1998/12/22 17:00:01 *************** *** 11,33 **** __version__ = "$Revision: 1.1 $" ! ! 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: --- 11,36 ---- __version__ = "$Revision: 1.1 $" ! import os ! import re ! import string ! import sys ! ! ! def get_config_h_filename(): ! return os.path.join(sys.exec_prefix, "lib", "python" + sys.version[:3], ! "config", "config.h") ! ! def get_makefile_filename(): ! return os.path.join(sys.exec_prefix, "lib", "python" + sys.version[:3], ! "config", "Makefile") ! ! def parse_config_h(fp, g=None): ! if g is None: ! g = {} define_rx = re.compile("#define ([A-Z][A-Z0-9_]+) (.*)\n") undef_rx = re.compile("/[*] #undef ([A-Z][A-Z0-9_]+) [*]/\n") ! # while 1: line = fp.readline() if not line: *************** *** 35,54 **** 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() --- 38,58 ---- m = define_rx.match(line) if m: n, v = m.group(1, 2) ! try: v = string.atoi(v) ! except ValueError: pass ! g[n] = v else: m = undef_rx.match(line) if m: g[m.group(1)] = 0 + return g ! def parse_makefile(fp, g=None): ! if g is None: ! g = {} variable_rx = re.compile("([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)\n") done = {} notdone = {} while 1: line = fp.readline() *************** *** 57,65 **** --- 61,72 ---- m = variable_rx.match(line) if m: n, v = m.group(1, 2) + v = string.strip(v) if "$" in v: notdone[n] = v else: + try: v = string.atoi(v) + except ValueError: pass done[n] = v # do variable interpolation here *************** *** 79,85 **** if "$" in after: notdone[name] = value else: ! done[name] = value del notdone[name] elif notdone.has_key(n): # get it on a subsequent round --- 86,94 ---- if "$" in after: notdone[name] = value else: ! try: value = string.atoi(value) ! except ValueError: pass ! done[name] = string.strip(value) del notdone[name] elif notdone.has_key(n): # get it on a subsequent round *************** *** 91,106 **** 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) - import os exec "_init_%s()" % os.name - del os del _init_posix --- 100,124 ---- if "$" in after: notdone[name] = value else: ! try: value = string.atoi(value) ! except ValueError: pass ! done[name] = string.strip(value) del notdone[name] else: + # bogus variable reference; just drop it since we can't deal del notdone[name] # save the results in the global dictionary g.update(done) + return g + + def _init_posix(): + g = globals() + # load the installed config.h: + parse_config_h(open(get_config_h_filename()), g) + # load the installed Makefile.pre.in: + parse_makefile(open(get_makefile_filename()), g) exec "_init_%s()" % os.name del _init_posix

John Skaller writes:
This depends on knowing where the makefile and the config file are. Which suggest a further factorisation:
Ok, I've modified distutils.sysconfig to contain: get_config_h_filename() get_makefile_filename() parse_config_h(fileobject, g=None) parse_makefile(fileobject, g=None) Note that the parse_*() routines take a file object instead of a filename, and the dictionary to update may be passed in. If no dictionary is provided a new one is used. However the dict is obtained, it is returned by the function. Equivalents for non-Unix platforms are still needed; has anyone thought about Windows or Mac platforms? I think the current implementation is fine for BeOS; can someone who uses the BeOS port confirm? NeXT users might want to pipe up as well!
I passed on this for now. I think the cross-platform issues need to be explored more.
Again, this factorisation simplifies the design, and also creates added functionality.
This I agree with. -Fred -- Fred L. Drake, Jr. <fdrake@acm.org> Corporation for National Research Initiatives 1895 Preston White Dr. Reston, VA 20191

Fred L. Drake wrote:
The Windows platform has a hardcoded "makefile" and a hardcoded config.h. If the sysconfig interface is simply a flat of list of names, then the Windows platform can ship a simple sysconfig module defining those names as appropriate (rather than trying to query them). This is partly why I advocate making sysocnfig as simple as possible. Preferably, it would be generate by the build process and shipped that way. NO functions. If you want functions/classes/whatever, then they go in the distutils package, consuming information from sysconfig.py as needed. Cheers, -g -- Greg Stein, http://www.lyra.org/

Oops, I forgot the patch. It should be below. If I don't forget again. ;-) Greg, please integrate with the CVS repo. -Fred -- Fred L. Drake, Jr. <fdrake@acm.org> Corporation for National Research Initiatives 1895 Preston White Dr. Reston, VA 20191 Index: sysconfig.py =================================================================== RCS file: /projects/cvsroot/distutils/distutils/sysconfig.py,v retrieving revision 1.1 diff -c -c -r1.1 sysconfig.py *** sysconfig.py 1998/12/18 23:46:33 1.1 --- sysconfig.py 1998/12/22 17:00:01 *************** *** 11,33 **** __version__ = "$Revision: 1.1 $" ! ! 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: --- 11,36 ---- __version__ = "$Revision: 1.1 $" ! import os ! import re ! import string ! import sys ! ! ! def get_config_h_filename(): ! return os.path.join(sys.exec_prefix, "lib", "python" + sys.version[:3], ! "config", "config.h") ! ! def get_makefile_filename(): ! return os.path.join(sys.exec_prefix, "lib", "python" + sys.version[:3], ! "config", "Makefile") ! ! def parse_config_h(fp, g=None): ! if g is None: ! g = {} define_rx = re.compile("#define ([A-Z][A-Z0-9_]+) (.*)\n") undef_rx = re.compile("/[*] #undef ([A-Z][A-Z0-9_]+) [*]/\n") ! # while 1: line = fp.readline() if not line: *************** *** 35,54 **** 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() --- 38,58 ---- m = define_rx.match(line) if m: n, v = m.group(1, 2) ! try: v = string.atoi(v) ! except ValueError: pass ! g[n] = v else: m = undef_rx.match(line) if m: g[m.group(1)] = 0 + return g ! def parse_makefile(fp, g=None): ! if g is None: ! g = {} variable_rx = re.compile("([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)\n") done = {} notdone = {} while 1: line = fp.readline() *************** *** 57,65 **** --- 61,72 ---- m = variable_rx.match(line) if m: n, v = m.group(1, 2) + v = string.strip(v) if "$" in v: notdone[n] = v else: + try: v = string.atoi(v) + except ValueError: pass done[n] = v # do variable interpolation here *************** *** 79,85 **** if "$" in after: notdone[name] = value else: ! done[name] = value del notdone[name] elif notdone.has_key(n): # get it on a subsequent round --- 86,94 ---- if "$" in after: notdone[name] = value else: ! try: value = string.atoi(value) ! except ValueError: pass ! done[name] = string.strip(value) del notdone[name] elif notdone.has_key(n): # get it on a subsequent round *************** *** 91,106 **** 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) - import os exec "_init_%s()" % os.name - del os del _init_posix --- 100,124 ---- if "$" in after: notdone[name] = value else: ! try: value = string.atoi(value) ! except ValueError: pass ! done[name] = string.strip(value) del notdone[name] else: + # bogus variable reference; just drop it since we can't deal del notdone[name] # save the results in the global dictionary g.update(done) + return g + + def _init_posix(): + g = globals() + # load the installed config.h: + parse_config_h(open(get_config_h_filename()), g) + # load the installed Makefile.pre.in: + parse_makefile(open(get_makefile_filename()), g) exec "_init_%s()" % os.name del _init_posix
participants (3)
-
Fred L. Drake
-
Greg Stein
-
John Skaller