util.py revision e7e35ac1c2e3c6b6a0836931b5c678d6af17129c
12689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward"""distutils.util 22689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 3aebf706b4e845d7525d2d8e792f0e23fcfb3e6afGreg WardMiscellaneous utility functions -- anything that doesn't fit into 4aebf706b4e845d7525d2d8e792f0e23fcfb3e6afGreg Wardone of the other *util.py modules.""" 52689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 62689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward# created 1999/03/08, Greg Ward 72689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 83ce77fd05ed00168f618b63401d770ccc4f04b09Greg Ward__revision__ = "$Id$" 92689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 10a7540bd043622de917fdc929310e1b5ca214ab83Greg Wardimport sys, os, string, re, shutil 112689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Wardfrom distutils.errors import * 127c1a6d477771955e3773849ef636fceda81bb3d5Greg Wardfrom distutils.spawn import spawn 132689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 14aebf706b4e845d7525d2d8e792f0e23fcfb3e6afGreg Ward# for backwards compatibility: 15aebf706b4e845d7525d2d8e792f0e23fcfb3e6afGreg Wardfrom distutils.file_util import * 16aebf706b4e845d7525d2d8e792f0e23fcfb3e6afGreg Wardfrom distutils.dir_util import * 17aebf706b4e845d7525d2d8e792f0e23fcfb3e6afGreg Wardfrom distutils.dep_util import * 18aebf706b4e845d7525d2d8e792f0e23fcfb3e6afGreg Wardfrom distutils.archive_util import * 19585df89f60ceb2e0a5b690f12f19c14093faa6fcGreg Ward 20585df89f60ceb2e0a5b690f12f19c14093faa6fcGreg Ward 21aa458bc46500a2b135cad66a4fd66cac69b8be51Greg Ward# Need to define 'abspath()', because it was new with Python 1.5.2 22aa458bc46500a2b135cad66a4fd66cac69b8be51Greg Wardif hasattr (os.path, 'abspath'): 23aa458bc46500a2b135cad66a4fd66cac69b8be51Greg Ward abspath = os.path.abspath 24aa458bc46500a2b135cad66a4fd66cac69b8be51Greg Wardelse: 25aa458bc46500a2b135cad66a4fd66cac69b8be51Greg Ward def abspath(path): 26aa458bc46500a2b135cad66a4fd66cac69b8be51Greg Ward if not os.path.isabs(path): 27aa458bc46500a2b135cad66a4fd66cac69b8be51Greg Ward path = os.path.join(os.getcwd(), path) 28aa458bc46500a2b135cad66a4fd66cac69b8be51Greg Ward return os.path.normpath(path) 29aa458bc46500a2b135cad66a4fd66cac69b8be51Greg Ward 30aa458bc46500a2b135cad66a4fd66cac69b8be51Greg Ward 31aa458bc46500a2b135cad66a4fd66cac69b8be51Greg Ward# More backwards compatability hacks 32aa458bc46500a2b135cad66a4fd66cac69b8be51Greg Warddef extend (list, new_list): 33aa458bc46500a2b135cad66a4fd66cac69b8be51Greg Ward """Appends the list 'new_list' to 'list', just like the 'extend()' 34aa458bc46500a2b135cad66a4fd66cac69b8be51Greg Ward list method does in Python 1.5.2 -- but this works on earlier 35aa458bc46500a2b135cad66a4fd66cac69b8be51Greg Ward versions of Python too.""" 36aa458bc46500a2b135cad66a4fd66cac69b8be51Greg Ward 37aa458bc46500a2b135cad66a4fd66cac69b8be51Greg Ward if hasattr (list, 'extend'): 38aa458bc46500a2b135cad66a4fd66cac69b8be51Greg Ward list.extend (new_list) 39aa458bc46500a2b135cad66a4fd66cac69b8be51Greg Ward else: 40aa458bc46500a2b135cad66a4fd66cac69b8be51Greg Ward list[len(list):] = new_list 41aa458bc46500a2b135cad66a4fd66cac69b8be51Greg Ward 42aa458bc46500a2b135cad66a4fd66cac69b8be51Greg Ward# extend () 43aa458bc46500a2b135cad66a4fd66cac69b8be51Greg Ward 44aa458bc46500a2b135cad66a4fd66cac69b8be51Greg Ward 45585df89f60ceb2e0a5b690f12f19c14093faa6fcGreg Warddef get_platform (): 46585df89f60ceb2e0a5b690f12f19c14093faa6fcGreg Ward """Return a string (suitable for tacking onto directory names) that 47585df89f60ceb2e0a5b690f12f19c14093faa6fcGreg Ward identifies the current platform. Under Unix, identifies both the OS 48585df89f60ceb2e0a5b690f12f19c14093faa6fcGreg Ward and hardware architecture, e.g. "linux-i586", "solaris-sparc", 49585df89f60ceb2e0a5b690f12f19c14093faa6fcGreg Ward "irix-mips". For Windows and Mac OS, just returns 'sys.platform' -- 50585df89f60ceb2e0a5b690f12f19c14093faa6fcGreg Ward i.e. "???" or "???".""" 51585df89f60ceb2e0a5b690f12f19c14093faa6fcGreg Ward 52585df89f60ceb2e0a5b690f12f19c14093faa6fcGreg Ward if os.name == 'posix': 536ce00b44405a478039d81a6c096620338b5d03a7Greg Ward (OS, _, rel, _, arch) = os.uname() 546ce00b44405a478039d81a6c096620338b5d03a7Greg Ward return "%s%c-%s" % (string.lower (OS), rel[0], string.lower (arch)) 55585df89f60ceb2e0a5b690f12f19c14093faa6fcGreg Ward else: 56585df89f60ceb2e0a5b690f12f19c14093faa6fcGreg Ward return sys.platform 57585df89f60ceb2e0a5b690f12f19c14093faa6fcGreg Ward 58585df89f60ceb2e0a5b690f12f19c14093faa6fcGreg Ward# get_platform() 595091929c2cf04bfbd545835d2435e43bda6afa05Greg Ward 605091929c2cf04bfbd545835d2435e43bda6afa05Greg Ward 615091929c2cf04bfbd545835d2435e43bda6afa05Greg Warddef native_path (pathname): 625091929c2cf04bfbd545835d2435e43bda6afa05Greg Ward """Return 'pathname' as a name that will work on the native 635091929c2cf04bfbd545835d2435e43bda6afa05Greg Ward filesystem, i.e. split it on '/' and put it back together again 645091929c2cf04bfbd545835d2435e43bda6afa05Greg Ward using the current directory separator. Needed because filenames in 655091929c2cf04bfbd545835d2435e43bda6afa05Greg Ward the setup script are always supplied in Unix style, and have to be 665091929c2cf04bfbd545835d2435e43bda6afa05Greg Ward converted to the local convention before we can actually use them in 6702a1a2b077e969e5fef8504cece5852bf641552dGreg Ward the filesystem. Raises ValueError if 'pathname' is 685091929c2cf04bfbd545835d2435e43bda6afa05Greg Ward absolute (starts with '/') or contains local directory separators 695091929c2cf04bfbd545835d2435e43bda6afa05Greg Ward (unless the local separator is '/', of course).""" 705091929c2cf04bfbd545835d2435e43bda6afa05Greg Ward 715091929c2cf04bfbd545835d2435e43bda6afa05Greg Ward if pathname[0] == '/': 7202a1a2b077e969e5fef8504cece5852bf641552dGreg Ward raise ValueError, "path '%s' cannot be absolute" % pathname 735091929c2cf04bfbd545835d2435e43bda6afa05Greg Ward if pathname[-1] == '/': 7402a1a2b077e969e5fef8504cece5852bf641552dGreg Ward raise ValueError, "path '%s' cannot end with '/'" % pathname 75464023fb64dd590b91cab7059dffdf0756eecbceGreg Ward if os.sep != '/': 76464023fb64dd590b91cab7059dffdf0756eecbceGreg Ward if os.sep in pathname: 77464023fb64dd590b91cab7059dffdf0756eecbceGreg Ward raise ValueError, \ 78464023fb64dd590b91cab7059dffdf0756eecbceGreg Ward "path '%s' cannot contain '%c' character" % (pathname, os.sep) 79464023fb64dd590b91cab7059dffdf0756eecbceGreg Ward else: 80464023fb64dd590b91cab7059dffdf0756eecbceGreg Ward paths = string.split (pathname, '/') 81464023fb64dd590b91cab7059dffdf0756eecbceGreg Ward return apply (os.path.join, paths) 825091929c2cf04bfbd545835d2435e43bda6afa05Greg Ward else: 835091929c2cf04bfbd545835d2435e43bda6afa05Greg Ward return pathname 845091929c2cf04bfbd545835d2435e43bda6afa05Greg Ward 855091929c2cf04bfbd545835d2435e43bda6afa05Greg Ward# native_path () 861b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward 871b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward 8867f75d4bcb3630c0f5b6761fb758072cc342157eGreg Warddef change_root (new_root, pathname): 8967f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward 9067f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward """Return 'pathname' with 'new_root' prepended. If 'pathname' is 9167f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward relative, this is equivalent to "os.path.join(new_root,pathname)". 9267f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward Otherwise, it requires making 'pathname' relative and then joining the 9367f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward two, which is tricky on DOS/Windows and Mac OS.""" 9467f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward 9567f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward if not abspath (pathname): 9667f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward return os.path.join (new_root, pathname) 9767f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward 9867f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward elif os.name == 'posix': 9967f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward return os.path.join (new_root, pathname[1:]) 10067f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward 10167f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward elif os.name == 'nt': 10267f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward (root_drive, root_path) = os.path.splitdrive (new_root) 10367f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward (drive, path) = os.path.splitdrive (pathname) 10467f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward raise RuntimeError, "I give up -- not sure how to do this on Windows" 10567f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward 10667f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward elif os.name == 'mac': 10767f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward raise RuntimeError, "no clue how to do this on Mac OS" 10867f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward 10967f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward else: 11067f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward raise DistutilsPlatformError, \ 11167f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward "nothing known about platform '%s'" % os.name 11267f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward 11367f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward 114e7e35ac1c2e3c6b6a0836931b5c678d6af17129cGregory P. Smith_environ_checked = 0 115e7e35ac1c2e3c6b6a0836931b5c678d6af17129cGregory P. Smithdef check_environ (): 1161b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward """Ensure that 'os.environ' has all the environment variables we 1171b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward guarantee that users can use in config files, command-line 1181b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward options, etc. Currently this includes: 1191b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward HOME - user's home directory (Unix only) 1201b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward PLAT - desription of the current platform, including hardware 1211b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward and OS (see 'get_platform()') 1221b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward """ 1231b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward 124e7e35ac1c2e3c6b6a0836931b5c678d6af17129cGregory P. Smith global _environ_checked 125e7e35ac1c2e3c6b6a0836931b5c678d6af17129cGregory P. Smith if _environ_checked: 126e7e35ac1c2e3c6b6a0836931b5c678d6af17129cGregory P. Smith return 127e7e35ac1c2e3c6b6a0836931b5c678d6af17129cGregory P. Smith 1281b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward if os.name == 'posix' and not os.environ.has_key('HOME'): 1291b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward import pwd 1301b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward os.environ['HOME'] = pwd.getpwuid (os.getuid())[5] 1311b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward 1321b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward if not os.environ.has_key('PLAT'): 1331b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward os.environ['PLAT'] = get_platform () 1341b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward 135e7e35ac1c2e3c6b6a0836931b5c678d6af17129cGregory P. Smith _environ_checked = 1 136e7e35ac1c2e3c6b6a0836931b5c678d6af17129cGregory P. Smith 1371b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward 1381b4ede5f24814dc4baa8832414093aa745c3755cGreg Warddef subst_vars (str, local_vars): 1391b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward """Perform shell/Perl-style variable substitution on 'string'. 1401b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward Every occurence of '$' followed by a name, or a name enclosed in 1411b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward braces, is considered a variable. Every variable is substituted by 1421b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward the value found in the 'local_vars' dictionary, or in 'os.environ' 1431b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward if it's not in 'local_vars'. 'os.environ' is first checked/ 1441b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward augmented to guarantee that it contains certain values: see 1451b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward '_check_environ()'. Raise ValueError for any variables not found in 1461b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward either 'local_vars' or 'os.environ'.""" 1471b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward 148e7e35ac1c2e3c6b6a0836931b5c678d6af17129cGregory P. Smith check_environ () 1491b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward def _subst (match, local_vars=local_vars): 1501b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward var_name = match.group(1) 1511b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward if local_vars.has_key (var_name): 1521b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward return str (local_vars[var_name]) 1531b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward else: 1541b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward return os.environ[var_name] 1551b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward 1561b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward return re.sub (r'\$([a-zA-Z_][a-zA-Z_0-9]*)', _subst, str) 1571b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward 1581b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward# subst_vars () 1597c1a6d477771955e3773849ef636fceda81bb3d5Greg Ward 1607c1a6d477771955e3773849ef636fceda81bb3d5Greg Ward 161