]> granicus.if.org Git - python/commitdiff
Merged revisions 74526 via svnmerge from
authorTarek Ziadé <ziade.tarek@gmail.com>
Thu, 20 Aug 2009 21:28:05 +0000 (21:28 +0000)
committerTarek Ziadé <ziade.tarek@gmail.com>
Thu, 20 Aug 2009 21:28:05 +0000 (21:28 +0000)
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r74526 | tarek.ziade | 2009-08-20 23:23:13 +0200 (Thu, 20 Aug 2009) | 1 line

  #6693: New functions in site.py to get user/global site packages paths.
........

Doc/library/site.rst
Lib/site.py
Lib/test/test_site.py
Misc/NEWS

index 0fe63a3a4d066b93d6c5b463af5d38f266d286d5..82184cbf3d01fb355085c9aa70bc52550c92c5b0 100644 (file)
@@ -116,6 +116,32 @@ empty, and the path manipulations are skipped; however the import of
 
    Adds a directory to sys.path and processes its pth files.
 
+.. function:: getsitepackages()
+
+   Returns a list containing all global site-packages directories
+   (and possibly site-python).
+
+   .. versionadded:: 2.7
+
+.. function:: getuserbase()
+
+   Returns the `user base` directory path.
+
+   The `user base` directory can be used to store data. If the global
+   variable ``USER_BASE`` is not initialized yet, this function will also set
+   it.
+
+   .. versionadded:: 2.7
+
+.. function:: getusersitepackages()
+
+   Returns the user-specific site-packages directory path.
+
+   If the global variable ``USER_SITE`` is not initialized yet, this
+   function will also set it.
+
+   .. versionadded:: 2.7
 
 XXX Update documentation
 XXX document python -m site --user-base --user-site
+
index 7bbd962632b9f92d5b3fb297d12115ff285b3e5d..3d455e79e238c0c45e1a43e1d88ac5405117d93e 100644 (file)
@@ -61,7 +61,10 @@ PREFIXES = [sys.prefix, sys.exec_prefix]
 # Enable per user site-packages directory
 # set it to False to disable the feature or True to force the feature
 ENABLE_USER_SITE = None
+
 # for distutils.commands.install
+# These values are initialized by the getuserbase() and getusersitepackages()
+# functions, through the main() function when Python starts.
 USER_SITE = None
 USER_BASE = None
 
@@ -205,49 +208,75 @@ def check_enableusersite():
 
     return True
 
+def getuserbase():
+    """Returns the `user base` directory path.
 
-def addusersitepackages(known_paths):
-    """Add a per user site-package to sys.path
-
-    Each user has its own python directory with site-packages in the
-    home directory.
-
-    USER_BASE is the root directory for all Python versions
-
-    USER_SITE is the user specific site-packages directory
-
-    USER_SITE/.. can be used for data.
+    The `user base` directory can be used to store data. If the global
+    variable ``USER_BASE`` is not initialized yet, this function will also set
+    it.
     """
-    global USER_BASE, USER_SITE, ENABLE_USER_SITE
+    global USER_BASE
+    if USER_BASE is not None:
+        return USER_BASE
+
     env_base = os.environ.get("PYTHONUSERBASE", None)
 
     def joinuser(*args):
         return os.path.expanduser(os.path.join(*args))
 
-    #if sys.platform in ('os2emx', 'riscos'):
-    #    # Don't know what to put here
-    #    USER_BASE = ''
-    #    USER_SITE = ''
+    # what about 'os2emx', 'riscos' ?
     if os.name == "nt":
         base = os.environ.get("APPDATA") or "~"
         USER_BASE = env_base if env_base else joinuser(base, "Python")
-        USER_SITE = os.path.join(USER_BASE,
-                                 "Python" + sys.version[0] + sys.version[2],
-                                 "site-packages")
     else:
         USER_BASE = env_base if env_base else joinuser("~", ".local")
-        USER_SITE = os.path.join(USER_BASE, "lib",
-                                 "python" + sys.version[:3],
+
+    return USER_BASE
+
+def getusersitepackages():
+    """Returns the user-specific site-packages directory path.
+
+    If the global variable ``USER_SITE`` is not initialized yet, this
+    function will also set it.
+    """
+    global USER_SITE
+    user_base = getuserbase() # this will also set USER_BASE
+
+    if USER_SITE is not None:
+        return USER_SITE
+
+    if os.name == "nt":
+        USER_SITE = os.path.join(user_base, "Python" + sys.version[0] +
+                                 sys.version[2], "site-packages")
+    else:
+        USER_SITE = os.path.join(user_base, "lib", "python" + sys.version[:3],
                                  "site-packages")
 
-    if ENABLE_USER_SITE and os.path.isdir(USER_SITE):
-        addsitedir(USER_SITE, known_paths)
+    return USER_SITE
+
+def addusersitepackages(known_paths):
+    """Add a per user site-package to sys.path
+
+    Each user has its own python directory with site-packages in the
+    home directory.
+    """
+    # get the per user site-package path
+    # this call will also make sure USER_BASE and USER_SITE are set
+    user_site = getusersitepackages()
+
+    if ENABLE_USER_SITE and os.path.isdir(user_site):
+        addsitedir(user_site, known_paths)
     return known_paths
 
+def getsitepackages():
+    """Returns a list containing all global site-packages directories
+    (and possibly site-python).
 
