12689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward"""distutils.util 22689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 3aebf706b4e845d7525d2d8e792f0e23fcfb3e6afGreg WardMiscellaneous utility functions -- anything that doesn't fit into 44752769d08c3ef950d31b926751d5e4d1dae294fGreg Wardone of the other *util.py modules. 54752769d08c3ef950d31b926751d5e4d1dae294fGreg Ward""" 62689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 73ce77fd05ed00168f618b63401d770ccc4f04b09Greg Ward__revision__ = "$Id$" 82689e3ddce70e8acc5bc231a80221980d5bdfec3Greg Ward 9f830aa54558b0d4358f427e46171e95c8218f2deJesus Ceaimport sys, os, string, re 101297b5ce67642dba35615121825fb1621e28e6b8Greg Wardfrom distutils.errors import DistutilsPlatformError 111297b5ce67642dba35615121825fb1621e28e6b8Greg Wardfrom distutils.dep_util import newer 12dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadéfrom distutils.spawn import spawn 13cd8a1148e19116db109f27d26c02e1de536dc76eJeremy Hyltonfrom distutils import log 14b9c1cfc42881370322ff6894568b45dcfec5ba2eTarek Ziadéfrom distutils.errors import DistutilsByteCompileError 15aa458bc46500a2b135cad66a4fd66cac69b8be51Greg Ward 16dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadédef get_platform (): 17dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé """Return a string that identifies the current platform. This is used 18dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé mainly to distinguish platform-specific build directories and 19dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé platform-specific built distributions. Typically includes the OS name 20dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé and version and the architecture (as supplied by 'os.uname()'), 21dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé although the exact information included depends on the OS; eg. for IRIX 22dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé the architecture isn't particularly important (IRIX only runs on SGI 23dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé hardware), but for Linux the kernel version isn't particularly 24dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé important. 25dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé 26dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé Examples of returned values: 27dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé linux-i586 28dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé linux-alpha (?) 29dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé solaris-2.6-sun4u 30dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé irix-5.3 31dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé irix64-6.2 32dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé 33dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé Windows will return one of: 34dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) 35dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé win-ia64 (64bit Windows on Itanium) 36dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé win32 (all others - specifically, sys.platform is returned) 37dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé 38dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé For other non-POSIX platforms, currently just returns 'sys.platform'. 39dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé """ 40dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé if os.name == 'nt': 41dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé # sniff sys.version for architecture. 42dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé prefix = " bit (" 43dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé i = string.find(sys.version, prefix) 44dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé if i == -1: 45dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé return sys.platform 46dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé j = string.find(sys.version, ")", i) 47dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé look = sys.version[i+len(prefix):j].lower() 48dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé if look=='amd64': 49dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé return 'win-amd64' 50dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé if look=='itanium': 51dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé return 'win-ia64' 52dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé return sys.platform 53dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé 54d65e2bab3b438f883ef28245f51795b14a4c498fdoko@python.org # Set for cross builds explicitly 55d65e2bab3b438f883ef28245f51795b14a4c498fdoko@python.org if "_PYTHON_HOST_PLATFORM" in os.environ: 56d65e2bab3b438f883ef28245f51795b14a4c498fdoko@python.org return os.environ["_PYTHON_HOST_PLATFORM"] 57d65e2bab3b438f883ef28245f51795b14a4c498fdoko@python.org 58dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé if os.name != "posix" or not hasattr(os, 'uname'): 59dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé # XXX what about the architecture? NT is Intel or Alpha, 60dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé # Mac OS is M68k or PPC, etc. 61dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé return sys.platform 62dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé 63dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé # Try to distinguish various flavours of Unix 64dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé 65dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé (osname, host, release, version, machine) = os.uname() 66dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé 67dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé # Convert the OS name to lowercase, remove '/' characters 68dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé # (to accommodate BSD/OS), and translate spaces (for "Power Macintosh") 69dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé osname = string.lower(osname) 70dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé osname = string.replace(osname, '/', '') 71dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé machine = string.replace(machine, ' ', '_') 72dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé machine = string.replace(machine, '/', '-') 73dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé 74dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé if osname[:5] == "linux": 75dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé # At least on Linux/Intel, 'machine' is the processor -- 76dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé # i386, etc. 77dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé # XXX what about Alpha, SPARC, etc? 78dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé return "%s-%s" % (osname, machine) 79dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé elif osname[:5] == "sunos": 80dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé if release[0] >= "5": # SunOS 5 == Solaris 2 81dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé osname = "solaris" 82dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé release = "%d.%s" % (int(release[0]) - 3, release[2:]) 83f830aa54558b0d4358f427e46171e95c8218f2deJesus Cea # We can't use "platform.architecture()[0]" because a 84f830aa54558b0d4358f427e46171e95c8218f2deJesus Cea # bootstrap problem. We use a dict to get an error 85f830aa54558b0d4358f427e46171e95c8218f2deJesus Cea # if some suspicious happens. 86f830aa54558b0d4358f427e46171e95c8218f2deJesus Cea bitness = {2147483647:"32bit", 9223372036854775807:"64bit"} 87f830aa54558b0d4358f427e46171e95c8218f2deJesus Cea machine += ".%s" % bitness[sys.maxint] 88dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé # fall through to standard osname-release-machine representation 89dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé elif osname[:4] == "irix": # could be "irix64"! 90dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé return "%s-%s" % (osname, release) 91dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé elif osname[:3] == "aix": 92dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé return "%s-%s.%s" % (osname, version, release) 93dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé elif osname[:6] == "cygwin": 94dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé osname = "cygwin" 95dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé rel_re = re.compile (r'[\d.]+') 96dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé m = rel_re.match(release) 97dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé if m: 98dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé release = m.group() 99dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé elif osname[:6] == "darwin": 10018fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily import _osx_support, distutils.sysconfig 10118fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily osname, release, machine = _osx_support.get_platform_osx( 10218fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily distutils.sysconfig.get_config_vars(), 10318fae3f9542fc7bb0d9da53a5de30041651a85b6Ned Deily osname, release, machine) 10492e68af56a2b95627c2220c3e190d7e3c2d4643eTarek Ziadé 105dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé return "%s-%s-%s" % (osname, release, machine) 106dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé 107dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé# get_platform () 1080276c7ad0b56024f5373ad8f7edca5d77c58df22Tarek Ziadé 1095091929c2cf04bfbd545835d2435e43bda6afa05Greg Ward 110dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadédef convert_path (pathname): 111dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé """Return 'pathname' as a name that will work on the native filesystem, 112b8b263b92f33162d0b1bd35f44a17e5538b9713fGreg Ward i.e. split it on '/' and put it back together again using the current 113b8b263b92f33162d0b1bd35f44a17e5538b9713fGreg Ward directory separator. Needed because filenames in the setup script are 114b8b263b92f33162d0b1bd35f44a17e5538b9713fGreg Ward always supplied in Unix style, and have to be converted to the local 115b8b263b92f33162d0b1bd35f44a17e5538b9713fGreg Ward convention before we can actually use them in the filesystem. Raises 1164752769d08c3ef950d31b926751d5e4d1dae294fGreg Ward ValueError on non-Unix-ish systems if 'pathname' either starts or 1174752769d08c3ef950d31b926751d5e4d1dae294fGreg Ward ends with a slash. 118b8b263b92f33162d0b1bd35f44a17e5538b9713fGreg Ward """ 1197ec053544cf4849a138e70329ffeec1d6ab93e62Greg Ward if os.sep == '/': 1207ec053544cf4849a138e70329ffeec1d6ab93e62Greg Ward return pathname 121b0df6a1afa585c5f4d097aeb68e41996a9fff9d7Neal Norwitz if not pathname: 122b0df6a1afa585c5f4d097aeb68e41996a9fff9d7Neal Norwitz return pathname 123b0df6a1afa585c5f4d097aeb68e41996a9fff9d7Neal Norwitz if pathname[0] == '/': 124dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé raise ValueError, "path '%s' cannot be absolute" % pathname 125b0df6a1afa585c5f4d097aeb68e41996a9fff9d7Neal Norwitz if pathname[-1] == '/': 126dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé raise ValueError, "path '%s' cannot end with '/'" % pathname 1277ec053544cf4849a138e70329ffeec1d6ab93e62Greg Ward 128dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé paths = string.split(pathname, '/') 129b4cd5c1a3aa11a7b7a180fe1d241968392ab8e33Jack Jansen while '.' in paths: 130b4cd5c1a3aa11a7b7a180fe1d241968392ab8e33Jack Jansen paths.remove('.') 131b4cd5c1a3aa11a7b7a180fe1d241968392ab8e33Jack Jansen if not paths: 132b4cd5c1a3aa11a7b7a180fe1d241968392ab8e33Jack Jansen return os.curdir 1338d1da0f5c3b8c6e3fa29e6ae7f891f699a041bb6Florent Xicluna return os.path.join(*paths) 1345091929c2cf04bfbd545835d2435e43bda6afa05Greg Ward 135dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé# convert_path () 1361b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward 1371b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward 138dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadédef change_root (new_root, pathname): 139dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé """Return 'pathname' with 'new_root' prepended. If 'pathname' is 140dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé relative, this is equivalent to "os.path.join(new_root,pathname)". 14167f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward Otherwise, it requires making 'pathname' relative and then joining the 1424b46ef9a4f35c50eed2e0993058be0cfe71e0b3bGreg Ward two, which is tricky on DOS/Windows and Mac OS. 1434b46ef9a4f35c50eed2e0993058be0cfe71e0b3bGreg Ward """ 1444b46ef9a4f35c50eed2e0993058be0cfe71e0b3bGreg Ward if os.name == 'posix': 145be86bdea734bc53b25698ff5961183cbb5352ffdGreg Ward if not os.path.isabs(pathname): 146be86bdea734bc53b25698ff5961183cbb5352ffdGreg Ward return os.path.join(new_root, pathname) 1474b46ef9a4f35c50eed2e0993058be0cfe71e0b3bGreg Ward else: 148be86bdea734bc53b25698ff5961183cbb5352ffdGreg Ward return os.path.join(new_root, pathname[1:]) 14967f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward 15067f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward elif os.name == 'nt': 151be86bdea734bc53b25698ff5961183cbb5352ffdGreg Ward (drive, path) = os.path.splitdrive(pathname) 1524b46ef9a4f35c50eed2e0993058be0cfe71e0b3bGreg Ward if path[0] == '\\': 1534b46ef9a4f35c50eed2e0993058be0cfe71e0b3bGreg Ward path = path[1:] 154be86bdea734bc53b25698ff5961183cbb5352ffdGreg Ward return os.path.join(new_root, path) 15567f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward 1562544f51036c51d87be53f6a5e35e867c8333378aMarc-André Lemburg elif os.name == 'os2': 1572544f51036c51d87be53f6a5e35e867c8333378aMarc-André Lemburg (drive, path) = os.path.splitdrive(pathname) 1582544f51036c51d87be53f6a5e35e867c8333378aMarc-André Lemburg if path[0] == os.sep: 1592544f51036c51d87be53f6a5e35e867c8333378aMarc-André Lemburg path = path[1:] 1602544f51036c51d87be53f6a5e35e867c8333378aMarc-André Lemburg return os.path.join(new_root, path) 1612544f51036c51d87be53f6a5e35e867c8333378aMarc-André Lemburg 16267f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward else: 163dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé raise DistutilsPlatformError, \ 164dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé "nothing known about platform '%s'" % os.name 16567f75d4bcb3630c0f5b6761fb758072cc342157eGreg Ward 1663757fbba2572133443c250858fcd65c50bf68058Tarek Ziadé 167dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé_environ_checked = 0 168dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadédef check_environ (): 169dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé """Ensure that 'os.environ' has all the environment variables we 170dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé guarantee that users can use in config files, command-line options, 171b8b263b92f33162d0b1bd35f44a17e5538b9713fGreg Ward etc. Currently this includes: 172b8b263b92f33162d0b1bd35f44a17e5538b9713fGreg Ward HOME - user's home directory (Unix only) 173b8b263b92f33162d0b1bd35f44a17e5538b9713fGreg Ward PLAT - description of the current platform, including hardware 174b8b263b92f33162d0b1bd35f44a17e5538b9713fGreg Ward and OS (see 'get_platform()') 1751b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward """ 176e7e35ac1c2e3c6b6a0836931b5c678d6af17129cGregory P. Smith global _environ_checked 177e7e35ac1c2e3c6b6a0836931b5c678d6af17129cGregory P. Smith if _environ_checked: 178e7e35ac1c2e3c6b6a0836931b5c678d6af17129cGregory P. Smith return 179e7e35ac1c2e3c6b6a0836931b5c678d6af17129cGregory P. Smith 1808bc0965adfbe55926a475370c70a8366462dacccGuido van Rossum if os.name == 'posix' and 'HOME' not in os.environ: 1811b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward import pwd 182be86bdea734bc53b25698ff5961183cbb5352ffdGreg Ward os.environ['HOME'] = pwd.getpwuid(os.getuid())[5] 1831b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward 1848bc0965adfbe55926a475370c70a8366462dacccGuido van Rossum if 'PLAT' not in os.environ: 185dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé os.environ['PLAT'] = get_platform() 1861b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward 187e7e35ac1c2e3c6b6a0836931b5c678d6af17129cGregory P. Smith _environ_checked = 1 188e7e35ac1c2e3c6b6a0836931b5c678d6af17129cGregory P. Smith 1891b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward 190dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadédef subst_vars (s, local_vars): 191dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé """Perform shell/Perl-style variable substitution on 'string'. Every 192dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé occurrence of '$' followed by a name is considered a variable, and 1934752769d08c3ef950d31b926751d5e4d1dae294fGreg Ward variable is substituted by the value found in the 'local_vars' 1944752769d08c3ef950d31b926751d5e4d1dae294fGreg Ward dictionary, or in 'os.environ' if it's not in 'local_vars'. 1954752769d08c3ef950d31b926751d5e4d1dae294fGreg Ward 'os.environ' is first checked/augmented to guarantee that it contains 1964752769d08c3ef950d31b926751d5e4d1dae294fGreg Ward certain values: see 'check_environ()'. Raise ValueError for any 1974752769d08c3ef950d31b926751d5e4d1dae294fGreg Ward variables not found in either 'local_vars' or 'os.environ'. 198b8b263b92f33162d0b1bd35f44a17e5538b9713fGreg Ward """ 199be86bdea734bc53b25698ff5961183cbb5352ffdGreg Ward check_environ() 2001b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward def _subst (match, local_vars=local_vars): 2011b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward var_name = match.group(1) 2028bc0965adfbe55926a475370c70a8366462dacccGuido van Rossum if var_name in local_vars: 203be86bdea734bc53b25698ff5961183cbb5352ffdGreg Ward return str(local_vars[var_name]) 2041b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward else: 2051b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward return os.environ[var_name] 2061b4ede5f24814dc4baa8832414093aa745c3755cGreg Ward 2074752769d08c3ef950d31b926751d5e4d1dae294fGreg Ward try: 2085e2d0764cd95b40de64fff54e14091e0e6bdf6f6Jeremy Hylton return re.sub(r'\$([a-zA-Z_][a-zA-Z_0-9]*)', _subst, s) 2094752769d08c3ef950d31b926751d5e4d1dae294fGreg Ward except KeyError, var: 210dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé raise ValueError, "invalid variable '$%s'" % var 211dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé 212dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé# subst_vars () 2137c1a6d477771955e3773849ef636fceda81bb3d5Greg Ward 2147c1a6d477771955e3773849ef636fceda81bb3d5Greg Ward 215dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadédef grok_environment_error (exc, prefix="error: "): 2163d1134e39551cd4277538f1fa9137fdf238d07fbÉric Araujo # Function kept for backward compatibility. 2173d1134e39551cd4277538f1fa9137fdf238d07fbÉric Araujo # Used to try clever things with EnvironmentErrors, 2183d1134e39551cd4277538f1fa9137fdf238d07fbÉric Araujo # but nowadays str(exception) produces good messages. 2193d1134e39551cd4277538f1fa9137fdf238d07fbÉric Araujo return prefix + str(exc) 2206a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward 221dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé 2226a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward# Needed by 'split_quoted()' 2231c0f1f97fb9021a2084298e04aa920d5f478f0c6Martin v. Löwis_wordchars_re = _squote_re = _dquote_re = None 2241c0f1f97fb9021a2084298e04aa920d5f478f0c6Martin v. Löwisdef _init_regex(): 2251c0f1f97fb9021a2084298e04aa920d5f478f0c6Martin v. Löwis global _wordchars_re, _squote_re, _dquote_re 2261c0f1f97fb9021a2084298e04aa920d5f478f0c6Martin v. Löwis _wordchars_re = re.compile(r'[^\\\'\"%s ]*' % string.whitespace) 2271c0f1f97fb9021a2084298e04aa920d5f478f0c6Martin v. Löwis _squote_re = re.compile(r"'(?:[^'\\]|\\.)*'") 2281c0f1f97fb9021a2084298e04aa920d5f478f0c6Martin v. Löwis _dquote_re = re.compile(r'"(?:[^"\\]|\\.)*"') 2296a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward 230dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadédef split_quoted (s): 2316a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward """Split a string up according to Unix shell-like rules for quotes and 232dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé backslashes. In short: words are delimited by spaces, as long as those 2336a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward spaces are not escaped by a backslash, or inside a quoted string. 2346a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward Single and double quotes are equivalent, and the quote characters can 2356a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward be backslash-escaped. The backslash is stripped from any two-character 2366a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward escape sequence, leaving only the escaped character. The quote 2376a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward characters are stripped from any quoted string. Returns a list of 2386a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward words. 2396a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward """ 240dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé 2416a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward # This is a nice algorithm for splitting up a single string, since it 2426a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward # doesn't require character-by-character examination. It was a little 2436a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward # bit of a brain-bender to get it working right, though... 2441c0f1f97fb9021a2084298e04aa920d5f478f0c6Martin v. Löwis if _wordchars_re is None: _init_regex() 2456a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward 246dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé s = string.strip(s) 2476a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward words = [] 2486a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward pos = 0 2496a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward 2506a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward while s: 2516a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward m = _wordchars_re.match(s, pos) 2526a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward end = m.end() 2536a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward if end == len(s): 2546a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward words.append(s[:end]) 2556a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward break 2566a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward 2572b042ded19bc7efa43551da297c29dc142b7d73cGreg Ward if s[end] in string.whitespace: # unescaped, unquoted whitespace: now 2586a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward words.append(s[:end]) # we definitely have a word delimiter 259dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé s = string.lstrip(s[end:]) 2606a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward pos = 0 2616a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward 2626a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward elif s[end] == '\\': # preserve whatever is being escaped; 2636a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward # will become part of the current word 2646a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward s = s[:end] + s[end+1:] 2656a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward pos = end+1 2666a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward 2676a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward else: 2686a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward if s[end] == "'": # slurp singly-quoted string 2696a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward m = _squote_re.match(s, end) 2706a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward elif s[end] == '"': # slurp doubly-quoted string 2716a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward m = _dquote_re.match(s, end) 2726a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward else: 273dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé raise RuntimeError, \ 274dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé "this can't happen (bad char '%c')" % s[end] 2756a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward 2766a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward if m is None: 277dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé raise ValueError, \ 278dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé "bad string (mismatched %s quotes?)" % s[end] 2796a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward 2806a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward (beg, end) = m.span() 2816a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward s = s[:beg] + s[beg+1:end-1] + s[end:] 2826a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward pos = m.end() - 2 2836a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward 2846a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward if pos >= len(s): 2856a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward words.append(s) 2866a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward break 2876a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward 2886a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward return words 2896a2a3dbec59f267e05c0c507457dfd234263237bGreg Ward 290dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé# split_quoted () 2911c16ac360a3fc63bfb1008c3a935907fe9064f26Greg Ward 2921c16ac360a3fc63bfb1008c3a935907fe9064f26Greg Ward 293dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadédef execute (func, args, msg=None, verbose=0, dry_run=0): 294dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé """Perform some action that affects the outside world (eg. by 295dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé writing to the filesystem). Such actions are special because they 296dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé are disabled by the 'dry_run' flag. This method takes care of all 297cd8a1148e19116db109f27d26c02e1de536dc76eJeremy Hylton that bureaucracy for you; all you have to do is supply the 298cd8a1148e19116db109f27d26c02e1de536dc76eJeremy Hylton function to call and an argument tuple for it (to embody the 299cd8a1148e19116db109f27d26c02e1de536dc76eJeremy Hylton "external action" being performed), and an optional message to 300cd8a1148e19116db109f27d26c02e1de536dc76eJeremy Hylton print. 3011c16ac360a3fc63bfb1008c3a935907fe9064f26Greg Ward """ 3021c16ac360a3fc63bfb1008c3a935907fe9064f26Greg Ward if msg is None: 30370a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald msg = "%s%r" % (func.__name__, args) 304b94b849d65af71b4b432a74fdaef8ccd88209cc0Fred Drake if msg[-2:] == ',)': # correct for singleton tuple 3051c16ac360a3fc63bfb1008c3a935907fe9064f26Greg Ward msg = msg[0:-2] + ')' 3061c16ac360a3fc63bfb1008c3a935907fe9064f26Greg Ward 307cd8a1148e19116db109f27d26c02e1de536dc76eJeremy Hylton log.info(msg) 3081c16ac360a3fc63bfb1008c3a935907fe9064f26Greg Ward if not dry_run: 3091f3b4e12e8ba9cd896625ba02ea1ab6849ca3a07Florent Xicluna func(*args) 3101c16ac360a3fc63bfb1008c3a935907fe9064f26Greg Ward 311817dc098efd0c2cba674cee32950fc5626e12881Greg Ward 312dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadédef strtobool (val): 313817dc098efd0c2cba674cee32950fc5626e12881Greg Ward """Convert a string representation of truth to true (1) or false (0). 314182b5aca27d376b08a2904bed42b751496f932f3Tim Peters 315817dc098efd0c2cba674cee32950fc5626e12881Greg Ward True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values 316817dc098efd0c2cba674cee32950fc5626e12881Greg Ward are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if 317817dc098efd0c2cba674cee32950fc5626e12881Greg Ward 'val' is anything else. 318817dc098efd0c2cba674cee32950fc5626e12881Greg Ward """ 319dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé val = string.lower(val) 320817dc098efd0c2cba674cee32950fc5626e12881Greg Ward if val in ('y', 'yes', 't', 'true', 'on', '1'): 321817dc098efd0c2cba674cee32950fc5626e12881Greg Ward return 1 322817dc098efd0c2cba674cee32950fc5626e12881Greg Ward elif val in ('n', 'no', 'f', 'false', 'off', '0'): 323817dc098efd0c2cba674cee32950fc5626e12881Greg Ward return 0 324817dc098efd0c2cba674cee32950fc5626e12881Greg Ward else: 32570a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald raise ValueError, "invalid truth value %r" % (val,) 3261297b5ce67642dba35615121825fb1621e28e6b8Greg Ward 3271297b5ce67642dba35615121825fb1621e28e6b8Greg Ward 328dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadédef byte_compile (py_files, 329dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé optimize=0, force=0, 330dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé prefix=None, base_dir=None, 331dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé verbose=1, dry_run=0, 332dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé direct=None): 333f217e2124a9b57dc13513ea4f9e430413135269eGreg Ward """Byte-compile a collection of Python source files to either .pyc 334dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé or .pyo files in the same directory. 'py_files' is a list of files 335dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé to compile; any files that don't end in ".py" are silently skipped. 336dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé 'optimize' must be one of the following: 3371297b5ce67642dba35615121825fb1621e28e6b8Greg Ward 0 - don't optimize (generate .pyc) 3381297b5ce67642dba35615121825fb1621e28e6b8Greg Ward 1 - normal optimization (like "python -O") 3391297b5ce67642dba35615121825fb1621e28e6b8Greg Ward 2 - extra optimization (like "python -OO") 3401297b5ce67642dba35615121825fb1621e28e6b8Greg Ward If 'force' is true, all files are recompiled regardless of 3411297b5ce67642dba35615121825fb1621e28e6b8Greg Ward timestamps. 3421297b5ce67642dba35615121825fb1621e28e6b8Greg Ward 3431297b5ce67642dba35615121825fb1621e28e6b8Greg Ward The source filename encoded in each bytecode file defaults to the 3441297b5ce67642dba35615121825fb1621e28e6b8Greg Ward filenames listed in 'py_files'; you can modify these with 'prefix' and 3451297b5ce67642dba35615121825fb1621e28e6b8Greg Ward 'basedir'. 'prefix' is a string that will be stripped off of each 3461297b5ce67642dba35615121825fb1621e28e6b8Greg Ward source filename, and 'base_dir' is a directory name that will be 3471297b5ce67642dba35615121825fb1621e28e6b8Greg Ward prepended (after 'prefix' is stripped). You can supply either or both 3481297b5ce67642dba35615121825fb1621e28e6b8Greg Ward (or neither) of 'prefix' and 'base_dir', as you wish. 3491297b5ce67642dba35615121825fb1621e28e6b8Greg Ward 350cd8a1148e19116db109f27d26c02e1de536dc76eJeremy Hylton If 'dry_run' is true, doesn't actually do anything that would 351cd8a1148e19116db109f27d26c02e1de536dc76eJeremy Hylton affect the filesystem. 3521297b5ce67642dba35615121825fb1621e28e6b8Greg Ward 3531297b5ce67642dba35615121825fb1621e28e6b8Greg Ward Byte-compilation is either done directly in this interpreter process 3541297b5ce67642dba35615121825fb1621e28e6b8Greg Ward with the standard py_compile module, or indirectly by writing a 3551297b5ce67642dba35615121825fb1621e28e6b8Greg Ward temporary script and executing it. Normally, you should let 3561297b5ce67642dba35615121825fb1621e28e6b8Greg Ward 'byte_compile()' figure out to use direct compilation or not (see 3571297b5ce67642dba35615121825fb1621e28e6b8Greg Ward the source for details). The 'direct' flag is used by the script 3581297b5ce67642dba35615121825fb1621e28e6b8Greg Ward generated in indirect mode; unless you know what you're doing, leave 3591297b5ce67642dba35615121825fb1621e28e6b8Greg Ward it set to None. 3601297b5ce67642dba35615121825fb1621e28e6b8Greg Ward """ 361b9c1cfc42881370322ff6894568b45dcfec5ba2eTarek Ziadé # nothing is done if sys.dont_write_bytecode is True 362b9c1cfc42881370322ff6894568b45dcfec5ba2eTarek Ziadé if sys.dont_write_bytecode: 3631733c9362b7520278120423550de28da44d15f33Tarek Ziadé raise DistutilsByteCompileError('byte-compiling is disabled.') 364b9c1cfc42881370322ff6894568b45dcfec5ba2eTarek Ziadé 3651297b5ce67642dba35615121825fb1621e28e6b8Greg Ward # First, if the caller didn't force us into direct or indirect mode, 3661297b5ce67642dba35615121825fb1621e28e6b8Greg Ward # figure out which mode we should be in. We take a conservative 3671297b5ce67642dba35615121825fb1621e28e6b8Greg Ward # approach: choose direct mode *only* if the current interpreter is 3681297b5ce67642dba35615121825fb1621e28e6b8Greg Ward # in debug mode and optimize is 0. If we're not in debug mode (-O 3691297b5ce67642dba35615121825fb1621e28e6b8Greg Ward # or -OO), we don't know which level of optimization this 3701297b5ce67642dba35615121825fb1621e28e6b8Greg Ward # interpreter is running with, so we can't do direct 3711297b5ce67642dba35615121825fb1621e28e6b8Greg Ward # byte-compilation and be certain that it's the right thing. Thus, 3721297b5ce67642dba35615121825fb1621e28e6b8Greg Ward # always compile indirectly if the current interpreter is in either 3731297b5ce67642dba35615121825fb1621e28e6b8Greg Ward # optimize mode, or if either optimization level was requested by 3741297b5ce67642dba35615121825fb1621e28e6b8Greg Ward # the caller. 3751297b5ce67642dba35615121825fb1621e28e6b8Greg Ward if direct is None: 3761297b5ce67642dba35615121825fb1621e28e6b8Greg Ward direct = (__debug__ and optimize == 0) 3771297b5ce67642dba35615121825fb1621e28e6b8Greg Ward 3781297b5ce67642dba35615121825fb1621e28e6b8Greg Ward # "Indirect" byte-compilation: write a temporary script and then 3791297b5ce67642dba35615121825fb1621e28e6b8Greg Ward # run it with the appropriate flags. 3801297b5ce67642dba35615121825fb1621e28e6b8Greg Ward if not direct: 3810375079e934156491ffe04771d7f4470f391377eMarc-André Lemburg try: 3820375079e934156491ffe04771d7f4470f391377eMarc-André Lemburg from tempfile import mkstemp 3830375079e934156491ffe04771d7f4470f391377eMarc-André Lemburg (script_fd, script_name) = mkstemp(".py") 3840375079e934156491ffe04771d7f4470f391377eMarc-André Lemburg except ImportError: 3850375079e934156491ffe04771d7f4470f391377eMarc-André Lemburg from tempfile import mktemp 3860375079e934156491ffe04771d7f4470f391377eMarc-André Lemburg (script_fd, script_name) = None, mktemp(".py") 387cd8a1148e19116db109f27d26c02e1de536dc76eJeremy Hylton log.info("writing byte-compilation script '%s'", script_name) 3881297b5ce67642dba35615121825fb1621e28e6b8Greg Ward if not dry_run: 3890375079e934156491ffe04771d7f4470f391377eMarc-André Lemburg if script_fd is not None: 3900375079e934156491ffe04771d7f4470f391377eMarc-André Lemburg script = os.fdopen(script_fd, "w") 3910375079e934156491ffe04771d7f4470f391377eMarc-André Lemburg else: 3920375079e934156491ffe04771d7f4470f391377eMarc-André Lemburg script = open(script_name, "w") 3931297b5ce67642dba35615121825fb1621e28e6b8Greg Ward 3941297b5ce67642dba35615121825fb1621e28e6b8Greg Ward script.write("""\ 3951297b5ce67642dba35615121825fb1621e28e6b8Greg Wardfrom distutils.util import byte_compile 3961297b5ce67642dba35615121825fb1621e28e6b8Greg Wardfiles = [ 3971297b5ce67642dba35615121825fb1621e28e6b8Greg Ward""") 3989216cfe7ba0257f10790f919e50283114a3476ddGreg Ward 3999216cfe7ba0257f10790f919e50283114a3476ddGreg Ward # XXX would be nice to write absolute filenames, just for 4009216cfe7ba0257f10790f919e50283114a3476ddGreg Ward # safety's sake (script should be more robust in the face of 4019216cfe7ba0257f10790f919e50283114a3476ddGreg Ward # chdir'ing before running it). But this requires abspath'ing 4029216cfe7ba0257f10790f919e50283114a3476ddGreg Ward # 'prefix' as well, and that breaks the hack in build_lib's 4039216cfe7ba0257f10790f919e50283114a3476ddGreg Ward # 'byte_compile()' method that carefully tacks on a trailing 4049216cfe7ba0257f10790f919e50283114a3476ddGreg Ward # slash (os.sep really) to make sure the prefix here is "just 4059216cfe7ba0257f10790f919e50283114a3476ddGreg Ward # right". This whole prefix business is rather delicate -- the 4069216cfe7ba0257f10790f919e50283114a3476ddGreg Ward # problem is that it's really a directory, but I'm treating it 4079216cfe7ba0257f10790f919e50283114a3476ddGreg Ward # as a dumb string, so trailing slashes and so forth matter. 4089216cfe7ba0257f10790f919e50283114a3476ddGreg Ward 4099216cfe7ba0257f10790f919e50283114a3476ddGreg Ward #py_files = map(os.path.abspath, py_files) 4109216cfe7ba0257f10790f919e50283114a3476ddGreg Ward #if prefix: 4119216cfe7ba0257f10790f919e50283114a3476ddGreg Ward # prefix = os.path.abspath(prefix) 4129216cfe7ba0257f10790f919e50283114a3476ddGreg Ward 413dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé script.write(string.join(map(repr, py_files), ",\n") + "]\n") 4141297b5ce67642dba35615121825fb1621e28e6b8Greg Ward script.write(""" 41570a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwaldbyte_compile(files, optimize=%r, force=%r, 41670a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald prefix=%r, base_dir=%r, 41770a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald verbose=%r, dry_run=0, 4181297b5ce67642dba35615121825fb1621e28e6b8Greg Ward direct=1) 41970a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald""" % (optimize, force, prefix, base_dir, verbose)) 4201297b5ce67642dba35615121825fb1621e28e6b8Greg Ward 4211297b5ce67642dba35615121825fb1621e28e6b8Greg Ward script.close() 4221297b5ce67642dba35615121825fb1621e28e6b8Greg Ward 4231297b5ce67642dba35615121825fb1621e28e6b8Greg Ward cmd = [sys.executable, script_name] 4241297b5ce67642dba35615121825fb1621e28e6b8Greg Ward if optimize == 1: 4251297b5ce67642dba35615121825fb1621e28e6b8Greg Ward cmd.insert(1, "-O") 4261297b5ce67642dba35615121825fb1621e28e6b8Greg Ward elif optimize == 2: 4271297b5ce67642dba35615121825fb1621e28e6b8Greg Ward cmd.insert(1, "-OO") 428cd8a1148e19116db109f27d26c02e1de536dc76eJeremy Hylton spawn(cmd, dry_run=dry_run) 4299216cfe7ba0257f10790f919e50283114a3476ddGreg Ward execute(os.remove, (script_name,), "removing %s" % script_name, 430cd8a1148e19116db109f27d26c02e1de536dc76eJeremy Hylton dry_run=dry_run) 431b94b849d65af71b4b432a74fdaef8ccd88209cc0Fred Drake 4321297b5ce67642dba35615121825fb1621e28e6b8Greg Ward # "Direct" byte-compilation: use the py_compile module to compile 4331297b5ce67642dba35615121825fb1621e28e6b8Greg Ward # right here, right now. Note that the script generated in indirect 4341297b5ce67642dba35615121825fb1621e28e6b8Greg Ward # mode simply calls 'byte_compile()' in direct mode, a weird sort of 4351297b5ce67642dba35615121825fb1621e28e6b8Greg Ward # cross-process recursion. Hey, it works! 4361297b5ce67642dba35615121825fb1621e28e6b8Greg Ward else: 4371297b5ce67642dba35615121825fb1621e28e6b8Greg Ward from py_compile import compile 4381297b5ce67642dba35615121825fb1621e28e6b8Greg Ward 4391297b5ce67642dba35615121825fb1621e28e6b8Greg Ward for file in py_files: 4401297b5ce67642dba35615121825fb1621e28e6b8Greg Ward if file[-3:] != ".py": 441f217e2124a9b57dc13513ea4f9e430413135269eGreg Ward # This lets us be lazy and not filter filenames in 442f217e2124a9b57dc13513ea4f9e430413135269eGreg Ward # the "install_lib" command. 443f217e2124a9b57dc13513ea4f9e430413135269eGreg Ward continue 4441297b5ce67642dba35615121825fb1621e28e6b8Greg Ward 4451297b5ce67642dba35615121825fb1621e28e6b8Greg Ward # Terminology from the py_compile module: 4461297b5ce67642dba35615121825fb1621e28e6b8Greg Ward # cfile - byte-compiled file 4471297b5ce67642dba35615121825fb1621e28e6b8Greg Ward # dfile - purported source filename (same as 'file' by default) 4481297b5ce67642dba35615121825fb1621e28e6b8Greg Ward cfile = file + (__debug__ and "c" or "o") 4491297b5ce67642dba35615121825fb1621e28e6b8Greg Ward dfile = file 4501297b5ce67642dba35615121825fb1621e28e6b8Greg Ward if prefix: 4511297b5ce67642dba35615121825fb1621e28e6b8Greg Ward if file[:len(prefix)] != prefix: 452dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé raise ValueError, \ 453dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé ("invalid prefix: filename %r doesn't start with %r" 454dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé % (file, prefix)) 4551297b5ce67642dba35615121825fb1621e28e6b8Greg Ward dfile = dfile[len(prefix):] 4561297b5ce67642dba35615121825fb1621e28e6b8Greg Ward if base_dir: 4571297b5ce67642dba35615121825fb1621e28e6b8Greg Ward dfile = os.path.join(base_dir, dfile) 4581297b5ce67642dba35615121825fb1621e28e6b8Greg Ward 4591297b5ce67642dba35615121825fb1621e28e6b8Greg Ward cfile_base = os.path.basename(cfile) 4601297b5ce67642dba35615121825fb1621e28e6b8Greg Ward if direct: 4611297b5ce67642dba35615121825fb1621e28e6b8Greg Ward if force or newer(file, cfile): 462cd8a1148e19116db109f27d26c02e1de536dc76eJeremy Hylton log.info("byte-compiling %s to %s", file, cfile_base) 4631297b5ce67642dba35615121825fb1621e28e6b8Greg Ward if not dry_run: 4641297b5ce67642dba35615121825fb1621e28e6b8Greg Ward compile(file, cfile, dfile) 4651297b5ce67642dba35615121825fb1621e28e6b8Greg Ward else: 466cd8a1148e19116db109f27d26c02e1de536dc76eJeremy Hylton log.debug("skipping byte-compilation of %s to %s", 467cd8a1148e19116db109f27d26c02e1de536dc76eJeremy Hylton file, cfile_base) 4681297b5ce67642dba35615121825fb1621e28e6b8Greg Ward 469dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé# byte_compile () 470df66df0a286c5d09022e7efe839759797318506cAndrew M. Kuchling 471dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadédef rfc822_escape (header): 472df66df0a286c5d09022e7efe839759797318506cAndrew M. Kuchling """Return a version of the string escaped for inclusion in an 47388b0884787f06667f59ebaab5413f3bedcdd631cAndrew M. Kuchling RFC-822 header, by ensuring there are 8 spaces space after each newline. 474df66df0a286c5d09022e7efe839759797318506cAndrew M. Kuchling """ 475dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé lines = string.split(header, '\n') 476dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé header = string.join(lines, '\n' + 8*' ') 477dd7bef9bf56933851e68094ffc70f8f20bc6b036Tarek Ziadé return header 478