1515from distutils .util import convert_path , subst_vars , change_root
1616from distutils .util import get_platform
1717from distutils .errors import DistutilsOptionError
18+ from site import USER_BASE
19+ from site import USER_SITE
20+
1821
1922if sys .version < "2.2" :
2023 WINDOWS_SCHEME = {
4851 'scripts' : '$base/bin' ,
4952 'data' : '$base' ,
5053 },
54+ 'unix_user' : {
55+ 'purelib' : '$usersite' ,
56+ 'platlib' : '$usersite' ,
57+ 'headers' : '$userbase/include/python$py_version_short/$dist_name' ,
58+ 'scripts' : '$userbase/bin' ,
59+ 'data' : '$userbase' ,
60+ },
5161 'nt' : WINDOWS_SCHEME ,
62+ 'nt_user' : {
63+ 'purelib' : '$usersite' ,
64+ 'platlib' : '$usersite' ,
65+ 'headers' : '$userbase/Python$py_version_nodot/Include/$dist_name' ,
66+ 'scripts' : '$userbase/Scripts' ,
67+ 'data' : '$userbase' ,
68+ },
5269 'mac' : {
5370 'purelib' : '$base/Lib/site-packages' ,
5471 'platlib' : '$base/Lib/site-packages' ,
5572 'headers' : '$base/Include/$dist_name' ,
5673 'scripts' : '$base/Scripts' ,
5774 'data' : '$base' ,
5875 },
76+ 'mac_user' : {
77+ 'purelib' : '$usersite' ,
78+ 'platlib' : '$usersite' ,
79+ 'headers' : '$userbase/$py_version_short/include/$dist_name' ,
80+ 'scripts' : '$userbase/bin' ,
81+ 'data' : '$userbase' ,
82+ },
5983 'os2' : {
6084 'purelib' : '$base/Lib/site-packages' ,
6185 'platlib' : '$base/Lib/site-packages' ,
6286 'headers' : '$base/Include/$dist_name' ,
6387 'scripts' : '$base/Scripts' ,
6488 'data' : '$base' ,
65- }
89+ },
90+ 'os2_home' : {
91+ 'purelib' : '$usersite' ,
92+ 'platlib' : '$usersite' ,
93+ 'headers' : '$userbase/include/python$py_version_short/$dist_name' ,
94+ 'scripts' : '$userbase/bin' ,
95+ 'data' : '$userbase' ,
96+ },
6697 }
6798
6899# The keys to an installation scheme; if any new types of files are to be
@@ -83,6 +114,8 @@ class install (Command):
83114 "(Unix only) prefix for platform-specific files" ),
84115 ('home=' , None ,
85116 "(Unix only) home directory to install under" ),
117+ ('user' , None ,
118+ "install in user site-package '%s'" % USER_SITE ),
86119
87120 # Or, just set the base director(y|ies)
88121 ('install-base=' , None ,
@@ -134,7 +167,7 @@ class install (Command):
134167 "filename in which to record list of installed files" ),
135168 ]
136169
137- boolean_options = ['compile' , 'force' , 'skip-build' ]
170+ boolean_options = ['compile' , 'force' , 'skip-build' , 'user' ]
138171 negative_opt = {'no-compile' : 'compile' }
139172
140173
@@ -145,6 +178,7 @@ def initialize_options(self):
145178 self .prefix = None
146179 self .exec_prefix = None
147180 self .home = None
181+ self .user = 0
148182
149183 # These select only the installation base; it's up to the user to
150184 # specify the installation scheme (currently, that means supplying
@@ -163,6 +197,8 @@ def initialize_options(self):
163197 self .install_lib = None # set to either purelib or platlib
164198 self .install_scripts = None
165199 self .install_data = None
200+ self .install_userbase = USER_BASE
201+ self .install_usersite = USER_SITE
166202
167203 self .compile = None
168204 self .optimize = None
@@ -238,6 +274,11 @@ def finalize_options(self):
238274 raise DistutilsOptionError (
239275 "must supply either home or prefix/exec-prefix -- not both" )
240276
277+ if self .user and (self .prefix or self .exec_prefix or self .home or
278+ self .install_base or self .install_platbase ):
279+ raise DistutilsOptionError ("can't combine user with with prefix/"
280+ "exec_prefix/home or install_(plat)base" )
281+
241282 # Next, stuff that's wrong (or dubious) only on certain platforms.
242283 if os .name != "posix" :
243284 if self .exec_prefix :
@@ -273,10 +314,13 @@ def finalize_options(self):
273314 'dist_fullname' : self .distribution .get_fullname (),
274315 'py_version' : py_version ,
275316 'py_version_short' : py_version [0 :3 ],
317+ 'py_version_nodot' : py_version [0 ] + py_version [2 ],
276318 'sys_prefix' : prefix ,
277319 'prefix' : prefix ,
278320 'sys_exec_prefix' : exec_prefix ,
279321 'exec_prefix' : exec_prefix ,
322+ 'userbase' : self .install_userbase ,
323+ 'usersite' : self .install_usersite ,
280324 }
281325 self .expand_basedirs ()
282326
@@ -298,6 +342,10 @@ def finalize_options(self):
298342
299343 self .dump_dirs ("post-expand_dirs()" )
300344
345+ # Create directories in the home dir:
346+ if self .user :
347+ self .create_home_path ()
348+
301349 # Pick the actual directory to install all modules to: either
302350 # install_purelib or install_platlib, depending on whether this
303351 # module distribution is pure or not. Of course, if the user
@@ -312,7 +360,8 @@ def finalize_options(self):
312360 # Convert directories from Unix /-separated syntax to the local
313361 # convention.
314362 self .convert_paths ('lib' , 'purelib' , 'platlib' ,
315- 'scripts' , 'data' , 'headers' )
363+ 'scripts' , 'data' , 'headers' ,
364+ 'userbase' , 'usersite' )
316365
317366 # Well, we're not actually fully completely finalized yet: we still
318367 # have to deal with 'extra_path', which is the hack for allowing
@@ -369,7 +418,13 @@ def finalize_unix(self):
369418 "installation scheme is incomplete" )
370419 return
371420
372- if self .home is not None :
421+ if self .user :
422+ if self .install_userbase is None :
423+ raise DistutilsPlatformError (
424+ "User base directory is not specified" )
425+ self .install_base = self .install_platbase = self .install_userbase
426+ self .select_scheme ("unix_user" )
427+ elif self .home is not None :
373428 self .install_base = self .install_platbase = self .home
374429 self .select_scheme ("unix_home" )
375430 else :
@@ -391,7 +446,13 @@ def finalize_unix(self):
391446
392447
393448 def finalize_other (self ): # Windows and Mac OS for now
394- if self .home is not None :
449+ if self .user :
450+ if self .install_userbase is None :
451+ raise DistutilsPlatformError (
452+ "User base directory is not specified" )
453+ self .install_base = self .install_platbase = self .install_userbase
454+ self .select_scheme (os .name + "_user" )
455+ elif self .home is not None :
395456 self .install_base = self .install_platbase = self .home
396457 self .select_scheme ("unix_home" )
397458 else :
@@ -419,7 +480,7 @@ def _expand_attrs(self, attrs):
419480 for attr in attrs :
420481 val = getattr (self , attr )
421482 if val is not None :
422- if os .name == 'posix' :
483+ if os .name == 'posix' or os . name == 'nt' :
423484 val = os .path .expanduser (val )
424485 val = subst_vars (val , self .config_vars )
425486 setattr (self , attr , val )
@@ -479,6 +540,16 @@ def change_roots(self, *names):
479540 attr = "install_" + name
480541 setattr (self , attr , change_root (self .root , getattr (self , attr )))
481542
543+ def create_home_path (self ):
544+ """Create directories under ~
545+ """
546+ if not self .user :
547+ return
548+ home = convert_path (os .path .expanduser ("~" ))
549+ for name , path in self .config_vars .iteritems ():
550+ if path .startswith (home ) and not os .path .isdir (path ):
551+ self .debug_print ("os.makedirs('%s', 0o700)" % path )
552+ os .makedirs (path , 0o700 )
482553
483554 # -- Command execution methods -------------------------------------
484555
0 commit comments