-def addsitepackages(known_paths):
-    """Add site-packages (and possibly site-python) to sys.path"""
-    sitedirs = []
+    For each directory present in the global ``PREFIXES``, this function
+    will find its `site-packages` subdirectory depending on the system
+    environment, and will return a list of full paths.
+    """
+    sitepackages = []
     seen = []
 
     for prefix in PREFIXES:
@@ -256,35 +285,36 @@ def addsitepackages(known_paths):
         seen.append(prefix)
 
         if sys.platform in ('os2emx', 'riscos'):
-            sitedirs.append(os.path.join(prefix, "Lib", "site-packages"))
+            sitepackages.append(os.path.join(prefix, "Lib", "site-packages"))
         elif os.sep == '/':
-            sitedirs.append(os.path.join(prefix, "lib",
+            sitepackages.append(os.path.join(prefix, "lib",
                                         "python" + sys.version[:3],
                                         "site-packages"))
-            sitedirs.append(os.path.join(prefix, "lib", "site-python"))
+            sitepackages.append(os.path.join(prefix, "lib", "site-python"))
         else:
-            sitedirs.append(prefix)
-            sitedirs.append(os.path.join(prefix, "lib", "site-packages"))
-
+            sitepackages.append(prefix)
+            sitepackages.append(os.path.join(prefix, "lib", "site-packages"))
         if sys.platform == "darwin":
             # for framework builds *only* we add the standard Apple
             # locations.
             if 'Python.framework' in prefix:
-                sitedirs.append(
+                sitepackages.append(
                     os.path.expanduser(
                         os.path.join("~", "Library", "Python",
                                      sys.version[:3], "site-packages")))
-                sitedirs.append(
+                sitepackages.append(
                         os.path.join("/Library", "Python",
                             sys.version[:3], "site-packages"))
+    return sitepackages
 
-    for sitedir in sitedirs:
+def addsitepackages(known_paths):
+    """Add site-packages (and possibly site-python) to sys.path"""
+    for sitedir in getsitepackages():
         if os.path.isdir(sitedir):
             addsitedir(sitedir, known_paths)
 
     return known_paths
 
-
 def setBEGINLIBPATH():
     """The OS/2 EMX port has optional extension modules that do double duty
     as DLLs (and must use the .DLL file extension) for other extensions.
index 7ed0ee24d489f199a1c2766ebfca60d062dd80e8..20444b76247cc6a8cf280cd37d7d5df14a8abd8b 100644 (file)
@@ -35,10 +35,16 @@ class HelperFunctionsTests(unittest.TestCase):
     def setUp(self):
         """Save a copy of sys.path"""
         self.sys_path = sys.path[:]
+        self.old_base = site.USER_BASE
+        self.old_site = site.USER_SITE
+        self.old_prefixes = site.PREFIXES
 
     def tearDown(self):
         """Restore sys.path"""
         sys.path = self.sys_path
+        site.USER_BASE = self.old_base
+        site.USER_SITE = self.old_site
+        site.PREFIXES = self.old_prefixes
 
     def test_makepath(self):
         # Test makepath() have an absolute path for its first return value
@@ -122,6 +128,60 @@ class HelperFunctionsTests(unittest.TestCase):
             env=env)
         self.assertEqual(rc, 1)
 
+    def test_getuserbase(self):
+        site.USER_BASE = None
+        user_base = site.getuserbase()
+
+        # the call sets site.USER_BASE
+        self.assertEquals(site.USER_BASE, user_base)
+
+        # let's set PYTHONUSERBASE and see if it uses it
+        site.USER_BASE = None
+        with EnvironmentVarGuard() as environ:
+            environ['PYTHONUSERBASE'] = 'xoxo'
+            self.assertTrue(site.getuserbase().startswith('xoxo'))
+
+    def test_getusersitepackages(self):
+        site.USER_SITE = None
+        site.USER_BASE = None
+        user_site = site.getusersitepackages()
+
+        # the call sets USER_BASE *and* USER_SITE
+        self.assertEquals(site.USER_SITE, user_site)
+        self.assertTrue(user_site.startswith(site.USER_BASE))
+
+    def test_getsitepackages(self):
+        site.PREFIXES = ['xoxo']
+        dirs = site.getsitepackages()
+
+        if sys.platform in ('os2emx', 'riscos'):
+            self.assertTrue(len(dirs), 1)
+            wanted = os.path.join('xoxo', 'Lib', 'site-packages')
+            self.assertEquals(dirs[0], wanted)
+        elif os.sep == '/':
+            self.assertTrue(len(dirs), 2)
+            wanted = os.path.join('xoxo', 'lib', 'python' + sys.version[:3],
+                                  'site-packages')
+            self.assertEquals(dirs[0], wanted)
+            wanted = os.path.join('xoxo', 'lib', 'site-python')
+            self.assertEquals(dirs[1], wanted)
+        else:
+            self.assertTrue(len(dirs), 2)
+            self.assertEquals(dirs[0], 'xoxo')
+            wanted = os.path.join('xoxo', 'Lib', 'site-packages')
+            self.assertEquals(dirs[1], wanted)
+
+        # let's try the specific Apple location
+        if sys.platform == "darwin":
+            site.PREFIXES = ['Python.framework']
+            dirs = site.getsitepackages()
+            self.assertTrue(len(dirs), 4)
+            wanted = os.path.join('~', 'Library', 'Python',
+                                  sys.version[:3], 'site-packages')
+            self.assertEquals(dirs[2], os.path.expanduser(wanted))
+            wanted = os.path.join('/Library', 'Python', sys.version[:3],
+                                  'site-packages')
+            self.assertEquals(dirs[3], wanted)
 
 class PthFile(object):
     """Helper class for handling testing of .pth files"""
index 9b38d34e7d5adba6e50541849b403532a53e0775..c9717417341ac7883297f990b17ad881d48ffdfc 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -992,6 +992,8 @@ Core and Builtins
 Library
 -------
 
+- Issue #6693: New functions in site.py to get user/global site packages paths.
+
 - Issue #6511: ZipFile now raises BadZipfile (instead of an IOError) when
   opening an empty or very small file.