22import sys
33import shutil
44import mimetypes
5+ import re
56from pythonbrew .util import makedirs , symlink , Package , is_url , Link ,\
67 unlink , is_html , Subprocess , rm_r ,\
78 is_python25 , is_python24 , is_python26 , is_python27 ,\
89 extract_downloadfile , is_archive_file , path_to_fileurl , is_file ,\
910 fileurl_to_path , is_python30 , is_python31 , is_python32 ,\
10- get_macosx_deployment_target
11+ get_macosx_deployment_target , Version
1112from pythonbrew .define import PATH_BUILD , PATH_DISTS , PATH_PYTHONS ,\
1213 ROOT , PATH_LOG , DISTRIBUTE_SETUP_DLSITE ,\
1314 PATH_PATCHES_MACOSX_PYTHON25 , PATH_PATCHES_MACOSX_PYTHON24 ,\
1617 get_headerinfo_from_url
1718from pythonbrew .log import logger
1819from pythonbrew .exceptions import UnknownVersionException ,\
19- AlreadyInstalledException , NotSupportedVersionException
20+ NotSupportedVersionException
2021
2122class PythonInstaller (object ):
2223 """Python installer
@@ -45,11 +46,21 @@ def __init__(self, arg, options):
4546 self .install_dir = os .path .join (PATH_PYTHONS , pkg .name )
4647 self .build_dir = os .path .join (PATH_BUILD , pkg .name )
4748 self .download_file = os .path .join (PATH_DISTS , filename )
48-
49+
50+ self .options = options
51+ self .logfile = os .path .join (PATH_LOG , 'build.log' )
52+ self .patches = []
53+
54+ if Version (self .pkg .version ) >= '3.1' :
55+ self .configure_options = ['--with-computed-gotos' ]
56+ else :
57+ self .configure_options = []
58+
59+ def install (self ):
4960 # cleanup
5061 if os .path .isdir (self .build_dir ):
5162 shutil .rmtree (self .build_dir )
52-
63+
5364 # get content type.
5465 if is_file (self .download_url ):
5566 path = fileurl_to_path (self .download_url )
@@ -61,16 +72,11 @@ def __init__(self, arg, options):
6172 # note: maybe got 404 or 503 http status code.
6273 logger .error ("Invalid content-type: `%s`" % self .content_type )
6374 return
64-
65- self .options = options
66- self .logfile = os .path .join (PATH_LOG , 'build.log' )
67- self .configure_options = ''
68- self .patches = []
6975
70- def install (self ):
7176 if os .path .isdir (self .install_dir ):
7277 logger .info ("You are already installed `%s`" % self .pkg .name )
73- raise AlreadyInstalledException
78+ return
79+
7480 self .download_and_extract ()
7581 logger .info ("\n This could take a while. You can run the following command on another shell to track the status:" )
7682 logger .info (" tail -f %s\n " % self .logfile )
@@ -114,7 +120,7 @@ def download_and_extract(self):
114120 sys .exit (1 )
115121
116122 def patch (self ):
117- version = self .pkg .version
123+ version = Version ( self .pkg .version )
118124 # for ubuntu 11.04(Natty)
119125 if is_python24 (version ):
120126 patch_dir = os .path .join (PATH_PATCHES_ALL , "python24" )
@@ -170,7 +176,10 @@ def _add_patches_to_list(self, patch_dir, patch_files):
170176
171177 def configure (self ):
172178 s = Subprocess (log = self .logfile , cwd = self .build_dir , verbose = self .options .verbose )
173- s .check_call ("./configure --prefix=%s %s %s" % (self .install_dir , self .options .configure , self .configure_options ))
179+ cmd = "./configure --prefix=%s %s %s" % (self .install_dir , self .options .configure , ' ' .join (self .configure_options ))
180+ if self .options .verbose :
181+ logger .log (cmd )
182+ s .check_call (cmd )
174183
175184 def make (self ):
176185 jobs = self .options .jobs
@@ -185,22 +194,35 @@ def make(self):
185194 s .check_call ("make test" )
186195
187196 def make_install (self ):
188- version = self .pkg .version
197+ version = Version ( self .pkg .version )
189198 if version == "1.5.2" or version == "1.6.1" :
190199 makedirs (self .install_dir )
191200 s = Subprocess (log = self .logfile , cwd = self .build_dir , verbose = self .options .verbose )
192201 s .check_call ("make install" )
193202
194203 def symlink (self ):
195204 install_dir = os .path .realpath (self .install_dir )
205+ if self .options .framework :
206+ # create symlink bin -> /path/to/Frameworks/Python.framework/Versions/?.?/bin
207+ bin_dir = os .path .join (install_dir , 'bin' )
208+ if os .path .exists (bin_dir ):
209+ rm_r (bin_dir )
210+ m = re .match (r'\d\.\d' , self .pkg .version )
211+ if m :
212+ version = m .group (0 )
213+ symlink (os .path .join (install_dir ,'Frameworks' ,'Python.framework' ,'Versions' ,version ,'bin' ),
214+ os .path .join (bin_dir ))
215+
196216 path_python = os .path .join (install_dir ,'bin' ,'python' )
197217 if not os .path .isfile (path_python ):
198- path_python3 = os .path .join (install_dir ,'bin' ,'python3' )
199- path_python3_0 = os .path .join (install_dir ,'bin' ,'python3.0' )
200- if os .path .isfile (path_python3 ):
201- symlink (path_python3 , path_python )
202- elif os .path .isfile (path_python3_0 ):
203- symlink (path_python3_0 , path_python )
218+ src = None
219+ for d in os .listdir (os .path .join (install_dir ,'bin' )):
220+ if re .match (r'python\d\.\d' , d ):
221+ src = d
222+ break
223+ if src :
224+ path_src = os .path .join (install_dir ,'bin' ,src )
225+ symlink (path_src , path_python )
204226
205227 def install_setuptools (self ):
206228 options = self .options
@@ -237,22 +259,34 @@ def __init__(self, arg, options):
237259 super (PythonInstallerMacOSX , self ).__init__ (arg , options )
238260
239261 # check for version
240- version = self .pkg .version
262+ version = Version ( self .pkg .version )
241263 if version < '2.6' and (version != '2.4.6' and version < '2.5.5' ):
242264 logger .error ("`%s` is not supported on MacOSX Snow Leopard" % self .pkg .name )
243265 raise NotSupportedVersionException
244266 # set configure options
245267 target = get_macosx_deployment_target ()
246268 if target :
247- self .configure_options = 'MACOSX_DEPLOYMENT_TARGET=%s' % target
269+ self .configure_options .append ('MACOSX_DEPLOYMENT_TARGET=%s' % target )
270+
271+ # set build options
272+ if options .framework and options .static :
273+ logger .error ("Can't specify both framework and static." )
274+ raise Exception
275+ if options .framework :
276+ self .configure_options .append ('--enable-framework=%s' % os .path .join (self .install_dir , 'Frameworks' ))
277+ elif not options .static :
278+ self .configure_options .append ('--enable-shared' )
279+ if options .universal :
280+ self .configure_options .append ('--enable-universalsdk=/' )
281+ self .configure_options .append ('--with-universal-archs=intel' )
248282
249283 # note: skip `make test` to avoid hanging test_threading.
250284 if is_python25 (version ) or is_python24 (version ):
251285 self .options .no_test = True
252286
253287 def patch (self ):
254288 # note: want an interface to the source patching functionality. like a patchperl.
255- version = self .pkg .version
289+ version = Version ( self .pkg .version )
256290 if is_python24 (version ):
257291 patch_dir = PATH_PATCHES_MACOSX_PYTHON24
258292 self ._add_patches_to_list (patch_dir , ['patch-configure' , 'patch-Makefile.pre.in' ,
0 commit comments