OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 """Create a "virtual" Python installation | 2 """Create a "virtual" Python installation""" |
3 """ | |
4 | 3 |
5 __version__ = "12.0" | 4 import os |
6 virtualenv_version = __version__ # legacy | 5 import sys |
7 | 6 |
8 # NB: avoid placing additional imports here, before sys.path is fixed! | 7 # If we are running in a new interpreter to create a virtualenv, |
9 | 8 # we do NOT want paths from our existing location interfering with anything, |
10 import sys | 9 # So we remove this file's directory from sys.path - most likely to be |
11 import os | 10 # the previous interpreter's site-packages. Solves #705, #763, #779 |
12 | |
13 # | |
14 # RATIONALE: | |
15 # This script is both it's own "host" and "guest". If it's running in "guest | |
16 # mode" (inside the virtualenv interpreter), it's essentially invoked via: | |
17 # /path/to/python /path/to/this/script.py | |
18 # | |
19 # Which, by the nature of Python, will put `/path/to/this` on the system path | |
20 # as the first argument. Now this can cause many subtle bugs, because the | |
21 # rest of the script is now looking to import from the "host" Python version | |
22 # first. This has been especially troublesome when trying to create a Python | |
23 # 3 "guest" env using a Python 2 "host", but even with minor Python | |
24 # differences, there may been some bleeding between environments that doesn't | |
25 # stand out as obviously. | |
26 # | |
27 # This removes the first argument off the system path, to avoid any accidental | |
28 # usage of the "host" library directories. | |
29 # | |
30 if os.environ.get('VIRTUALENV_INTERPRETER_RUNNING'): | 11 if os.environ.get('VIRTUALENV_INTERPRETER_RUNNING'): |
31 del sys.path[0] | 12 for path in sys.path[:]: |
| 13 if os.path.realpath(os.path.dirname(__file__)) == os.path.realpath(path)
: |
| 14 sys.path.remove(path) |
32 | 15 |
33 import base64 | 16 import base64 |
34 import codecs | 17 import codecs |
35 import optparse | 18 import optparse |
36 import re | 19 import re |
37 import shutil | 20 import shutil |
38 import logging | 21 import logging |
39 import tempfile | |
40 import zlib | 22 import zlib |
41 import errno | 23 import errno |
42 import glob | 24 import glob |
43 import distutils.sysconfig | 25 import distutils.sysconfig |
44 from distutils.util import strtobool | |
45 import struct | 26 import struct |
46 import subprocess | 27 import subprocess |
47 import tarfile | 28 import pkgutil |
| 29 import tempfile |
| 30 import textwrap |
| 31 from distutils.util import strtobool |
| 32 from os.path import join |
| 33 |
| 34 try: |
| 35 import ConfigParser |
| 36 except ImportError: |
| 37 import configparser as ConfigParser |
| 38 |
| 39 __version__ = "15.1.0" |
| 40 virtualenv_version = __version__ # legacy |
48 | 41 |
49 if sys.version_info < (2, 6): | 42 if sys.version_info < (2, 6): |
50 print('ERROR: %s' % sys.exc_info()[1]) | 43 print('ERROR: %s' % sys.exc_info()[1]) |
51 print('ERROR: this script requires Python 2.6 or greater.') | 44 print('ERROR: this script requires Python 2.6 or greater.') |
52 sys.exit(101) | 45 sys.exit(101) |
53 | 46 |
54 try: | 47 try: |
55 basestring | 48 basestring |
56 except NameError: | 49 except NameError: |
57 basestring = str | 50 basestring = str |
58 | 51 |
59 try: | |
60 import ConfigParser | |
61 except ImportError: | |
62 import configparser as ConfigParser | |
63 | |
64 join = os.path.join | |
65 py_version = 'python%s.%s' % (sys.version_info[0], sys.version_info[1]) | 52 py_version = 'python%s.%s' % (sys.version_info[0], sys.version_info[1]) |
66 | 53 |
67 is_jython = sys.platform.startswith('java') | 54 is_jython = sys.platform.startswith('java') |
68 is_pypy = hasattr(sys, 'pypy_version_info') | 55 is_pypy = hasattr(sys, 'pypy_version_info') |
69 is_win = (sys.platform == 'win32') | 56 is_win = (sys.platform == 'win32') |
70 is_cygwin = (sys.platform == 'cygwin') | 57 is_cygwin = (sys.platform == 'cygwin') |
71 is_darwin = (sys.platform == 'darwin') | 58 is_darwin = (sys.platform == 'darwin') |
72 abiflags = getattr(sys, 'abiflags', '') | 59 abiflags = getattr(sys, 'abiflags', '') |
73 | 60 |
74 user_dir = os.path.expanduser('~') | 61 user_dir = os.path.expanduser('~') |
(...skipping 17 matching lines...) Expand all Loading... |
92 return {} | 79 return {} |
93 else: | 80 else: |
94 try: | 81 try: |
95 import winreg | 82 import winreg |
96 except ImportError: | 83 except ImportError: |
97 import _winreg as winreg | 84 import _winreg as winreg |
98 | 85 |
99 def get_installed_pythons(): | 86 def get_installed_pythons(): |
100 try: | 87 try: |
101 python_core = winreg.CreateKey(winreg.HKEY_LOCAL_MACHINE, | 88 python_core = winreg.CreateKey(winreg.HKEY_LOCAL_MACHINE, |
102 "Software\\Python\\PythonCore") | 89 "Software\\Python\\PythonCore") |
103 except WindowsError: | 90 except WindowsError: |
104 # No registered Python installations | 91 # No registered Python installations |
105 return {} | 92 return {} |
106 i = 0 | 93 i = 0 |
107 versions = [] | 94 versions = [] |
108 while True: | 95 while True: |
109 try: | 96 try: |
110 versions.append(winreg.EnumKey(python_core, i)) | 97 versions.append(winreg.EnumKey(python_core, i)) |
111 i = i + 1 | 98 i = i + 1 |
112 except WindowsError: | 99 except WindowsError: |
(...skipping 26 matching lines...) Expand all Loading... |
139 | 126 |
140 majver, minver = sys.version_info[:2] | 127 majver, minver = sys.version_info[:2] |
141 if majver == 2: | 128 if majver == 2: |
142 if minver >= 6: | 129 if minver >= 6: |
143 REQUIRED_MODULES.extend(['warnings', 'linecache', '_abcoll', 'abc']) | 130 REQUIRED_MODULES.extend(['warnings', 'linecache', '_abcoll', 'abc']) |
144 if minver >= 7: | 131 if minver >= 7: |
145 REQUIRED_MODULES.extend(['_weakrefset']) | 132 REQUIRED_MODULES.extend(['_weakrefset']) |
146 elif majver == 3: | 133 elif majver == 3: |
147 # Some extra modules are needed for Python 3, but different ones | 134 # Some extra modules are needed for Python 3, but different ones |
148 # for different versions. | 135 # for different versions. |
149 REQUIRED_MODULES.extend(['_abcoll', 'warnings', 'linecache', 'abc', 'io', | 136 REQUIRED_MODULES.extend([ |
150 '_weakrefset', 'copyreg', 'tempfile', 'random', | 137 » '_abcoll', 'warnings', 'linecache', 'abc', 'io', '_weakrefset', |
151 '__future__', 'collections', 'keyword', 'tarfile', | 138 » 'copyreg', 'tempfile', 'random', '__future__', 'collections', |
152 'shutil', 'struct', 'copy', 'tokenize', 'token', | 139 » 'keyword', 'tarfile', 'shutil', 'struct', 'copy', 'tokenize', |
153 'functools', 'heapq', 'bisect', 'weakref', | 140 » 'token', 'functools', 'heapq', 'bisect', 'weakref', 'reprlib' |
154 'reprlib']) | 141 ]) |
155 if minver >= 2: | 142 if minver >= 2: |
156 REQUIRED_FILES[-1] = 'config-%s' % majver | 143 REQUIRED_FILES[-1] = 'config-%s' % majver |
157 if minver >= 3: | 144 if minver >= 3: |
158 import sysconfig | 145 import sysconfig |
159 platdir = sysconfig.get_config_var('PLATDIR') | 146 platdir = sysconfig.get_config_var('PLATDIR') |
160 REQUIRED_FILES.append(platdir) | 147 REQUIRED_FILES.append(platdir) |
161 # The whole list of 3.3 modules is reproduced below - the current | |
162 # uncommented ones are required for 3.3 as of now, but more may be | |
163 # added as 3.3 development continues. | |
164 REQUIRED_MODULES.extend([ | 148 REQUIRED_MODULES.extend([ |
165 #"aifc", | 149 » 'base64', '_dummy_thread', 'hashlib', 'hmac', |
166 #"antigravity", | 150 » 'imp', 'importlib', 'rlcompleter' |
167 #"argparse", | |
168 #"ast", | |
169 #"asynchat", | |
170 #"asyncore", | |
171 "base64", | |
172 #"bdb", | |
173 #"binhex", | |
174 #"bisect", | |
175 #"calendar", | |
176 #"cgi", | |
177 #"cgitb", | |
178 #"chunk", | |
179 #"cmd", | |
180 #"codeop", | |
181 #"code", | |
182 #"colorsys", | |
183 #"_compat_pickle", | |
184 #"compileall", | |
185 #"concurrent", | |
186 #"configparser", | |
187 #"contextlib", | |
188 #"cProfile", | |
189 #"crypt", | |
190 #"csv", | |
191 #"ctypes", | |
192 #"curses", | |
193 #"datetime", | |
194 #"dbm", | |
195 #"decimal", | |
196 #"difflib", | |
197 #"dis", | |
198 #"doctest", | |
199 #"dummy_threading", | |
200 "_dummy_thread", | |
201 #"email", | |
202 #"filecmp", | |
203 #"fileinput", | |
204 #"formatter", | |
205 #"fractions", | |
206 #"ftplib", | |
207 #"functools", | |
208 #"getopt", | |
209 #"getpass", | |
210 #"gettext", | |
211 #"glob", | |
212 #"gzip", | |
213 "hashlib", | |
214 #"heapq", | |
215 "hmac", | |
216 #"html", | |
217 #"http", | |
218 #"idlelib", | |
219 #"imaplib", | |
220 #"imghdr", | |
221 "imp", | |
222 "importlib", | |
223 #"inspect", | |
224 #"json", | |
225 #"lib2to3", | |
226 #"logging", | |
227 #"macpath", | |
228 #"macurl2path", | |
229 #"mailbox", | |
230 #"mailcap", | |
231 #"_markupbase", | |
232 #"mimetypes", | |
233 #"modulefinder", | |
234 #"multiprocessing", | |
235 #"netrc", | |
236 #"nntplib", | |
237 #"nturl2path", | |
238 #"numbers", | |
239 #"opcode", | |
240 #"optparse", | |
241 #"os2emxpath", | |
242 #"pdb", | |
243 #"pickle", | |
244 #"pickletools", | |
245 #"pipes", | |
246 #"pkgutil", | |
247 #"platform", | |
248 #"plat-linux2", | |
249 #"plistlib", | |
250 #"poplib", | |
251 #"pprint", | |
252 #"profile", | |
253 #"pstats", | |
254 #"pty", | |
255 #"pyclbr", | |
256 #"py_compile", | |
257 #"pydoc_data", | |
258 #"pydoc", | |
259 #"_pyio", | |
260 #"queue", | |
261 #"quopri", | |
262 #"reprlib", | |
263 "rlcompleter", | |
264 #"runpy", | |
265 #"sched", | |
266 #"shelve", | |
267 #"shlex", | |
268 #"smtpd", | |
269 #"smtplib", | |
270 #"sndhdr", | |
271 #"socket", | |
272 #"socketserver", | |
273 #"sqlite3", | |
274 #"ssl", | |
275 #"stringprep", | |
276 #"string", | |
277 #"_strptime", | |
278 #"subprocess", | |
279 #"sunau", | |
280 #"symbol", | |
281 #"symtable", | |
282 #"sysconfig", | |
283 #"tabnanny", | |
284 #"telnetlib", | |
285 #"test", | |
286 #"textwrap", | |
287 #"this", | |
288 #"_threading_local", | |
289 #"threading", | |
290 #"timeit", | |
291 #"tkinter", | |
292 #"tokenize", | |
293 #"token", | |
294 #"traceback", | |
295 #"trace", | |
296 #"tty", | |
297 #"turtledemo", | |
298 #"turtle", | |
299 #"unittest", | |
300 #"urllib", | |
301 #"uuid", | |
302 #"uu", | |
303 #"wave", | |
304 #"weakref", | |
305 #"webbrowser", | |
306 #"wsgiref", | |
307 #"xdrlib", | |
308 #"xml", | |
309 #"xmlrpc", | |
310 #"zipfile", | |
311 ]) | 151 ]) |
312 if minver >= 4: | 152 if minver >= 4: |
313 REQUIRED_MODULES.extend([ | 153 REQUIRED_MODULES.extend([ |
314 'operator', | 154 'operator', |
315 '_collections_abc', | 155 '_collections_abc', |
316 '_bootlocale', | 156 '_bootlocale', |
317 ]) | 157 ]) |
| 158 if minver >= 6: |
| 159 REQUIRED_MODULES.extend(['enum']) |
318 | 160 |
319 if is_pypy: | 161 if is_pypy: |
320 # these are needed to correctly display the exceptions that may happen | 162 # these are needed to correctly display the exceptions that may happen |
321 # during the bootstrap | 163 # during the bootstrap |
322 REQUIRED_MODULES.extend(['traceback', 'linecache']) | 164 REQUIRED_MODULES.extend(['traceback', 'linecache']) |
323 | 165 |
| 166 if majver == 3: |
| 167 # _functools is needed to import locale during stdio initialization and |
| 168 # needs to be copied on PyPy because it's not built in |
| 169 REQUIRED_MODULES.append('_functools') |
| 170 |
| 171 |
324 class Logger(object): | 172 class Logger(object): |
325 | 173 |
326 """ | 174 """ |
327 Logging object for use in command-line script. Allows ranges of | 175 Logging object for use in command-line script. Allows ranges of |
328 levels, to avoid some redundancy of displayed information. | 176 levels, to avoid some redundancy of displayed information. |
329 """ | 177 """ |
330 | 178 |
331 DEBUG = logging.DEBUG | 179 DEBUG = logging.DEBUG |
332 INFO = logging.INFO | 180 INFO = logging.INFO |
333 NOTIFY = (logging.INFO+logging.WARN)/2 | 181 NOTIFY = (logging.INFO+logging.WARN)/2 |
334 WARN = WARNING = logging.WARN | 182 WARN = WARNING = logging.WARN |
335 ERROR = logging.ERROR | 183 ERROR = logging.ERROR |
336 FATAL = logging.FATAL | 184 FATAL = logging.FATAL |
337 | 185 |
338 LEVELS = [DEBUG, INFO, NOTIFY, WARN, ERROR, FATAL] | 186 LEVELS = [DEBUG, INFO, NOTIFY, WARN, ERROR, FATAL] |
339 | 187 |
340 def __init__(self, consumers): | 188 def __init__(self, consumers): |
341 self.consumers = consumers | 189 self.consumers = consumers |
342 self.indent = 0 | 190 self.indent = 0 |
343 self.in_progress = None | 191 self.in_progress = None |
344 self.in_progress_hanging = False | 192 self.in_progress_hanging = False |
345 | 193 |
346 def debug(self, msg, *args, **kw): | 194 def debug(self, msg, *args, **kw): |
347 self.log(self.DEBUG, msg, *args, **kw) | 195 self.log(self.DEBUG, msg, *args, **kw) |
| 196 |
348 def info(self, msg, *args, **kw): | 197 def info(self, msg, *args, **kw): |
349 self.log(self.INFO, msg, *args, **kw) | 198 self.log(self.INFO, msg, *args, **kw) |
| 199 |
350 def notify(self, msg, *args, **kw): | 200 def notify(self, msg, *args, **kw): |
351 self.log(self.NOTIFY, msg, *args, **kw) | 201 self.log(self.NOTIFY, msg, *args, **kw) |
| 202 |
352 def warn(self, msg, *args, **kw): | 203 def warn(self, msg, *args, **kw): |
353 self.log(self.WARN, msg, *args, **kw) | 204 self.log(self.WARN, msg, *args, **kw) |
| 205 |
354 def error(self, msg, *args, **kw): | 206 def error(self, msg, *args, **kw): |
355 self.log(self.ERROR, msg, *args, **kw) | 207 self.log(self.ERROR, msg, *args, **kw) |
| 208 |
356 def fatal(self, msg, *args, **kw): | 209 def fatal(self, msg, *args, **kw): |
357 self.log(self.FATAL, msg, *args, **kw) | 210 self.log(self.FATAL, msg, *args, **kw) |
| 211 |
358 def log(self, level, msg, *args, **kw): | 212 def log(self, level, msg, *args, **kw): |
359 if args: | 213 if args: |
360 if kw: | 214 if kw: |
361 raise TypeError( | 215 raise TypeError( |
362 "You may give positional or keyword arguments, not both") | 216 "You may give positional or keyword arguments, not both") |
363 args = args or kw | 217 args = args or kw |
364 rendered = None | 218 rendered = None |
365 for consumer_level, consumer in self.consumers: | 219 for consumer_level, consumer in self.consumers: |
366 if self.level_matches(level, consumer_level): | 220 if self.level_matches(level, consumer_level): |
367 if (self.in_progress_hanging | 221 if (self.in_progress_hanging |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 if isinstance(level, slice): | 297 if isinstance(level, slice): |
444 start, stop = level.start, level.stop | 298 start, stop = level.start, level.stop |
445 if start is not None and start > consumer_level: | 299 if start is not None and start > consumer_level: |
446 return False | 300 return False |
447 if stop is not None and stop <= consumer_level: | 301 if stop is not None and stop <= consumer_level: |
448 return False | 302 return False |
449 return True | 303 return True |
450 else: | 304 else: |
451 return level >= consumer_level | 305 return level >= consumer_level |
452 | 306 |
453 #@classmethod | 307 @classmethod |
454 def level_for_integer(cls, level): | 308 def level_for_integer(cls, level): |
455 levels = cls.LEVELS | 309 levels = cls.LEVELS |
456 if level < 0: | 310 if level < 0: |
457 return levels[0] | 311 return levels[0] |
458 if level >= len(levels): | 312 if level >= len(levels): |
459 return levels[-1] | 313 return levels[-1] |
460 return levels[level] | 314 return levels[level] |
461 | 315 |
462 level_for_integer = classmethod(level_for_integer) | |
463 | |
464 # create a silent logger just to prevent this from being undefined | 316 # create a silent logger just to prevent this from being undefined |
465 # will be overridden with requested verbosity main() is called. | 317 # will be overridden with requested verbosity main() is called. |
466 logger = Logger([(Logger.LEVELS[-1], sys.stdout)]) | 318 logger = Logger([(Logger.LEVELS[-1], sys.stdout)]) |
467 | 319 |
468 def mkdir(path): | 320 def mkdir(path): |
469 if not os.path.exists(path): | 321 if not os.path.exists(path): |
470 logger.info('Creating %s', path) | 322 logger.info('Creating %s', path) |
471 os.makedirs(path) | 323 os.makedirs(path) |
472 else: | 324 else: |
473 logger.info('Directory %s already exists', path) | 325 logger.info('Directory %s already exists', path) |
(...skipping 26 matching lines...) Expand all Loading... |
500 except (OSError, NotImplementedError): | 352 except (OSError, NotImplementedError): |
501 logger.info('Symlinking failed, copying to %s', dest) | 353 logger.info('Symlinking failed, copying to %s', dest) |
502 copyfileordir(src, dest, symlink) | 354 copyfileordir(src, dest, symlink) |
503 else: | 355 else: |
504 logger.info('Copying to %s', dest) | 356 logger.info('Copying to %s', dest) |
505 copyfileordir(src, dest, symlink) | 357 copyfileordir(src, dest, symlink) |
506 | 358 |
507 def writefile(dest, content, overwrite=True): | 359 def writefile(dest, content, overwrite=True): |
508 if not os.path.exists(dest): | 360 if not os.path.exists(dest): |
509 logger.info('Writing %s', dest) | 361 logger.info('Writing %s', dest) |
510 f = open(dest, 'wb') | 362 with open(dest, 'wb') as f: |
511 f.write(content.encode('utf-8')) | 363 f.write(content.encode('utf-8')) |
512 f.close() | |
513 return | 364 return |
514 else: | 365 else: |
515 f = open(dest, 'rb') | 366 with open(dest, 'rb') as f: |
516 c = f.read() | 367 c = f.read() |
517 f.close() | |
518 if c != content.encode("utf-8"): | 368 if c != content.encode("utf-8"): |
519 if not overwrite: | 369 if not overwrite: |
520 logger.notify('File %s exists with different content; not overwr
iting', dest) | 370 logger.notify('File %s exists with different content; not overwr
iting', dest) |
521 return | 371 return |
522 logger.notify('Overwriting %s with new content', dest) | 372 logger.notify('Overwriting %s with new content', dest) |
523 f = open(dest, 'wb') | 373 with open(dest, 'wb') as f: |
524 f.write(content.encode('utf-8')) | 374 f.write(content.encode('utf-8')) |
525 f.close() | |
526 else: | 375 else: |
527 logger.info('Content %s already in place', dest) | 376 logger.info('Content %s already in place', dest) |
528 | 377 |
529 def rmtree(dir): | 378 def rmtree(dir): |
530 if os.path.exists(dir): | 379 if os.path.exists(dir): |
531 logger.notify('Deleting tree %s', dir) | 380 logger.notify('Deleting tree %s', dir) |
532 shutil.rmtree(dir) | 381 shutil.rmtree(dir) |
533 else: | 382 else: |
534 logger.info('Do not need to delete %s; already gone', dir) | 383 logger.info('Do not need to delete %s; already gone', dir) |
535 | 384 |
536 def make_exe(fn): | 385 def make_exe(fn): |
537 if hasattr(os, 'chmod'): | 386 if hasattr(os, 'chmod'): |
538 oldmode = os.stat(fn).st_mode & 0xFFF # 0o7777 | 387 oldmode = os.stat(fn).st_mode & 0xFFF # 0o7777 |
539 newmode = (oldmode | 0x16D) & 0xFFF # 0o555, 0o7777 | 388 newmode = (oldmode | 0x16D) & 0xFFF # 0o555, 0o7777 |
540 os.chmod(fn, newmode) | 389 os.chmod(fn, newmode) |
541 logger.info('Changed mode of %s to %s', fn, oct(newmode)) | 390 logger.info('Changed mode of %s to %s', fn, oct(newmode)) |
542 | 391 |
543 def _find_file(filename, dirs): | 392 def _find_file(filename, dirs): |
544 for dir in reversed(dirs): | 393 for dir in reversed(dirs): |
545 files = glob.glob(os.path.join(dir, filename)) | 394 files = glob.glob(os.path.join(dir, filename)) |
546 if files and os.path.isfile(files[0]): | 395 if files and os.path.isfile(files[0]): |
547 return True, files[0] | 396 return True, files[0] |
548 return False, filename | 397 return False, filename |
549 | 398 |
550 def file_search_dirs(): | 399 def file_search_dirs(): |
551 here = os.path.dirname(os.path.abspath(__file__)) | 400 here = os.path.dirname(os.path.abspath(__file__)) |
552 dirs = ['.', here, | 401 dirs = [here, join(here, 'virtualenv_support')] |
553 join(here, 'virtualenv_support')] | |
554 if os.path.splitext(os.path.dirname(__file__))[0] != 'virtualenv': | 402 if os.path.splitext(os.path.dirname(__file__))[0] != 'virtualenv': |
555 # Probably some boot script; just in case virtualenv is installed... | 403 # Probably some boot script; just in case virtualenv is installed... |
556 try: | 404 try: |
557 import virtualenv | 405 import virtualenv |
558 except ImportError: | 406 except ImportError: |
559 pass | 407 pass |
560 else: | 408 else: |
561 dirs.append(os.path.join(os.path.dirname(virtualenv.__file__), 'virt
ualenv_support')) | 409 dirs.append(os.path.join( |
| 410 os.path.dirname(virtualenv.__file__), 'virtualenv_support')) |
562 return [d for d in dirs if os.path.isdir(d)] | 411 return [d for d in dirs if os.path.isdir(d)] |
563 | 412 |
564 | 413 |
565 class UpdatingDefaultsHelpFormatter(optparse.IndentedHelpFormatter): | 414 class UpdatingDefaultsHelpFormatter(optparse.IndentedHelpFormatter): |
566 """ | 415 """ |
567 Custom help formatter for use in ConfigOptionParser that updates | 416 Custom help formatter for use in ConfigOptionParser that updates |
568 the defaults before expanding them, allowing them to show up correctly | 417 the defaults before expanding them, allowing them to show up correctly |
569 in the help listing | 418 in the help listing |
570 """ | 419 """ |
571 def expand_default(self, option): | 420 def expand_default(self, option): |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
730 '--relocatable', | 579 '--relocatable', |
731 dest='relocatable', | 580 dest='relocatable', |
732 action='store_true', | 581 action='store_true', |
733 help='Make an EXISTING virtualenv environment relocatable. ' | 582 help='Make an EXISTING virtualenv environment relocatable. ' |
734 'This fixes up scripts and makes all .pth files relative.') | 583 'This fixes up scripts and makes all .pth files relative.') |
735 | 584 |
736 parser.add_option( | 585 parser.add_option( |
737 '--no-setuptools', | 586 '--no-setuptools', |
738 dest='no_setuptools', | 587 dest='no_setuptools', |
739 action='store_true', | 588 action='store_true', |
740 help='Do not install setuptools (or pip) in the new virtualenv.') | 589 help='Do not install setuptools in the new virtualenv.') |
741 | 590 |
742 parser.add_option( | 591 parser.add_option( |
743 '--no-pip', | 592 '--no-pip', |
744 dest='no_pip', | 593 dest='no_pip', |
745 action='store_true', | 594 action='store_true', |
746 help='Do not install pip in the new virtualenv.') | 595 help='Do not install pip in the new virtualenv.') |
747 | 596 |
| 597 parser.add_option( |
| 598 '--no-wheel', |
| 599 dest='no_wheel', |
| 600 action='store_true', |
| 601 help='Do not install wheel in the new virtualenv.') |
| 602 |
748 default_search_dirs = file_search_dirs() | 603 default_search_dirs = file_search_dirs() |
749 parser.add_option( | 604 parser.add_option( |
750 '--extra-search-dir', | 605 '--extra-search-dir', |
751 dest="search_dirs", | 606 dest="search_dirs", |
752 action="append", | 607 action="append", |
753 metavar='DIR', | 608 metavar='DIR', |
754 default=default_search_dirs, | 609 default=default_search_dirs, |
755 help="Directory to look for setuptools/pip distributions in. " | 610 help="Directory to look for setuptools/pip distributions in. " |
756 "This option can be used multiple times.") | 611 "This option can be used multiple times.") |
757 | 612 |
758 parser.add_option( | 613 parser.add_option( |
| 614 "--download", |
| 615 dest="download", |
| 616 default=True, |
| 617 action="store_true", |
| 618 help="Download preinstalled packages from PyPI.", |
| 619 ) |
| 620 |
| 621 parser.add_option( |
| 622 "--no-download", |
759 '--never-download', | 623 '--never-download', |
760 dest="never_download", | 624 dest="download", |
761 action="store_true", | 625 action="store_false", |
762 default=True, | 626 help="Do not download preinstalled packages from PyPI.", |
763 help="DEPRECATED. Retained only for backward compatibility. This option
has no effect. " | 627 ) |
764 "Virtualenv never downloads pip or setuptools.") | |
765 | 628 |
766 parser.add_option( | 629 parser.add_option( |
767 '--prompt', | 630 '--prompt', |
768 dest='prompt', | 631 dest='prompt', |
769 help='Provides an alternative prompt prefix for this environment.') | 632 help='Provides an alternative prompt prefix for this environment.') |
770 | 633 |
771 parser.add_option( | 634 parser.add_option( |
772 '--setuptools', | 635 '--setuptools', |
773 dest='setuptools', | 636 dest='setuptools', |
774 action='store_true', | 637 action='store_true', |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
812 parser.print_help() | 675 parser.print_help() |
813 sys.exit(2) | 676 sys.exit(2) |
814 if len(args) > 1: | 677 if len(args) > 1: |
815 print('There must be only one argument: DEST_DIR (you gave %s)' % ( | 678 print('There must be only one argument: DEST_DIR (you gave %s)' % ( |
816 ' '.join(args))) | 679 ' '.join(args))) |
817 parser.print_help() | 680 parser.print_help() |
818 sys.exit(2) | 681 sys.exit(2) |
819 | 682 |
820 home_dir = args[0] | 683 home_dir = args[0] |
821 | 684 |
| 685 if os.path.exists(home_dir) and os.path.isfile(home_dir): |
| 686 logger.fatal('ERROR: File already exists and is not a directory.') |
| 687 logger.fatal('Please provide a different path or delete the file.') |
| 688 sys.exit(3) |
| 689 |
822 if os.environ.get('WORKING_ENV'): | 690 if os.environ.get('WORKING_ENV'): |
823 logger.fatal('ERROR: you cannot run virtualenv while in a workingenv') | 691 logger.fatal('ERROR: you cannot run virtualenv while in a workingenv') |
824 logger.fatal('Please deactivate your workingenv, then re-run this script
') | 692 logger.fatal('Please deactivate your workingenv, then re-run this script
') |
825 sys.exit(3) | 693 sys.exit(3) |
826 | 694 |
827 if 'PYTHONHOME' in os.environ: | 695 if 'PYTHONHOME' in os.environ: |
828 logger.warn('PYTHONHOME is set. You *must* activate the virtualenv befo
re using it') | 696 logger.warn('PYTHONHOME is set. You *must* activate the virtualenv befo
re using it') |
829 del os.environ['PYTHONHOME'] | 697 del os.environ['PYTHONHOME'] |
830 | 698 |
831 if options.relocatable: | 699 if options.relocatable: |
832 make_environment_relocatable(home_dir) | 700 make_environment_relocatable(home_dir) |
833 return | 701 return |
834 | 702 |
835 if not options.never_download: | |
836 logger.warn('The --never-download option is for backward compatibility o
nly.') | |
837 logger.warn('Setting it to false is no longer supported, and will be ign
ored.') | |
838 | |
839 create_environment(home_dir, | 703 create_environment(home_dir, |
840 site_packages=options.system_site_packages, | 704 site_packages=options.system_site_packages, |
841 clear=options.clear, | 705 clear=options.clear, |
842 unzip_setuptools=options.unzip_setuptools, | 706 unzip_setuptools=options.unzip_setuptools, |
843 prompt=options.prompt, | 707 prompt=options.prompt, |
844 search_dirs=options.search_dirs, | 708 search_dirs=options.search_dirs, |
845 never_download=True, | 709 download=options.download, |
846 no_setuptools=options.no_setuptools, | 710 no_setuptools=options.no_setuptools, |
847 no_pip=options.no_pip, | 711 no_pip=options.no_pip, |
| 712 no_wheel=options.no_wheel, |
848 symlink=options.symlink) | 713 symlink=options.symlink) |
849 if 'after_install' in globals(): | 714 if 'after_install' in globals(): |
850 after_install(options, home_dir) | 715 after_install(options, home_dir) |
851 | 716 |
852 def call_subprocess(cmd, show_stdout=True, | 717 def call_subprocess(cmd, show_stdout=True, |
853 filter_stdout=None, cwd=None, | 718 filter_stdout=None, cwd=None, |
854 raise_on_returncode=True, extra_env=None, | 719 raise_on_returncode=True, extra_env=None, |
855 remove_from_env=None): | 720 remove_from_env=None, stdin=None): |
856 cmd_parts = [] | 721 cmd_parts = [] |
857 for part in cmd: | 722 for part in cmd: |
858 if len(part) > 45: | 723 if len(part) > 45: |
859 part = part[:20]+"..."+part[-20:] | 724 part = part[:20]+"..."+part[-20:] |
860 if ' ' in part or '\n' in part or '"' in part or "'" in part: | 725 if ' ' in part or '\n' in part or '"' in part or "'" in part: |
861 part = '"%s"' % part.replace('"', '\\"') | 726 part = '"%s"' % part.replace('"', '\\"') |
862 if hasattr(part, 'decode'): | 727 if hasattr(part, 'decode'): |
863 try: | 728 try: |
864 part = part.decode(sys.getdefaultencoding()) | 729 part = part.decode(sys.getdefaultencoding()) |
865 except UnicodeDecodeError: | 730 except UnicodeDecodeError: |
866 part = part.decode(sys.getfilesystemencoding()) | 731 part = part.decode(sys.getfilesystemencoding()) |
867 cmd_parts.append(part) | 732 cmd_parts.append(part) |
868 cmd_desc = ' '.join(cmd_parts) | 733 cmd_desc = ' '.join(cmd_parts) |
869 if show_stdout: | 734 if show_stdout: |
870 stdout = None | 735 stdout = None |
871 else: | 736 else: |
872 stdout = subprocess.PIPE | 737 stdout = subprocess.PIPE |
873 logger.debug("Running command %s" % cmd_desc) | 738 logger.debug("Running command %s" % cmd_desc) |
874 if extra_env or remove_from_env: | 739 if extra_env or remove_from_env: |
875 env = os.environ.copy() | 740 env = os.environ.copy() |
876 if extra_env: | 741 if extra_env: |
877 env.update(extra_env) | 742 env.update(extra_env) |
878 if remove_from_env: | 743 if remove_from_env: |
879 for varname in remove_from_env: | 744 for varname in remove_from_env: |
880 env.pop(varname, None) | 745 env.pop(varname, None) |
881 else: | 746 else: |
882 env = None | 747 env = None |
883 try: | 748 try: |
884 proc = subprocess.Popen( | 749 proc = subprocess.Popen( |
885 cmd, stderr=subprocess.STDOUT, stdin=None, stdout=stdout, | 750 cmd, stderr=subprocess.STDOUT, |
| 751 stdin=None if stdin is None else subprocess.PIPE, |
| 752 stdout=stdout, |
886 cwd=cwd, env=env) | 753 cwd=cwd, env=env) |
887 except Exception: | 754 except Exception: |
888 e = sys.exc_info()[1] | 755 e = sys.exc_info()[1] |
889 logger.fatal( | 756 logger.fatal( |
890 "Error %s while executing command %s" % (e, cmd_desc)) | 757 "Error %s while executing command %s" % (e, cmd_desc)) |
891 raise | 758 raise |
892 all_output = [] | 759 all_output = [] |
893 if stdout is not None: | 760 if stdout is not None: |
| 761 if stdin is not None: |
| 762 proc.stdin.write(stdin) |
| 763 proc.stdin.close() |
| 764 |
894 stdout = proc.stdout | 765 stdout = proc.stdout |
895 encoding = sys.getdefaultencoding() | 766 encoding = sys.getdefaultencoding() |
896 fs_encoding = sys.getfilesystemencoding() | 767 fs_encoding = sys.getfilesystemencoding() |
897 while 1: | 768 while 1: |
898 line = stdout.readline() | 769 line = stdout.readline() |
899 try: | 770 try: |
900 line = line.decode(encoding) | 771 line = line.decode(encoding) |
901 except UnicodeDecodeError: | 772 except UnicodeDecodeError: |
902 line = line.decode(fs_encoding) | 773 line = line.decode(fs_encoding) |
903 if not line: | 774 if not line: |
904 break | 775 break |
905 line = line.rstrip() | 776 line = line.rstrip() |
906 all_output.append(line) | 777 all_output.append(line) |
907 if filter_stdout: | 778 if filter_stdout: |
908 level = filter_stdout(line) | 779 level = filter_stdout(line) |
909 if isinstance(level, tuple): | 780 if isinstance(level, tuple): |
910 level, line = level | 781 level, line = level |
911 logger.log(level, line) | 782 logger.log(level, line) |
912 if not logger.stdout_level_matches(level): | 783 if not logger.stdout_level_matches(level): |
913 logger.show_progress() | 784 logger.show_progress() |
914 else: | 785 else: |
915 logger.info(line) | 786 logger.info(line) |
916 else: | 787 else: |
917 proc.communicate() | 788 proc.communicate(stdin) |
918 proc.wait() | 789 proc.wait() |
919 if proc.returncode: | 790 if proc.returncode: |
920 if raise_on_returncode: | 791 if raise_on_returncode: |
921 if all_output: | 792 if all_output: |
922 logger.notify('Complete output from command %s:' % cmd_desc) | 793 logger.notify('Complete output from command %s:' % cmd_desc) |
923 logger.notify('\n'.join(all_output) + '\n-----------------------
-----------------') | 794 logger.notify('\n'.join(all_output) + '\n-----------------------
-----------------') |
924 raise OSError( | 795 raise OSError( |
925 "Command %s failed with error code %s" | 796 "Command %s failed with error code %s" |
926 % (cmd_desc, proc.returncode)) | 797 % (cmd_desc, proc.returncode)) |
927 else: | 798 else: |
(...skipping 25 matching lines...) Expand all Loading... |
953 files = glob.glob(os.path.join(dirname, project + '-*.whl')) | 824 files = glob.glob(os.path.join(dirname, project + '-*.whl')) |
954 if files: | 825 if files: |
955 wheels.append(os.path.abspath(files[0])) | 826 wheels.append(os.path.abspath(files[0])) |
956 break | 827 break |
957 else: | 828 else: |
958 # We're out of luck, so quit with a suitable error | 829 # We're out of luck, so quit with a suitable error |
959 logger.fatal('Cannot find a wheel for %s' % (project,)) | 830 logger.fatal('Cannot find a wheel for %s' % (project,)) |
960 | 831 |
961 return wheels | 832 return wheels |
962 | 833 |
963 def install_wheel(project_names, py_executable, search_dirs=None): | 834 def install_wheel(project_names, py_executable, search_dirs=None, |
| 835 download=False): |
964 if search_dirs is None: | 836 if search_dirs is None: |
965 search_dirs = file_search_dirs() | 837 search_dirs = file_search_dirs() |
966 | 838 |
967 wheels = find_wheels(['setuptools', 'pip'], search_dirs) | 839 wheels = find_wheels(['setuptools', 'pip'], search_dirs) |
968 pythonpath = os.pathsep.join(wheels) | 840 pythonpath = os.pathsep.join(wheels) |
969 findlinks = ' '.join(search_dirs) | |
970 | 841 |
971 cmd = [ | 842 # PIP_FIND_LINKS uses space as the path separator and thus cannot have paths |
972 py_executable, '-c', | 843 # with spaces in them. Convert any of those to local file:// URL form. |
973 'import sys, pip; sys.exit(pip.main(["install", "--ignore-installed"] +
sys.argv[1:]))', | 844 try: |
974 ] + project_names | 845 from urlparse import urljoin |
| 846 from urllib import pathname2url |
| 847 except ImportError: |
| 848 from urllib.parse import urljoin |
| 849 from urllib.request import pathname2url |
| 850 def space_path2url(p): |
| 851 if ' ' not in p: |
| 852 return p |
| 853 return urljoin('file:', pathname2url(os.path.abspath(p))) |
| 854 findlinks = ' '.join(space_path2url(d) for d in search_dirs) |
| 855 |
| 856 SCRIPT = textwrap.dedent(""" |
| 857 import sys |
| 858 import pkgutil |
| 859 import tempfile |
| 860 import os |
| 861 |
| 862 import pip |
| 863 |
| 864 cert_data = pkgutil.get_data("pip._vendor.requests", "cacert.pem") |
| 865 if cert_data is not None: |
| 866 cert_file = tempfile.NamedTemporaryFile(delete=False) |
| 867 cert_file.write(cert_data) |
| 868 cert_file.close() |
| 869 else: |
| 870 cert_file = None |
| 871 |
| 872 try: |
| 873 args = ["install", "--ignore-installed"] |
| 874 if cert_file is not None: |
| 875 args += ["--cert", cert_file.name] |
| 876 args += sys.argv[1:] |
| 877 |
| 878 sys.exit(pip.main(args)) |
| 879 finally: |
| 880 if cert_file is not None: |
| 881 os.remove(cert_file.name) |
| 882 """).encode("utf8") |
| 883 |
| 884 cmd = [py_executable, '-'] + project_names |
975 logger.start_progress('Installing %s...' % (', '.join(project_names))) | 885 logger.start_progress('Installing %s...' % (', '.join(project_names))) |
976 logger.indent += 2 | 886 logger.indent += 2 |
| 887 |
| 888 env = { |
| 889 "PYTHONPATH": pythonpath, |
| 890 "JYTHONPATH": pythonpath, # for Jython < 3.x |
| 891 "PIP_FIND_LINKS": findlinks, |
| 892 "PIP_USE_WHEEL": "1", |
| 893 "PIP_ONLY_BINARY": ":all:", |
| 894 "PIP_USER": "0", |
| 895 } |
| 896 |
| 897 if not download: |
| 898 env["PIP_NO_INDEX"] = "1" |
| 899 |
977 try: | 900 try: |
978 call_subprocess(cmd, show_stdout=False, | 901 call_subprocess(cmd, show_stdout=False, extra_env=env, stdin=SCRIPT) |
979 extra_env = { | |
980 'PYTHONPATH': pythonpath, | |
981 'PIP_FIND_LINKS': findlinks, | |
982 'PIP_USE_WHEEL': '1', | |
983 'PIP_PRE': '1', | |
984 'PIP_NO_INDEX': '1' | |
985 } | |
986 ) | |
987 finally: | 902 finally: |
988 logger.indent -= 2 | 903 logger.indent -= 2 |
989 logger.end_progress() | 904 logger.end_progress() |
990 | 905 |
| 906 |
991 def create_environment(home_dir, site_packages=False, clear=False, | 907 def create_environment(home_dir, site_packages=False, clear=False, |
992 unzip_setuptools=False, | 908 unzip_setuptools=False, |
993 prompt=None, search_dirs=None, never_download=False, | 909 prompt=None, search_dirs=None, download=False, |
994 no_setuptools=False, no_pip=False, symlink=True): | 910 no_setuptools=False, no_pip=False, no_wheel=False, |
| 911 symlink=True): |
995 """ | 912 """ |
996 Creates a new environment in ``home_dir``. | 913 Creates a new environment in ``home_dir``. |
997 | 914 |
998 If ``site_packages`` is true, then the global ``site-packages/`` | 915 If ``site_packages`` is true, then the global ``site-packages/`` |
999 directory will be on the path. | 916 directory will be on the path. |
1000 | 917 |
1001 If ``clear`` is true (default False) then the environment will | 918 If ``clear`` is true (default False) then the environment will |
1002 first be cleared. | 919 first be cleared. |
1003 """ | 920 """ |
1004 home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir) | 921 home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir) |
1005 | 922 |
1006 py_executable = os.path.abspath(install_python( | 923 py_executable = os.path.abspath(install_python( |
1007 home_dir, lib_dir, inc_dir, bin_dir, | 924 home_dir, lib_dir, inc_dir, bin_dir, |
1008 site_packages=site_packages, clear=clear, symlink=symlink)) | 925 site_packages=site_packages, clear=clear, symlink=symlink)) |
1009 | 926 |
1010 install_distutils(home_dir) | 927 install_distutils(home_dir) |
1011 | 928 |
| 929 to_install = [] |
| 930 |
1012 if not no_setuptools: | 931 if not no_setuptools: |
1013 to_install = ['setuptools'] | 932 to_install.append('setuptools') |
1014 if not no_pip: | 933 |
1015 to_install.append('pip') | 934 if not no_pip: |
1016 install_wheel(to_install, py_executable, search_dirs) | 935 to_install.append('pip') |
| 936 |
| 937 if not no_wheel: |
| 938 to_install.append('wheel') |
| 939 |
| 940 if to_install: |
| 941 install_wheel( |
| 942 to_install, |
| 943 py_executable, |
| 944 search_dirs, |
| 945 download=download, |
| 946 ) |
1017 | 947 |
1018 install_activate(home_dir, bin_dir, prompt) | 948 install_activate(home_dir, bin_dir, prompt) |
1019 | 949 |
| 950 install_python_config(home_dir, bin_dir, prompt) |
| 951 |
1020 def is_executable_file(fpath): | 952 def is_executable_file(fpath): |
1021 return os.path.isfile(fpath) and os.access(fpath, os.X_OK) | 953 return os.path.isfile(fpath) and os.access(fpath, os.X_OK) |
1022 | 954 |
1023 def path_locations(home_dir): | 955 def path_locations(home_dir): |
1024 """Return the path locations for the environment (where libraries are, | 956 """Return the path locations for the environment (where libraries are, |
1025 where scripts go, etc)""" | 957 where scripts go, etc)""" |
| 958 home_dir = os.path.abspath(home_dir) |
1026 # XXX: We'd use distutils.sysconfig.get_python_inc/lib but its | 959 # XXX: We'd use distutils.sysconfig.get_python_inc/lib but its |
1027 # prefix arg is broken: http://bugs.python.org/issue3386 | 960 # prefix arg is broken: http://bugs.python.org/issue3386 |
1028 if is_win: | 961 if is_win: |
1029 # Windows has lots of problems with executables with spaces in | 962 # Windows has lots of problems with executables with spaces in |
1030 # the name; this function will remove them (using the ~1 | 963 # the name; this function will remove them (using the ~1 |
1031 # format): | 964 # format): |
1032 mkdir(home_dir) | 965 mkdir(home_dir) |
1033 if ' ' in home_dir: | 966 if ' ' in home_dir: |
1034 import ctypes | 967 import ctypes |
1035 GetShortPathName = ctypes.windll.kernel32.GetShortPathNameW | 968 GetShortPathName = ctypes.windll.kernel32.GetShortPathNameW |
(...skipping 16 matching lines...) Expand all Loading... |
1052 if is_jython: | 985 if is_jython: |
1053 lib_dir = join(home_dir, 'Lib') | 986 lib_dir = join(home_dir, 'Lib') |
1054 inc_dir = join(home_dir, 'Include') | 987 inc_dir = join(home_dir, 'Include') |
1055 bin_dir = join(home_dir, 'bin') | 988 bin_dir = join(home_dir, 'bin') |
1056 elif is_pypy: | 989 elif is_pypy: |
1057 lib_dir = home_dir | 990 lib_dir = home_dir |
1058 inc_dir = join(home_dir, 'include') | 991 inc_dir = join(home_dir, 'include') |
1059 bin_dir = join(home_dir, 'bin') | 992 bin_dir = join(home_dir, 'bin') |
1060 elif not is_win: | 993 elif not is_win: |
1061 lib_dir = join(home_dir, 'lib', py_version) | 994 lib_dir = join(home_dir, 'lib', py_version) |
1062 multiarch_exec = '/usr/bin/multiarch-platform' | 995 inc_dir = join(home_dir, 'include', py_version + abiflags) |
1063 if is_executable_file(multiarch_exec): | |
1064 # In Mageia (2) and Mandriva distros the include dir must be like: | |
1065 # virtualenv/include/multiarch-x86_64-linux/python2.7 | |
1066 # instead of being virtualenv/include/python2.7 | |
1067 p = subprocess.Popen(multiarch_exec, stdout=subprocess.PIPE, stderr=
subprocess.PIPE) | |
1068 stdout, stderr = p.communicate() | |
1069 # stdout.strip is needed to remove newline character | |
1070 inc_dir = join(home_dir, 'include', stdout.strip(), py_version + abi
flags) | |
1071 else: | |
1072 inc_dir = join(home_dir, 'include', py_version + abiflags) | |
1073 bin_dir = join(home_dir, 'bin') | 996 bin_dir = join(home_dir, 'bin') |
1074 return home_dir, lib_dir, inc_dir, bin_dir | 997 return home_dir, lib_dir, inc_dir, bin_dir |
1075 | 998 |
1076 | 999 |
1077 def change_prefix(filename, dst_prefix): | 1000 def change_prefix(filename, dst_prefix): |
1078 prefixes = [sys.prefix] | 1001 prefixes = [sys.prefix] |
1079 | 1002 |
1080 if is_darwin: | 1003 if is_darwin: |
1081 prefixes.extend(( | 1004 prefixes.extend(( |
1082 os.path.join("/Library/Python", sys.version[:3], "site-packages"), | 1005 os.path.join("/Library/Python", sys.version[:3], "site-packages"), |
1083 os.path.join(sys.prefix, "Extras", "lib", "python"), | 1006 os.path.join(sys.prefix, "Extras", "lib", "python"), |
1084 os.path.join("~", "Library", "Python", sys.version[:3], "site-packag
es"), | 1007 os.path.join("~", "Library", "Python", sys.version[:3], "site-packag
es"), |
1085 # Python 2.6 no-frameworks | 1008 # Python 2.6 no-frameworks |
1086 os.path.join("~", ".local", "lib","python", sys.version[:3], "site-p
ackages"), | 1009 os.path.join("~", ".local", "lib","python", sys.version[:3], "site-p
ackages"), |
1087 # System Python 2.7 on OSX Mountain Lion | 1010 # System Python 2.7 on OSX Mountain Lion |
1088 os.path.join("~", "Library", "Python", sys.version[:3], "lib", "pyth
on", "site-packages"))) | 1011 os.path.join("~", "Library", "Python", sys.version[:3], "lib", "pyth
on", "site-packages"))) |
1089 | 1012 |
1090 if hasattr(sys, 'real_prefix'): | 1013 if hasattr(sys, 'real_prefix'): |
1091 prefixes.append(sys.real_prefix) | 1014 prefixes.append(sys.real_prefix) |
1092 if hasattr(sys, 'base_prefix'): | 1015 if hasattr(sys, 'base_prefix'): |
1093 prefixes.append(sys.base_prefix) | 1016 prefixes.append(sys.base_prefix) |
1094 prefixes = list(map(os.path.expanduser, prefixes)) | 1017 prefixes = list(map(os.path.expanduser, prefixes)) |
1095 prefixes = list(map(os.path.abspath, prefixes)) | 1018 prefixes = list(map(os.path.abspath, prefixes)) |
1096 # Check longer prefixes first so we don't split in the middle of a filename | 1019 # Check longer prefixes first so we don't split in the middle of a filename |
1097 prefixes = sorted(prefixes, key=len, reverse=True) | 1020 prefixes = sorted(prefixes, key=len, reverse=True) |
1098 filename = os.path.abspath(filename) | 1021 filename = os.path.abspath(filename) |
| 1022 # On Windows, make sure drive letter is uppercase |
| 1023 if is_win and filename[0] in 'abcdefghijklmnopqrstuvwxyz': |
| 1024 filename = filename[0].upper() + filename[1:] |
| 1025 for i, prefix in enumerate(prefixes): |
| 1026 if is_win and prefix[0] in 'abcdefghijklmnopqrstuvwxyz': |
| 1027 prefixes[i] = prefix[0].upper() + prefix[1:] |
1099 for src_prefix in prefixes: | 1028 for src_prefix in prefixes: |
1100 if filename.startswith(src_prefix): | 1029 if filename.startswith(src_prefix): |
1101 _, relpath = filename.split(src_prefix, 1) | 1030 _, relpath = filename.split(src_prefix, 1) |
1102 if src_prefix != os.sep: # sys.prefix == "/" | 1031 if src_prefix != os.sep: # sys.prefix == "/" |
1103 assert relpath[0] == os.sep | 1032 assert relpath[0] == os.sep |
1104 relpath = relpath[1:] | 1033 relpath = relpath[1:] |
1105 return join(dst_prefix, relpath) | 1034 return join(dst_prefix, relpath) |
1106 assert False, "Filename %s does not start with any of these prefixes: %s" %
\ | 1035 assert False, "Filename %s does not start with any of these prefixes: %s" %
\ |
1107 (filename, prefixes) | 1036 (filename, prefixes) |
1108 | 1037 |
1109 def copy_required_modules(dst_prefix, symlink): | 1038 def copy_required_modules(dst_prefix, symlink): |
1110 import imp | 1039 import imp |
| 1040 |
1111 for modname in REQUIRED_MODULES: | 1041 for modname in REQUIRED_MODULES: |
1112 if modname in sys.builtin_module_names: | 1042 if modname in sys.builtin_module_names: |
1113 logger.info("Ignoring built-in bootstrap module: %s" % modname) | 1043 logger.info("Ignoring built-in bootstrap module: %s" % modname) |
1114 continue | 1044 continue |
1115 try: | 1045 try: |
1116 f, filename, _ = imp.find_module(modname) | 1046 f, filename, _ = imp.find_module(modname) |
1117 except ImportError: | 1047 except ImportError: |
1118 logger.info("Cannot import bootstrap module: %s" % modname) | 1048 logger.info("Cannot import bootstrap module: %s" % modname) |
1119 else: | 1049 else: |
1120 if f is not None: | 1050 if f is not None: |
1121 f.close() | 1051 f.close() |
1122 # special-case custom readline.so on OS X, but not for pypy: | 1052 # special-case custom readline.so on OS X, but not for pypy: |
1123 if modname == 'readline' and sys.platform == 'darwin' and not ( | 1053 if modname == 'readline' and sys.platform == 'darwin' and not ( |
1124 is_pypy or filename.endswith(join('lib-dynload', 'readline.s
o'))): | 1054 is_pypy or filename.endswith(join('lib-dynload', 'readline.s
o'))): |
1125 dst_filename = join(dst_prefix, 'lib', 'python%s' % sys.version[
:3], 'readline.so') | 1055 dst_filename = join(dst_prefix, 'lib', 'python%s' % sys.version[
:3], 'readline.so') |
1126 elif modname == 'readline' and sys.platform == 'win32': | 1056 elif modname == 'readline' and sys.platform == 'win32': |
1127 # special-case for Windows, where readline is not a | 1057 # special-case for Windows, where readline is not a |
1128 # standard module, though it may have been installed in | 1058 # standard module, though it may have been installed in |
1129 # site-packages by a third-party package | 1059 # site-packages by a third-party package |
1130 pass | 1060 pass |
1131 else: | 1061 else: |
1132 dst_filename = change_prefix(filename, dst_prefix) | 1062 dst_filename = change_prefix(filename, dst_prefix) |
1133 copyfile(filename, dst_filename, symlink) | 1063 copyfile(filename, dst_filename, symlink) |
1134 if filename.endswith('.pyc'): | 1064 if filename.endswith('.pyc'): |
1135 pyfile = filename[:-1] | 1065 pyfile = filename[:-1] |
1136 if os.path.exists(pyfile): | 1066 if os.path.exists(pyfile): |
1137 copyfile(pyfile, dst_filename[:-1], symlink) | 1067 copyfile(pyfile, dst_filename[:-1], symlink) |
1138 | 1068 |
| 1069 def copy_tcltk(src, dest, symlink): |
| 1070 """ copy tcl/tk libraries on Windows (issue #93) """ |
| 1071 for libversion in '8.5', '8.6': |
| 1072 for libname in 'tcl', 'tk': |
| 1073 srcdir = join(src, 'tcl', libname + libversion) |
| 1074 destdir = join(dest, 'tcl', libname + libversion) |
| 1075 # Only copy the dirs from the above combinations that exist |
| 1076 if os.path.exists(srcdir) and not os.path.exists(destdir): |
| 1077 copyfileordir(srcdir, destdir, symlink) |
| 1078 |
1139 | 1079 |
1140 def subst_path(prefix_path, prefix, home_dir): | 1080 def subst_path(prefix_path, prefix, home_dir): |
1141 prefix_path = os.path.normpath(prefix_path) | 1081 prefix_path = os.path.normpath(prefix_path) |
1142 prefix = os.path.normpath(prefix) | 1082 prefix = os.path.normpath(prefix) |
1143 home_dir = os.path.normpath(home_dir) | 1083 home_dir = os.path.normpath(home_dir) |
1144 if not prefix_path.startswith(prefix): | 1084 if not prefix_path.startswith(prefix): |
1145 logger.warn('Path not in prefix %r %r', prefix_path, prefix) | 1085 logger.warn('Path not in prefix %r %r', prefix_path, prefix) |
1146 return | 1086 return |
1147 return prefix_path.replace(prefix, home_dir, 1) | 1087 return prefix_path.replace(prefix, home_dir, 1) |
1148 | 1088 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1185 if not os.path.isdir(stdlib_dir): | 1125 if not os.path.isdir(stdlib_dir): |
1186 continue | 1126 continue |
1187 for fn in os.listdir(stdlib_dir): | 1127 for fn in os.listdir(stdlib_dir): |
1188 bn = os.path.splitext(fn)[0] | 1128 bn = os.path.splitext(fn)[0] |
1189 if fn != 'site-packages' and bn in REQUIRED_FILES: | 1129 if fn != 'site-packages' and bn in REQUIRED_FILES: |
1190 copyfile(join(stdlib_dir, fn), join(lib_dir, fn), symlink) | 1130 copyfile(join(stdlib_dir, fn), join(lib_dir, fn), symlink) |
1191 # ...and modules | 1131 # ...and modules |
1192 copy_required_modules(home_dir, symlink) | 1132 copy_required_modules(home_dir, symlink) |
1193 finally: | 1133 finally: |
1194 logger.indent -= 2 | 1134 logger.indent -= 2 |
| 1135 # ...copy tcl/tk |
| 1136 if is_win: |
| 1137 copy_tcltk(prefix, home_dir, symlink) |
1195 mkdir(join(lib_dir, 'site-packages')) | 1138 mkdir(join(lib_dir, 'site-packages')) |
1196 import site | 1139 import site |
1197 site_filename = site.__file__ | 1140 site_filename = site.__file__ |
1198 if site_filename.endswith('.pyc'): | 1141 if site_filename.endswith('.pyc') or site_filename.endswith('.pyo'): |
1199 site_filename = site_filename[:-1] | 1142 site_filename = site_filename[:-1] |
1200 elif site_filename.endswith('$py.class'): | 1143 elif site_filename.endswith('$py.class'): |
1201 site_filename = site_filename.replace('$py.class', '.py') | 1144 site_filename = site_filename.replace('$py.class', '.py') |
1202 site_filename_dst = change_prefix(site_filename, home_dir) | 1145 site_filename_dst = change_prefix(site_filename, home_dir) |
1203 site_dir = os.path.dirname(site_filename_dst) | 1146 site_dir = os.path.dirname(site_filename_dst) |
1204 writefile(site_filename_dst, SITE_PY) | 1147 writefile(site_filename_dst, SITE_PY) |
1205 writefile(join(site_dir, 'orig-prefix.txt'), prefix) | 1148 writefile(join(site_dir, 'orig-prefix.txt'), prefix) |
1206 site_packages_filename = join(site_dir, 'no-global-site-packages.txt') | 1149 site_packages_filename = join(site_dir, 'no-global-site-packages.txt') |
1207 if not site_packages: | 1150 if not site_packages: |
1208 writefile(site_packages_filename, '') | 1151 writefile(site_packages_filename, '') |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1421 | 1364 |
1422 for pth in required_symlinks: | 1365 for pth in required_symlinks: |
1423 full_pth = join(bin_dir, pth) | 1366 full_pth = join(bin_dir, pth) |
1424 if os.path.exists(full_pth): | 1367 if os.path.exists(full_pth): |
1425 os.unlink(full_pth) | 1368 os.unlink(full_pth) |
1426 if symlink: | 1369 if symlink: |
1427 os.symlink(py_executable_base, full_pth) | 1370 os.symlink(py_executable_base, full_pth) |
1428 else: | 1371 else: |
1429 copyfile(py_executable, full_pth, symlink) | 1372 copyfile(py_executable, full_pth, symlink) |
1430 | 1373 |
1431 if is_win and ' ' in py_executable: | |
1432 # There's a bug with subprocess on Windows when using a first | |
1433 # argument that has a space in it. Instead we have to quote | |
1434 # the value: | |
1435 py_executable = '"%s"' % py_executable | |
1436 # NOTE: keep this check as one line, cmd.exe doesn't cope with line breaks | |
1437 cmd = [py_executable, '-c', 'import sys;out=sys.stdout;' | 1374 cmd = [py_executable, '-c', 'import sys;out=sys.stdout;' |
1438 'getattr(out, "buffer", out).write(sys.prefix.encode("utf-8"))'] | 1375 'getattr(out, "buffer", out).write(sys.prefix.encode("utf-8"))'] |
1439 logger.info('Testing executable with %s %s "%s"' % tuple(cmd)) | 1376 logger.info('Testing executable with %s %s "%s"' % tuple(cmd)) |
1440 try: | 1377 try: |
1441 proc = subprocess.Popen(cmd, | 1378 proc = subprocess.Popen(cmd, |
1442 stdout=subprocess.PIPE) | 1379 stdout=subprocess.PIPE) |
1443 proc_stdout, proc_stderr = proc.communicate() | 1380 proc_stdout, proc_stderr = proc.communicate() |
1444 except OSError: | 1381 except OSError: |
1445 e = sys.exc_info()[1] | 1382 e = sys.exc_info()[1] |
1446 if e.errno == errno.EACCES: | 1383 if e.errno == errno.EACCES: |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1483 | 1420 |
1484 if site_packages: | 1421 if site_packages: |
1485 if os.path.exists(site_packages_filename): | 1422 if os.path.exists(site_packages_filename): |
1486 logger.info('Deleting %s' % site_packages_filename) | 1423 logger.info('Deleting %s' % site_packages_filename) |
1487 os.unlink(site_packages_filename) | 1424 os.unlink(site_packages_filename) |
1488 | 1425 |
1489 return py_executable | 1426 return py_executable |
1490 | 1427 |
1491 | 1428 |
1492 def install_activate(home_dir, bin_dir, prompt=None): | 1429 def install_activate(home_dir, bin_dir, prompt=None): |
1493 home_dir = os.path.abspath(home_dir) | |
1494 if is_win or is_jython and os._name == 'nt': | 1430 if is_win or is_jython and os._name == 'nt': |
1495 files = { | 1431 files = { |
1496 'activate.bat': ACTIVATE_BAT, | 1432 'activate.bat': ACTIVATE_BAT, |
1497 'deactivate.bat': DEACTIVATE_BAT, | 1433 'deactivate.bat': DEACTIVATE_BAT, |
1498 'activate.ps1': ACTIVATE_PS, | 1434 'activate.ps1': ACTIVATE_PS, |
1499 } | 1435 } |
1500 | 1436 |
1501 # MSYS needs paths of the form /c/path/to/file | 1437 # MSYS needs paths of the form /c/path/to/file |
1502 drive, tail = os.path.splitdrive(home_dir.replace(os.sep, '/')) | 1438 drive, tail = os.path.splitdrive(home_dir.replace(os.sep, '/')) |
1503 home_dir_msys = (drive and "/%s%s" or "%s%s") % (drive[:1], tail) | 1439 home_dir_msys = (drive and "/%s%s" or "%s%s") % (drive[:1], tail) |
1504 | 1440 |
1505 # Run-time conditional enables (basic) Cygwin compatibility | 1441 # Run-time conditional enables (basic) Cygwin compatibility |
1506 home_dir_sh = ("""$(if [ "$OSTYPE" "==" "cygwin" ]; then cygpath -u '%s'
; else echo '%s'; fi;)""" % | 1442 home_dir_sh = ("""$(if [ "$OSTYPE" "==" "cygwin" ]; then cygpath -u '%s'
; else echo '%s'; fi;)""" % |
1507 (home_dir, home_dir_msys)) | 1443 (home_dir, home_dir_msys)) |
1508 files['activate'] = ACTIVATE_SH.replace('__VIRTUAL_ENV__', home_dir_sh) | 1444 files['activate'] = ACTIVATE_SH.replace('__VIRTUAL_ENV__', home_dir_sh) |
1509 | 1445 |
1510 else: | 1446 else: |
1511 files = {'activate': ACTIVATE_SH} | 1447 files = {'activate': ACTIVATE_SH} |
1512 | 1448 |
1513 # suppling activate.fish in addition to, not instead of, the | 1449 # suppling activate.fish in addition to, not instead of, the |
1514 # bash script support. | 1450 # bash script support. |
1515 files['activate.fish'] = ACTIVATE_FISH | 1451 files['activate.fish'] = ACTIVATE_FISH |
1516 | 1452 |
1517 # same for csh/tcsh support... | 1453 # same for csh/tcsh support... |
1518 files['activate.csh'] = ACTIVATE_CSH | 1454 files['activate.csh'] = ACTIVATE_CSH |
1519 | 1455 |
1520 files['activate_this.py'] = ACTIVATE_THIS | 1456 files['activate_this.py'] = ACTIVATE_THIS |
| 1457 |
| 1458 install_files(home_dir, bin_dir, prompt, files) |
| 1459 |
| 1460 def install_files(home_dir, bin_dir, prompt, files): |
1521 if hasattr(home_dir, 'decode'): | 1461 if hasattr(home_dir, 'decode'): |
1522 home_dir = home_dir.decode(sys.getfilesystemencoding()) | 1462 home_dir = home_dir.decode(sys.getfilesystemencoding()) |
1523 vname = os.path.basename(home_dir) | 1463 vname = os.path.basename(home_dir) |
1524 for name, content in files.items(): | 1464 for name, content in files.items(): |
1525 content = content.replace('__VIRTUAL_PROMPT__', prompt or '') | 1465 content = content.replace('__VIRTUAL_PROMPT__', prompt or '') |
1526 content = content.replace('__VIRTUAL_WINPROMPT__', prompt or '(%s)' % vn
ame) | 1466 content = content.replace('__VIRTUAL_WINPROMPT__', prompt or '(%s)' % vn
ame) |
1527 content = content.replace('__VIRTUAL_ENV__', home_dir) | 1467 content = content.replace('__VIRTUAL_ENV__', home_dir) |
1528 content = content.replace('__VIRTUAL_NAME__', vname) | 1468 content = content.replace('__VIRTUAL_NAME__', vname) |
1529 content = content.replace('__BIN_NAME__', os.path.basename(bin_dir)) | 1469 content = content.replace('__BIN_NAME__', os.path.basename(bin_dir)) |
1530 writefile(os.path.join(bin_dir, name), content) | 1470 writefile(os.path.join(bin_dir, name), content) |
1531 | 1471 |
| 1472 def install_python_config(home_dir, bin_dir, prompt=None): |
| 1473 if sys.platform == 'win32' or is_jython and os._name == 'nt': |
| 1474 files = {} |
| 1475 else: |
| 1476 files = {'python-config': PYTHON_CONFIG} |
| 1477 install_files(home_dir, bin_dir, prompt, files) |
| 1478 for name, content in files.items(): |
| 1479 make_exe(os.path.join(bin_dir, name)) |
| 1480 |
1532 def install_distutils(home_dir): | 1481 def install_distutils(home_dir): |
1533 distutils_path = change_prefix(distutils.__path__[0], home_dir) | 1482 distutils_path = change_prefix(distutils.__path__[0], home_dir) |
1534 mkdir(distutils_path) | 1483 mkdir(distutils_path) |
1535 ## FIXME: maybe this prefix setting should only be put in place if | 1484 ## FIXME: maybe this prefix setting should only be put in place if |
1536 ## there's a local distutils.cfg with a prefix setting? | 1485 ## there's a local distutils.cfg with a prefix setting? |
1537 home_dir = os.path.abspath(home_dir) | 1486 home_dir = os.path.abspath(home_dir) |
1538 ## FIXME: this is breaking things, removing for now: | 1487 ## FIXME: this is breaking things, removing for now: |
1539 #distutils_cfg = DISTUTILS_CFG + "\n[install]\nprefix=%s\n" % home_dir | 1488 #distutils_cfg = DISTUTILS_CFG + "\n[install]\nprefix=%s\n" % home_dir |
1540 writefile(os.path.join(distutils_path, '__init__.py'), DISTUTILS_INIT) | 1489 writefile(os.path.join(distutils_path, '__init__.py'), DISTUTILS_INIT) |
1541 writefile(os.path.join(distutils_path, 'distutils.cfg'), DISTUTILS_CFG, over
write=False) | 1490 writefile(os.path.join(distutils_path, 'distutils.cfg'), DISTUTILS_CFG, over
write=False) |
(...skipping 17 matching lines...) Expand all Loading... |
1559 continue | 1508 continue |
1560 copyfile(os.path.abspath(os.path.join(home_dir, subdir_name)
), \ | 1509 copyfile(os.path.abspath(os.path.join(home_dir, subdir_name)
), \ |
1561 os.path.join(local_p
ath, subdir_name), symlink) | 1510 os.path.join(local_p
ath, subdir_name), symlink) |
1562 | 1511 |
1563 def fix_lib64(lib_dir, symlink=True): | 1512 def fix_lib64(lib_dir, symlink=True): |
1564 """ | 1513 """ |
1565 Some platforms (particularly Gentoo on x64) put things in lib64/pythonX.Y | 1514 Some platforms (particularly Gentoo on x64) put things in lib64/pythonX.Y |
1566 instead of lib/pythonX.Y. If this is such a platform we'll just create a | 1515 instead of lib/pythonX.Y. If this is such a platform we'll just create a |
1567 symlink so lib64 points to lib | 1516 symlink so lib64 points to lib |
1568 """ | 1517 """ |
1569 if [p for p in distutils.sysconfig.get_config_vars().values() | 1518 # PyPy's library path scheme is not affected by this. |
1570 if isinstance(p, basestring) and 'lib64' in p]: | 1519 # Return early or we will die on the following assert. |
1571 # PyPy's library path scheme is not affected by this. | 1520 if is_pypy: |
1572 # Return early or we will die on the following assert. | 1521 logger.debug('PyPy detected, skipping lib64 symlinking') |
1573 if is_pypy: | 1522 return |
1574 logger.debug('PyPy detected, skipping lib64 symlinking') | 1523 # Check we have a lib64 library path |
1575 return | 1524 if not [p for p in distutils.sysconfig.get_config_vars().values() |
| 1525 if isinstance(p, basestring) and 'lib64' in p]: |
| 1526 return |
1576 | 1527 |
1577 logger.debug('This system uses lib64; symlinking lib64 to lib') | 1528 logger.debug('This system uses lib64; symlinking lib64 to lib') |
1578 | 1529 |
1579 assert os.path.basename(lib_dir) == 'python%s' % sys.version[:3], ( | 1530 assert os.path.basename(lib_dir) == 'python%s' % sys.version[:3], ( |
1580 "Unexpected python lib dir: %r" % lib_dir) | 1531 "Unexpected python lib dir: %r" % lib_dir) |
1581 lib_parent = os.path.dirname(lib_dir) | 1532 lib_parent = os.path.dirname(lib_dir) |
1582 top_level = os.path.dirname(lib_parent) | 1533 top_level = os.path.dirname(lib_parent) |
1583 lib_dir = os.path.join(top_level, 'lib') | 1534 lib_dir = os.path.join(top_level, 'lib') |
1584 lib64_link = os.path.join(top_level, 'lib64') | 1535 lib64_link = os.path.join(top_level, 'lib64') |
1585 assert os.path.basename(lib_parent) == 'lib', ( | 1536 assert os.path.basename(lib_parent) == 'lib', ( |
1586 "Unexpected parent dir: %r" % lib_parent) | 1537 "Unexpected parent dir: %r" % lib_parent) |
1587 if os.path.lexists(lib64_link): | 1538 if os.path.lexists(lib64_link): |
1588 return | 1539 return |
1589 if symlink: | 1540 if symlink: |
1590 os.symlink('lib', lib64_link) | 1541 os.symlink('lib', lib64_link) |
1591 else: | 1542 else: |
1592 copyfile('lib', lib64_link) | 1543 copyfile('lib', lib64_link) |
1593 | 1544 |
1594 def resolve_interpreter(exe): | 1545 def resolve_interpreter(exe): |
1595 """ | 1546 """ |
1596 If the executable given isn't an absolute path, search $PATH for the interpr
eter | 1547 If the executable given isn't an absolute path, search $PATH for the interpr
eter |
1597 """ | 1548 """ |
1598 # If the "executable" is a version number, get the installed executable for | 1549 # If the "executable" is a version number, get the installed executable for |
1599 # that version | 1550 # that version |
| 1551 orig_exe = exe |
1600 python_versions = get_installed_pythons() | 1552 python_versions = get_installed_pythons() |
1601 if exe in python_versions: | 1553 if exe in python_versions: |
1602 exe = python_versions[exe] | 1554 exe = python_versions[exe] |
1603 | 1555 |
1604 if os.path.abspath(exe) != exe: | 1556 if os.path.abspath(exe) != exe: |
1605 paths = os.environ.get('PATH', '').split(os.pathsep) | 1557 paths = os.environ.get('PATH', '').split(os.pathsep) |
1606 for path in paths: | 1558 for path in paths: |
1607 if os.path.exists(os.path.join(path, exe)): | 1559 if os.path.exists(join(path, exe)): |
1608 exe = os.path.join(path, exe) | 1560 exe = join(path, exe) |
1609 break | 1561 break |
1610 if not os.path.exists(exe): | 1562 if not os.path.exists(exe): |
1611 logger.fatal('The executable %s (from --python=%s) does not exist' % (ex
e, exe)) | 1563 logger.fatal('The path %s (from --python=%s) does not exist' % (exe, ori
g_exe)) |
1612 raise SystemExit(3) | 1564 raise SystemExit(3) |
1613 if not is_executable(exe): | 1565 if not is_executable(exe): |
1614 logger.fatal('The executable %s (from --python=%s) is not executable' %
(exe, exe)) | 1566 logger.fatal('The path %s (from --python=%s) is not an executable file'
% (exe, orig_exe)) |
1615 raise SystemExit(3) | 1567 raise SystemExit(3) |
1616 return exe | 1568 return exe |
1617 | 1569 |
1618 def is_executable(exe): | 1570 def is_executable(exe): |
1619 """Checks a file is executable""" | 1571 """Checks a file is executable""" |
1620 return os.access(exe, os.X_OK) | 1572 return os.path.isfile(exe) and os.access(exe, os.X_OK) |
1621 | 1573 |
1622 ############################################################ | 1574 ############################################################ |
1623 ## Relocating the environment: | 1575 ## Relocating the environment: |
1624 | 1576 |
1625 def make_environment_relocatable(home_dir): | 1577 def make_environment_relocatable(home_dir): |
1626 """ | 1578 """ |
1627 Makes the already-existing environment use relative paths, and takes out | 1579 Makes the already-existing environment use relative paths, and takes out |
1628 the #!-based environment selection in scripts. | 1580 the #!-based environment selection in scripts. |
1629 """ | 1581 """ |
1630 home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir) | 1582 home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir) |
(...skipping 22 matching lines...) Expand all Loading... |
1653 shebang = '#!%s' % os.path.normcase(os.path.join( | 1605 shebang = '#!%s' % os.path.normcase(os.path.join( |
1654 os.path.abspath(bin_dir), 'python%s' % new_shebang_args[2])) | 1606 os.path.abspath(bin_dir), 'python%s' % new_shebang_args[2])) |
1655 # This is what we'll put: | 1607 # This is what we'll put: |
1656 new_shebang = '#!%s python%s%s' % new_shebang_args | 1608 new_shebang = '#!%s python%s%s' % new_shebang_args |
1657 | 1609 |
1658 for filename in os.listdir(bin_dir): | 1610 for filename in os.listdir(bin_dir): |
1659 filename = os.path.join(bin_dir, filename) | 1611 filename = os.path.join(bin_dir, filename) |
1660 if not os.path.isfile(filename): | 1612 if not os.path.isfile(filename): |
1661 # ignore subdirs, e.g. .svn ones. | 1613 # ignore subdirs, e.g. .svn ones. |
1662 continue | 1614 continue |
1663 f = open(filename, 'rb') | 1615 lines = None |
1664 try: | 1616 with open(filename, 'rb') as f: |
1665 try: | 1617 try: |
1666 lines = f.read().decode('utf-8').splitlines() | 1618 lines = f.read().decode('utf-8').splitlines() |
1667 except UnicodeDecodeError: | 1619 except UnicodeDecodeError: |
1668 # This is probably a binary program instead | 1620 # This is probably a binary program instead |
1669 # of a script, so just ignore it. | 1621 # of a script, so just ignore it. |
1670 continue | 1622 continue |
1671 finally: | |
1672 f.close() | |
1673 if not lines: | 1623 if not lines: |
1674 logger.warn('Script %s is an empty file' % filename) | 1624 logger.warn('Script %s is an empty file' % filename) |
1675 continue | 1625 continue |
1676 | 1626 |
1677 old_shebang = lines[0].strip() | 1627 old_shebang = lines[0].strip() |
1678 old_shebang = old_shebang[0:2] + os.path.normcase(old_shebang[2:]) | 1628 old_shebang = old_shebang[0:2] + os.path.normcase(old_shebang[2:]) |
1679 | 1629 |
1680 if not old_shebang.startswith(shebang): | 1630 if not old_shebang.startswith(shebang): |
1681 if os.path.basename(filename) in OK_ABS_SCRIPTS: | 1631 if os.path.basename(filename) in OK_ABS_SCRIPTS: |
1682 logger.debug('Cannot make script %s relative' % filename) | 1632 logger.debug('Cannot make script %s relative' % filename) |
1683 elif lines[0].strip() == new_shebang: | 1633 elif lines[0].strip() == new_shebang: |
1684 logger.info('Script %s has already been made relative' % filenam
e) | 1634 logger.info('Script %s has already been made relative' % filenam
e) |
1685 else: | 1635 else: |
1686 logger.warn('Script %s cannot be made relative (it\'s not a norm
al script that starts with %s)' | 1636 logger.warn('Script %s cannot be made relative (it\'s not a norm
al script that starts with %s)' |
1687 % (filename, shebang)) | 1637 % (filename, shebang)) |
1688 continue | 1638 continue |
1689 logger.notify('Making script %s relative' % filename) | 1639 logger.notify('Making script %s relative' % filename) |
1690 script = relative_script([new_shebang] + lines[1:]) | 1640 script = relative_script([new_shebang] + lines[1:]) |
1691 f = open(filename, 'wb') | 1641 with open(filename, 'wb') as f: |
1692 f.write('\n'.join(script).encode('utf-8')) | 1642 f.write('\n'.join(script).encode('utf-8')) |
1693 f.close() | 1643 |
1694 | 1644 |
1695 def relative_script(lines): | 1645 def relative_script(lines): |
1696 "Return a script that'll work in a relocatable environment." | 1646 "Return a script that'll work in a relocatable environment." |
1697 activate = "import os; activate_this=os.path.join(os.path.dirname(os.path.re
alpath(__file__)), 'activate_this.py'); exec(compile(open(activate_this).read(),
activate_this, 'exec'), dict(__file__=activate_this)); del os, activate_this" | 1647 activate = "import os; activate_this=os.path.join(os.path.dirname(os.path.re
alpath(__file__)), 'activate_this.py'); exec(compile(open(activate_this).read(),
activate_this, 'exec'), dict(__file__=activate_this)); del os, activate_this" |
1698 # Find the last future statement in the script. If we insert the activation | 1648 # Find the last future statement in the script. If we insert the activation |
1699 # line before a future statement, Python will raise a SyntaxError. | 1649 # line before a future statement, Python will raise a SyntaxError. |
1700 activate_at = None | 1650 activate_at = None |
1701 for idx, line in reversed(list(enumerate(lines))): | 1651 for idx, line in reversed(list(enumerate(lines))): |
1702 if line.split()[:3] == ['from', '__future__', 'import']: | 1652 if line.split()[:3] == ['from', '__future__', 'import']: |
1703 activate_at = idx + 1 | 1653 activate_at = idx + 1 |
(...skipping 26 matching lines...) Expand all Loading... |
1730 fixup_pth_file(filename) | 1680 fixup_pth_file(filename) |
1731 if filename.endswith('.egg-link'): | 1681 if filename.endswith('.egg-link'): |
1732 if not os.access(filename, os.W_OK): | 1682 if not os.access(filename, os.W_OK): |
1733 logger.warn('Cannot write .egg-link file %s, skipping' % fil
ename) | 1683 logger.warn('Cannot write .egg-link file %s, skipping' % fil
ename) |
1734 else: | 1684 else: |
1735 fixup_egg_link(filename) | 1685 fixup_egg_link(filename) |
1736 | 1686 |
1737 def fixup_pth_file(filename): | 1687 def fixup_pth_file(filename): |
1738 lines = [] | 1688 lines = [] |
1739 prev_lines = [] | 1689 prev_lines = [] |
1740 f = open(filename) | 1690 with open(filename) as f: |
1741 prev_lines = f.readlines() | 1691 prev_lines = f.readlines() |
1742 f.close() | |
1743 for line in prev_lines: | 1692 for line in prev_lines: |
1744 line = line.strip() | 1693 line = line.strip() |
1745 if (not line or line.startswith('#') or line.startswith('import ') | 1694 if (not line or line.startswith('#') or line.startswith('import ') |
1746 or os.path.abspath(line) != line): | 1695 or os.path.abspath(line) != line): |
1747 lines.append(line) | 1696 lines.append(line) |
1748 else: | 1697 else: |
1749 new_value = make_relative_path(filename, line) | 1698 new_value = make_relative_path(filename, line) |
1750 if line != new_value: | 1699 if line != new_value: |
1751 logger.debug('Rewriting path %s as %s (in %s)' % (line, new_valu
e, filename)) | 1700 logger.debug('Rewriting path %s as %s (in %s)' % (line, new_valu
e, filename)) |
1752 lines.append(new_value) | 1701 lines.append(new_value) |
1753 if lines == prev_lines: | 1702 if lines == prev_lines: |
1754 logger.info('No changes to .pth file %s' % filename) | 1703 logger.info('No changes to .pth file %s' % filename) |
1755 return | 1704 return |
1756 logger.notify('Making paths in .pth file %s relative' % filename) | 1705 logger.notify('Making paths in .pth file %s relative' % filename) |
1757 f = open(filename, 'w') | 1706 with open(filename, 'w') as f: |
1758 f.write('\n'.join(lines) + '\n') | 1707 f.write('\n'.join(lines) + '\n') |
1759 f.close() | |
1760 | 1708 |
1761 def fixup_egg_link(filename): | 1709 def fixup_egg_link(filename): |
1762 f = open(filename) | 1710 with open(filename) as f: |
1763 link = f.readline().strip() | 1711 link = f.readline().strip() |
1764 f.close() | |
1765 if os.path.abspath(link) != link: | 1712 if os.path.abspath(link) != link: |
1766 logger.debug('Link in %s already relative' % filename) | 1713 logger.debug('Link in %s already relative' % filename) |
1767 return | 1714 return |
1768 new_link = make_relative_path(filename, link) | 1715 new_link = make_relative_path(filename, link) |
1769 logger.notify('Rewriting link %s in %s as %s' % (link, filename, new_link)) | 1716 logger.notify('Rewriting link %s in %s as %s' % (link, filename, new_link)) |
1770 f = open(filename, 'w') | 1717 with open(filename, 'w') as f: |
1771 f.write(new_link) | 1718 f.write(new_link) |
1772 f.close() | |
1773 | 1719 |
1774 def make_relative_path(source, dest, dest_is_directory=True): | 1720 def make_relative_path(source, dest, dest_is_directory=True): |
1775 """ | 1721 """ |
1776 Make a filename relative, where the filename is dest, and it is | 1722 Make a filename relative, where the filename is dest, and it is |
1777 being referred to from the filename source. | 1723 being referred to from the filename source. |
1778 | 1724 |
1779 >>> make_relative_path('/usr/share/something/a-file.pth', | 1725 >>> make_relative_path('/usr/share/something/a-file.pth', |
1780 ... '/usr/share/another-place/src/Directory') | 1726 ... '/usr/share/another-place/src/Directory') |
1781 '../another-place/src/Directory' | 1727 '../another-place/src/Directory' |
1782 >>> make_relative_path('/usr/share/something/a-file.pth', | 1728 >>> make_relative_path('/usr/share/something/a-file.pth', |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1845 script from that package. | 1791 script from that package. |
1846 | 1792 |
1847 If you provide something like ``python_version='2.5'`` then the | 1793 If you provide something like ``python_version='2.5'`` then the |
1848 script will start with ``#!/usr/bin/env python2.5`` instead of | 1794 script will start with ``#!/usr/bin/env python2.5`` instead of |
1849 ``#!/usr/bin/env python``. You can use this when the script must | 1795 ``#!/usr/bin/env python``. You can use this when the script must |
1850 be run with a particular Python version. | 1796 be run with a particular Python version. |
1851 """ | 1797 """ |
1852 filename = __file__ | 1798 filename = __file__ |
1853 if filename.endswith('.pyc'): | 1799 if filename.endswith('.pyc'): |
1854 filename = filename[:-1] | 1800 filename = filename[:-1] |
1855 f = codecs.open(filename, 'r', encoding='utf-8') | 1801 with codecs.open(filename, 'r', encoding='utf-8') as f: |
1856 content = f.read() | 1802 content = f.read() |
1857 f.close() | |
1858 py_exe = 'python%s' % python_version | 1803 py_exe = 'python%s' % python_version |
1859 content = (('#!/usr/bin/env %s\n' % py_exe) | 1804 content = (('#!/usr/bin/env %s\n' % py_exe) |
1860 + '## WARNING: This file is generated\n' | 1805 + '## WARNING: This file is generated\n' |
1861 + content) | 1806 + content) |
1862 return content.replace('##EXT' 'END##', extra_text) | 1807 return content.replace('##EXT' 'END##', extra_text) |
1863 | 1808 |
1864 ##EXTEND## | 1809 ##EXTEND## |
1865 | 1810 |
1866 def convert(s): | 1811 def convert(s): |
1867 b = base64.b64decode(s.encode('ascii')) | 1812 b = base64.b64decode(s.encode('ascii')) |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2007 Q+6hHuihalPc51hgzNIcqicV3xFkPs4UdMGX53zgGbre9sPX28uXR/ZwAfkdXzuKhLLJRo5hv3Sy | 1952 Q+6hHuihalPc51hgzNIcqicV3xFkPs4UdMGX53zgGbre9sPX28uXR/ZwAfkdXzuKhLLJRo5hv3Sy |
2008 MXdeKul0J2Ypp5Suh3s1JySsW1w5UNknGNrbdEpSBvY/Js+BIY289/0hM9PDu3p/1MbUst4RTEmM | 1953 MXdeKul0J2Ypp5Suh3s1JySsW1w5UNknGNrbdEpSBvY/Js+BIY289/0hM9PDu3p/1MbUst4RTEmM |
2009 n6kJTcsp4tG42yeT7nQbtdUFwgVJjwDSUYEAC8F0dKOTILrlLO/xC70bnNd0Ha97whQ6UkHJYj5H | 1954 n6kJTcsp4tG42yeT7nQbtdUFwgVJjwDSUYEAC8F0dKOTILrlLO/xC70bnNd0Ha97whQ6UkHJYj5H |
2010 cA/j+zX4tbtTIfGjujOKpj83aHOgXnIQbvYduNXEC4UMm4T21Bs+GHABuCa7v//LR/TvpjHa7oe7 | 1955 cA/j+zX4tbtTIfGjujOKpj83aHOgXnIQbvYduNXEC4UMm4T21Bs+GHABuCa7v//LR/TvpjHa7oe7 |
2011 /Grb6lVvHSD7spj5iplBLRKZxxEYGdCbY9LWWC5hBB2voWno6DJUMzfkC3T8KJsWL9umDQY5szPt | 1956 /Grb6lVvHSD7spj5iplBLRKZxxEYGdCbY9LWWC5hBB2voWno6DJUMzfkC3T8KJsWL9umDQY5szPt |
2012 AVijEPwfucjncQ== | 1957 AVijEPwfucjncQ== |
2013 """) | 1958 """) |
2014 | 1959 |
2015 ##file activate.sh | 1960 ##file activate.sh |
2016 ACTIVATE_SH = convert(""" | 1961 ACTIVATE_SH = convert(""" |
2017 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 | 1975 VzsV75usvTdYef+57v5n1b225qhXfwEmxHEs |
2031 +n8O9H8f5vsGOWXsL1+1k3g= | |
2032 """) | 1976 """) |
2033 | 1977 |
2034 ##file activate.fish | 1978 ##file activate.fish |
2035 ACTIVATE_FISH = convert(""" | 1979 ACTIVATE_FISH = convert(""" |
2036 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 | 1994 wYyNuRPSTcd/B48Ppeg= |
2051 32XS1ITj/qLjN72ob0hc5C9bzw8MhfmL | |
2052 """) | 1995 """) |
2053 | 1996 |
2054 ##file activate.csh | 1997 ##file activate.csh |
2055 ACTIVATE_CSH = convert(""" | 1998 ACTIVATE_CSH = convert(""" |
2056 eJx9VG1P2zAQ/u5fcYQKNgTNPtN1WxlIQ4KCUEGaxuQ6yYVYSuzKdhqVX7+zk3bpy5YPUXL3PPfc | 1999 eJx1U2FP2zAQ/e5f8TAV3Soo+0zXbYUiDQkKQgVp2ibjJNfFUuIg22nVf885SVFLO3+I7Lt3fr6X |
2057 ne98DLNCWshliVDV1kGCUFvMoJGugMjq2qQIiVSxSJ1cCofD1BYRnOVGV0CfZ0N2DD91DalQSjsw | 2000 d8eY58ZjYQpCWfuAhFB7yrAyIYf0Ve1SQmLsuU6DWepAw9TnEoOFq0rwdjAUx/hV1Ui1tVWAqy1M |
2058 tQLpIJMGU1euvPe7QeJlkKzgWixlhnAt4aoUVsLnLBiy5NtbJWQ5THX1ZciYKKWwkOFaE04dUm6D | 2001 QGYcpaFYx+yVI67LkKwx1UuTEaYGl4X2Bl+zJpAlP/6V2hTDtCq/DYXQhdEeGW040Q/Eb+t9V/e3 |
2059 r/zh7pq/3D7Nnid3/HEy+wFHY/gEJydg0aFaQrBFgz1c5DG1IhTs+UZgsBC2GMFBlaeH+8dZXwcW | 2002 U/V88zh/mtyqh8n8J47G+IKTE3gKZJdoYrK3h5MRU1tGYS83gqNc+3yEgyyP93cP820evHLvr2H8 |
2060 VPvCjXdlAvCfQsE7al0+07XjZvrSCUevR5dnkVeKlFYZmUztG4BdzL2u9KyLVabTU0bdfg7a0hgs | 2003 kaYB/peoyY7aVHzpJnE9e+6I5Z+ji4GMTNJWNuOQq6MA1N25p8pW9HWdVWlfsNpPDbdxjgpaahuw |
2061 cSmUg6UwUiQl2iHrcbcVGNvPCiLOe7+cRwG13z9qRGgx2z6DHjfm/Op2yqeT+xvOLzs0PTKHDz2V | 2004 1M7opCA/FFu1uwxC7L8KUqmto1KyQe3rx0I0Eovdf7BVe67U5c1MzSZ310pddGheZoFPWyytRkzU |
2062 tkckFHoQfQRXoGJAj9el0FyJCmEMhzgMS4sB7KPOE2ExoLcSieYwDvR+cP8cg11gKkVJc2wRcm1g | 2005 aCA/I+RkBXhFXr5aWV0SxjhUI6jwdAj8kmhPzX7nTfJFkM3MImp2VdVFFq1vLHSU5szYQK4Ri+Jd |
2063 QhYFlXiTaTfO2ki0fQoiFM4tLuO4aZrhOzqR4dIPcWx17hphMBY+Srwh7RTyN83XOWkcSPh1Pg/k | 2006 xlW2JBtOGcyYVW7SnB3v6RS91g3gKapZ0oWxbHVteYIIq3iv7QeuSrUj6KSqQ+yqsxDj1ivNQxKF |
2064 TXX/jbJTbMtUmcxZ+/bbqOsy82suFQg/BhdSOTRhMNBHlUarCpU7JzBhmkKmRejKOQzayQe6MWoa | 2007 YON10Q+NH/ARS95i5Tuqq2Vxfvc23f/FO6zrtXXmJr+ZtMY9/A15ZXFWtmch2rEQ4g1ryVHH |
2065 n1wqWmuh6LZAaHxcdeqIlVLhIBJdO9/kbl0It2oEXQj+eGjJOuvOIR/YGRqvFhttUB2XTvLXYN2H | |
2066 37CBdbW2W7j2r2+VsCn0doVWcFG1/4y1VwBjfwAyoZhD | |
2067 """) | 2008 """) |
2068 | 2009 |
2069 ##file activate.bat | 2010 ##file activate.bat |
2070 ACTIVATE_BAT = convert(""" | 2011 ACTIVATE_BAT = convert(""" |
2071 eJx9UdEKgjAUfW6wfxjiIH+hEDKUFHSKLCMI7kNOEkIf9P9pTJ3OLJ/03HPPPed4Es9XS9qqwqgT | 2012 eJx9Ul9LhEAQfxf8DoOclI/dYyFkaCmcq4gZQTBUrincuZFbff12T133TM+nnd35/Zvxlr7XDFhV |
2072 PbGKKOdXL4aAFS7A4gvAwgijuiKlqOpGlATS2NeMLE+TjJM9RkQ+SmqAXLrBo1LLIeLdiWlD6jZt | 2013 mUZHOVhFlOWP3g4DUriIWoVomYZpNBWUtGpaWgImO191pFkSpzlcmgaI70jVX7n2Qp8tuByg+46O |
2073 r7VNubWkndkXaxg5GO3UaOOKS6drO3luDDiO5my3iA0YAKGzPRV1ack8cOdhysI0CYzIPzjSiH5X | 2014 CMHbMq64T+nmlJt082D1T44muCDk2prgEHF4mdI9RaS/QwSt3zSyIAaftRccvqVTBziD1x/WlPD5 |
2074 0QcvC8Lfaj0emsVKYF2rhL5L3fCkVjV76kShi59NHwDniAHzkgDgqBcwOgTMx+gDQQqXCw== | 2015 xd729NDBb8Nr4DU9QNMKsJeH9pkhPedhQsIkDuCDCa6A+NF9IevVFAohkqizdHetg/tkWvPoftWJ |
| 2016 MCqnOxv7/x7Np6yv9P2Ker5dmX8yNyCkkWnbZy3N5LarczlqL8htx2EM9rQ/2H5BvIsIEi8OEG8U |
| 2017 +g8CsNTr |
2075 """) | 2018 """) |
2076 | 2019 |
2077 ##file deactivate.bat | 2020 ##file deactivate.bat |
2078 DEACTIVATE_BAT = convert(""" | 2021 DEACTIVATE_BAT = convert(""" |
2079 eJxzSE3OyFfIT0vj4ipOLVEI8wwKCXX0iXf1C7Pl4spMU0hJTcvMS01RiPf3cYmHyQYE+fsGhCho | 2022 eJyFkN0KgkAUhO8F32EQpHqFQEjQUPAPMaErqVxzId3IrV6/XST/UDx3c86c4WMO5FYysKJQFVVp |
2080 cCkAAUibEkTEVhWLMlUlLk6QGixStlyaeCyJDPHw9/Pw93VFsQguim4ZXAJoIUw5DhX47XUM8UCx | 2023 CEfqxsnJ9DI7SA25i20fFqs3HO+GYLsDZ7h8GM3xfLHrg1QNvpSX4CWpQGvokZk4uqrQAjXjyElB |
2081 EchHtwsohN1bILUgw61c/Vy4AJYPYm4= | 2024 a5IjCz0r+2dHcehHCe5MZNmB5R7TdqMqECMptHZh6DN/utb7Zs6Cej8OXYE5J04YOKFvD4GkHuJ0 |
| 2025 pilSd1jG6n87tDZ+BUwUOepI6CGSkFMYWf0ihvT33Qj1A+tCkSI= |
2082 """) | 2026 """) |
2083 | 2027 |
2084 ##file activate.ps1 | 2028 ##file activate.ps1 |
2085 ACTIVATE_PS = convert(""" | 2029 ACTIVATE_PS = convert(""" |
2086 eJylWdmO41hyfW+g/0FTU7C7IXeJIqmtB/3AnZRIStxF2kaBm7gv4ipyMF/mB3+Sf8GXVGVl1tLT | 2030 eJylWdmO41hyfW+g/0FTU7C7IXeJIqmtB/3AnZRIStxF2kaBm7gv4ipyMF/mB3+Sf8GXVGVl1tLT |
2087 43ECSqR4b5wbETeWE8z/+a///vNCDaN6cYtSf5G1dbNw/IVXNIu6aCvX9xa3qsgWl0IJ/7IYinbh | 2031 43ECSqR4b5wbETeWE8z/+a///vNCDaN6cYtSf5G1dbNw/IVXNIu6aCvX9xa3qsgWl0IJ/7IYinbh |
2088 2nkOVqs2X0TNjz/8eeFFle826fBhQRaLBkD9uviw+LCy3Sbq7Mb/UNbrH3+YNtLcVaB+Xbipb+eL | 2032 2nkOVqs2X0TNjz/8eeFFle826fBhQRaLBkD9uviw+LCy3Sbq7Mb/UNbrH3+YNtLcVaB+Xbipb+eL |
2089 tly0eVsD/M6u6g8//vC+dquobH5VWU75eMFUdvHb4n02RHlXuHYTFfmHbHCLLLNz70NpN+GrBI4p | 2033 tly0eVsD/M6u6g8//vC+dquobH5VWU75eMFUdvHb4n02RHlXuHYTFfmHbHCLLLNz70NpN+GrBI4p |
2090 1EeSk4FAXaZR88u0vPip8usi7fznt3fvP+OuPnx49/Pil4td+XnzigIAPoqYQH2J8v4z+C+8b98m | 2034 1EeSk4FAXaZR88u0vPip8usi7fznt3fvP+OuPnx49/Pil4td+XnzigIAPoqYQH2J8v4z+C+8b98m |
2091 Q25t7k76LIK0cOz0V89/MXXx0+Lf6z5q3PA/F+/FIif9uqnaadFf/PzXSXYBfqIb2NeApecJwPzI | 2035 Q25t7k76LIK0cOz0V89/MXXx0+Lf6z5q3PA/F+/FIif9uqnaadFf/PzXSXYBfqIb2NeApecJwPzI |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2213 5a3p0cRKiEe2NtLAFikftnDco0ko/SFEVgEZ8aRCZDIPY9xbA8pE9M4jfW/B2CjiHq9zbJVZuOQq | 2157 5a3p0cRKiEe2NtLAFikftnDco0ko/SFEVgEZ8aRCZDIPY9xbA8pE9M4jfW/B2CjiHq9zbJVZuOQq |
2214 siwTIvpxKYCembPAU4Muwi/Z4zfvrZ/MXipKeB8C+qisSZYiWfjJfs+0/MFMdWn1hJcO5U7G/SLa | 2158 siwTIvpxKYCembPAU4Muwi/Z4zfvrZ/MXipKeB8C+qisSZYiWfjJfs+0/MFMdWn1hJcO5U7G/SLa |
2215 xVx8zU6VG/PXLXvfsyyzUqjeWR8hjGE+2iCE1W1tQ82hsCJN9dzKaoexyB/uH79TnjwvxcW0ntSb | 2159 xVx8zU6VG/PXLXvfsyyzUqjeWR8hjGE+2iCE1W1tQ82hsCJN9dzKaoexyB/uH79TnjwvxcW0ntSb |
2216 yZ8jq1Z5Q1UXsyy3gf9nbjTEj7NzQMfCJa/YSmrQ+2D/BqfiOi6sclrGzvoeVivIj8rcfcmnIQRF | 2160 yZ8jq1Z5Q1UXsyy3gf9nbjTEj7NzQMfCJa/YSmrQ+2D/BqfiOi6sclrGzvoeVivIj8rcfcmnIQRF |
2217 7XCyeZI7DFe5/lhlCs5PRf5QW66VXT/NrlQ46oD/D6InkOmi3IQcbhKxAX2g4a+Xd5s3UtCtG2py | 2161 7XCyeZI7DFe5/lhlCs5PRf5QW66VXT/NrlQ46oD/D6InkOmi3IQcbhKxAX2g4a+Xd5s3UtCtG2py |
2218 m8eg6WYWqR6SL5OjKMGfSrYt/6kxxQtOpeAgj1LXBNmpE2ElmCSIy5H0zFd8gJ924HWijWhb2hRC | 2162 m8eg6WYWqR6SL5OjKMGfSrYt/6kxxQtOpeAgj1LXBNmpE2ElmCSIy5H0zFd8gJ924HWijWhb2hRC |
2219 6wNEm1QdDZtuSZcEprIUBo/XRNcbQe1OUbQ/r3hPTaPJJDNtFLu8KHV5XoNr3Eo6h6YtOKw8e8yw | 2163 6wNEm1QdDZtuSZcEprIUBo/XRNcbQe1OUbQ/r3hPTaPJJDNtFLu8KHV5XoNr3Eo6h6YtOKw8e8yw |
2220 VF5PnJ+ts3a9/Mz38RpG/AUSzYUW | 2164 VF5PnJ+ts3a9/Mz38RpG/AUSzYUW |
2221 """) | 2165 """) |
2222 | 2166 |
| 2167 ##file python-config |
| 2168 PYTHON_CONFIG = convert(""" |
| 2169 eJyNVV1P2zAUfc+v8ODBiSABxlulTipbO6p1LWqBgVhlhcZpPYUkctzSivHfd6+dpGloGH2Ja/ue |
| 2170 e+65Hz78xNhtf3x90xmw7vCWsRPGLvpDNuz87MKfdKMWSWxZ4ilNpCLZJiuWc66SVFUOZkkcirll |
| 2171 rfxIBAzOMtImDzSVPBRrekwoX/OZu/0r4lm0DHiG60g86u8sjPw5rCyy86NRkB8QuuBRSqfAKESn |
| 2172 3orLTCQxE3GYkC9tYp8fk89OSwNsmXgizrhUtnumeSgeo5GbLUMk49Rv+2nK48Cm/qMwfp333J2/ |
| 2173 dVcAGE0CIQHBsgIeEr4Wij0LtWDLzJ9ze5YEvH2WI6CHTAVcSu9ZCsXtgxu81CIvp6/k4eXsdfo7 |
| 2174 PvDCRD75yi41QitfzlcPp1OI7i/1/iQitqnr0iMgQ+A6wa+IKwwdxyk9IiXNAzgquTFU8NIxAVjM |
| 2175 osm1Zz526e+shQ4hKRVci69nPC3Kw4NQEmkQ65E7OodxorSvxjvpBjQHDmWFIQ1mlmzlS5vedseT |
| 2176 /mgIEsMJ7Lxz2bLAF9M5xeLEhdbHxpWOw0GdkJApMVBRF1y+a0z3c9WZPAXGFcFrJgCIB+024uad |
| 2177 0CrzmEoRa3Ub4swNIHPGf7QDV+2uj2OiFWsChgCwjKqN6rp5izpbH6Wc1O1TclQTP/XVwi6anTr1 |
| 2178 1sbubjZLI1+VptPSdCfwnFBrB1jvebrTA9uUhU2/9gad7xPqeFkaQcnnLbCViZK8d7R1kxzFrIJV |
| 2179 8EaLYmKYpvGVkig+3C5HCXbM1jGCGekiM2pRCVPyRyXYdPf6kcbWEQ36F5V4Gq9N7icNNw+JHwRE |
| 2180 LTgxRXACpvnQv/PuT0xCCAywY/K4hE6Now2qDwaSE5FB+1agsoUveYDepS83qFcF1NufvULD3fTl |
| 2181 g6Hgf7WBt6lzMeiyyWVn3P1WVbwaczHmTzE9A5SyItTVgFYyvs/L/fXlaNgbw8v3azT+0eikVlWD |
| 2182 /vBHbzQumP23uBCjsYdrL9OWARwxs/nuLOzeXbPJTa/Xv6sUmQir5pC1YRLz3eA+CD8Z0XpcW8v9 |
| 2183 MZWF36ryyXXf3yBIz6nzqz8Muyz0m5Qj7OexfYo/Ph3LqvkHUg7AuA== |
| 2184 """) |
| 2185 |
2223 MH_MAGIC = 0xfeedface | 2186 MH_MAGIC = 0xfeedface |
2224 MH_CIGAM = 0xcefaedfe | 2187 MH_CIGAM = 0xcefaedfe |
2225 MH_MAGIC_64 = 0xfeedfacf | 2188 MH_MAGIC_64 = 0xfeedfacf |
2226 MH_CIGAM_64 = 0xcffaedfe | 2189 MH_CIGAM_64 = 0xcffaedfe |
2227 FAT_MAGIC = 0xcafebabe | 2190 FAT_MAGIC = 0xcafebabe |
2228 BIG_ENDIAN = '>' | 2191 BIG_ENDIAN = '>' |
2229 LITTLE_ENDIAN = '<' | 2192 LITTLE_ENDIAN = '<' |
2230 LC_LOAD_DYLIB = 0xc | 2193 LC_LOAD_DYLIB = 0xc |
2231 maxint = majver == 3 and getattr(sys, 'maxsize') or getattr(sys, 'maxint') | 2194 maxint = majver == 3 and getattr(sys, 'maxsize') or getattr(sys, 'maxint') |
2232 | 2195 |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2349 elif magic == MH_MAGIC: | 2312 elif magic == MH_MAGIC: |
2350 do_macho(file, 32, BIG_ENDIAN) | 2313 do_macho(file, 32, BIG_ENDIAN) |
2351 elif magic == MH_CIGAM: | 2314 elif magic == MH_CIGAM: |
2352 do_macho(file, 32, LITTLE_ENDIAN) | 2315 do_macho(file, 32, LITTLE_ENDIAN) |
2353 elif magic == MH_MAGIC_64: | 2316 elif magic == MH_MAGIC_64: |
2354 do_macho(file, 64, BIG_ENDIAN) | 2317 do_macho(file, 64, BIG_ENDIAN) |
2355 elif magic == MH_CIGAM_64: | 2318 elif magic == MH_CIGAM_64: |
2356 do_macho(file, 64, LITTLE_ENDIAN) | 2319 do_macho(file, 64, LITTLE_ENDIAN) |
2357 | 2320 |
2358 assert(len(what) >= len(value)) | 2321 assert(len(what) >= len(value)) |
2359 do_file(open(path, 'r+b')) | 2322 |
| 2323 with open(path, 'r+b') as f: |
| 2324 do_file(f) |
2360 | 2325 |
2361 | 2326 |
2362 if __name__ == '__main__': | 2327 if __name__ == '__main__': |
2363 main() | 2328 main() |
2364 | 2329 |
2365 ## TODO: | 2330 # TODO: |
2366 ## Copy python.exe.manifest | 2331 # Copy python.exe.manifest |
2367 ## Monkeypatch distutils.sysconfig | 2332 # Monkeypatch distutils.sysconfig |
OLD | NEW |