1# coding: utf-8 2from __future__ import unicode_literals, division, absolute_import, print_function 3 4import os 5import subprocess 6import sys 7 8 9run_args = [ 10 { 11 'name': 'version', 12 'kwarg': 'version', 13 }, 14] 15 16 17def _write_env(env, key, value): 18 sys.stdout.write("%s: %s\n" % (key, value)) 19 sys.stdout.flush() 20 if sys.version_info < (3,): 21 env[key.encode('utf-8')] = value.encode('utf-8') 22 else: 23 env[key] = value 24 25 26def run(version=None): 27 """ 28 Installs a version of Python on Mac using pyenv 29 30 :return: 31 A bool - if Python was installed successfully 32 """ 33 34 if sys.platform == 'win32': 35 raise ValueError('pyenv-install is not designed for Windows') 36 37 if version not in set(['2.6', '3.3']): 38 raise ValueError('Invalid version: %r' % version) 39 40 python_path = os.path.expanduser('~/.pyenv/versions/%s/bin' % version) 41 if os.path.exists(os.path.join(python_path, 'python')): 42 print(python_path) 43 return True 44 45 stdout = "" 46 stderr = "" 47 48 proc = subprocess.Popen( 49 'command -v pyenv', 50 shell=True, 51 stdout=subprocess.PIPE, 52 stderr=subprocess.PIPE 53 ) 54 proc.communicate() 55 if proc.returncode != 0: 56 proc = subprocess.Popen( 57 ['brew', 'install', 'pyenv'], 58 stdout=subprocess.PIPE, 59 stderr=subprocess.PIPE 60 ) 61 so, se = proc.communicate() 62 stdout += so.decode('utf-8') 63 stderr += se.decode('utf-8') 64 if proc.returncode != 0: 65 print(stdout) 66 print(stderr, file=sys.stderr) 67 return False 68 69 pyenv_script = './%s' % version 70 try: 71 with open(pyenv_script, 'wb') as f: 72 if version == '2.6': 73 contents = '#require_gcc\n' \ 74 'install_package "openssl-1.0.2k" "https://www.openssl.org/source/old/1.0.2/openssl-1.0.2k.tar.gz' \ 75 '#6b3977c61f2aedf0f96367dcfb5c6e578cf37e7b8d913b4ecb6643c3cb88d8c0" mac_openssl\n' \ 76 'install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz' \ 77 '#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline' \ 78 ' --if has_broken_mac_readline\n' \ 79 'install_package "Python-2.6.9" "https://www.python.org/ftp/python/2.6.9/Python-2.6.9.tgz' \ 80 '#7277b1285d8a82f374ef6ebaac85b003266f7939b3f2a24a3af52f9523ac94db" standard verify_py26' 81 elif version == '3.3': 82 contents = '#require_gcc\n' \ 83 'install_package "openssl-1.0.2k" "https://www.openssl.org/source/old/1.0.2/openssl-1.0.2k.tar.gz' \ 84 '#6b3977c61f2aedf0f96367dcfb5c6e578cf37e7b8d913b4ecb6643c3cb88d8c0" mac_openssl\n' \ 85 'install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz' \ 86 '#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline' \ 87 ' --if has_broken_mac_readline\n' \ 88 'install_package "Python-3.3.7" "https://www.python.org/ftp/python/3.3.7/Python-3.3.7.tar.xz' \ 89 '#85f60c327501c36bc18c33370c14d472801e6af2f901dafbba056f61685429fe" standard verify_py33' 90 f.write(contents.encode('utf-8')) 91 92 args = ['pyenv', 'install', pyenv_script] 93 stdin = None 94 stdin_contents = None 95 env = os.environ.copy() 96 97 if version == '2.6': 98 _write_env(env, 'PYTHON_CONFIGURE_OPTS', '--enable-ipv6') 99 stdin = subprocess.PIPE 100 stdin_contents = '--- configure 2021-08-05 20:17:26.000000000 -0400\n' \ 101 '+++ configure 2021-08-05 20:21:30.000000000 -0400\n' \ 102 '@@ -10300,17 +10300,8 @@\n' \ 103 ' rm -f core conftest.err conftest.$ac_objext \\\n' \ 104 ' conftest$ac_exeext conftest.$ac_ext\n' \ 105 ' \n' \ 106 '-if test "$buggygetaddrinfo" = "yes"; then\n' \ 107 '-\tif test "$ipv6" = "yes"; then\n' \ 108 '-\t\techo \'Fatal: You must get working getaddrinfo() function.\'\n' \ 109 '-\t\techo \' or you can specify "--disable-ipv6"\'.\n' \ 110 '-\t\texit 1\n' \ 111 '-\tfi\n' \ 112 '-else\n' \ 113 '-\n' \ 114 ' $as_echo "#define HAVE_GETADDRINFO 1" >>confdefs.h\n' \ 115 ' \n' \ 116 '-fi\n' \ 117 ' for ac_func in getnameinfo\n' \ 118 ' do :\n' \ 119 ' ac_fn_c_check_func "$LINENO" "getnameinfo" "ac_cv_func_getnameinfo"' 120 stdin_contents = stdin_contents.encode('ascii') 121 args.append('--patch') 122 123 proc = subprocess.Popen( 124 args, 125 stdout=subprocess.PIPE, 126 stderr=subprocess.PIPE, 127 stdin=stdin, 128 env=env 129 ) 130 so, se = proc.communicate(stdin_contents) 131 stdout += so.decode('utf-8') 132 stderr += se.decode('utf-8') 133 134 if proc.returncode != 0: 135 print(stdout) 136 print(stderr, file=sys.stderr) 137 return False 138 139 finally: 140 if os.path.exists(pyenv_script): 141 os.unlink(pyenv_script) 142 143 print(python_path) 144 return True 145