10c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi"""Tests for 'site'.
20c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
30c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiTests assume the initial paths in sys.path once the interpreter has begun
40c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiexecuting have not been removed.
50c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
60c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi"""
70c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport unittest
80c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom test.test_support import run_unittest, TESTFN, EnvironmentVarGuard
90c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom test.test_support import captured_output
100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport __builtin__
110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport os
120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport sys
130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport re
140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport encodings
150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport subprocess
160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport sysconfig
170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom copy import copy
180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Need to make sure to not import 'site' if someone specified ``-S`` at the
200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# command-line.  Detect this by just making sure 'site' has not been imported
210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# already.
220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiif "site" in sys.modules:
230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    import site
240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yielse:
250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    raise unittest.SkipTest("importation of site.py suppressed")
260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiif site.ENABLE_USER_SITE and not os.path.isdir(site.USER_SITE):
280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # need to add user site directory for tests
290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    os.makedirs(site.USER_SITE)
300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    site.addsitedir(site.USER_SITE)
310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass HelperFunctionsTests(unittest.TestCase):
330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Tests for helper functions.
340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    The setting of the encoding (set using sys.setdefaultencoding) used by
360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    the Unicode implementation is not tested.
370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """
390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def setUp(self):
410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Save a copy of sys.path"""
420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.sys_path = sys.path[:]
430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.old_base = site.USER_BASE
440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.old_site = site.USER_SITE
450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.old_prefixes = site.PREFIXES
460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.old_vars = copy(sysconfig._CONFIG_VARS)
470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def tearDown(self):
490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Restore sys.path"""
500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        sys.path[:] = self.sys_path
510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        site.USER_BASE = self.old_base
520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        site.USER_SITE = self.old_site
530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        site.PREFIXES = self.old_prefixes
540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        sysconfig._CONFIG_VARS = self.old_vars
550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_makepath(self):
570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Test makepath() have an absolute path for its first return value
580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # and a case-normalized version of the absolute path for its
590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # second value.
600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        path_parts = ("Beginning", "End")
610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        original_dir = os.path.join(*path_parts)
620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        abs_dir, norm_dir = site.makepath(*path_parts)
630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(os.path.abspath(original_dir), abs_dir)
640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if original_dir == os.path.normcase(original_dir):
650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(abs_dir, norm_dir)
660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(os.path.normcase(abs_dir), norm_dir)
680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_init_pathinfo(self):
700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        dir_set = site._init_pathinfo()
710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for entry in [site.makepath(path)[1] for path in sys.path
720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        if path and os.path.isdir(path)]:
730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertIn(entry, dir_set,
740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                          "%s from sys.path not found in set returned "
750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                          "by _init_pathinfo(): %s" % (entry, dir_set))
760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def pth_file_tests(self, pth_file):
780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Contain common code for testing results of reading a .pth file"""
790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn(pth_file.imported, sys.modules,
800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      "%s not in sys.modules" % pth_file.imported)
810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn(site.makepath(pth_file.good_dir_path)[0], sys.path)
820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertFalse(os.path.exists(pth_file.bad_dir_path))
830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_addpackage(self):
850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Make sure addpackage() imports if the line starts with 'import',
860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # adds directories to sys.path for any line in the file that is not a
870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # comment or import that is a valid directory name for where the .pth
880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # file resides; invalid directories are not added
890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pth_file = PthFile()
900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pth_file.cleanup(prep=True)  # to make sure that nothing is
910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                      # pre-existing that shouldn't be
920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        try:
930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            pth_file.create()
940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            site.addpackage(pth_file.base_dir, pth_file.filename, set())
950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.pth_file_tests(pth_file)
960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        finally:
970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            pth_file.cleanup()
980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def make_pth(self, contents, pth_dir='.', pth_name=TESTFN):
1000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Create a .pth file and return its (abspath, basename).
1010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pth_dir = os.path.abspath(pth_dir)
1020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pth_basename = pth_name + '.pth'
1030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pth_fn = os.path.join(pth_dir, pth_basename)
1040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pth_file = open(pth_fn, 'w')
1050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.addCleanup(lambda: os.remove(pth_fn))
1060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pth_file.write(contents)
1070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pth_file.close()
1080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return pth_dir, pth_basename
1090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_addpackage_import_bad_syntax(self):
1110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Issue 10642
1120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pth_dir, pth_fn = self.make_pth("import bad)syntax\n")
1130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with captured_output("stderr") as err_out:
1140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            site.addpackage(pth_dir, pth_fn, set())
1150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRegexpMatches(err_out.getvalue(), "line 1")
1160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRegexpMatches(err_out.getvalue(),
1170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            re.escape(os.path.join(pth_dir, pth_fn)))
1180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # XXX: the previous two should be independent checks so that the
1190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # order doesn't matter.  The next three could be a single check
1200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # but my regex foo isn't good enough to write it.
1210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRegexpMatches(err_out.getvalue(), 'Traceback')
1220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRegexpMatches(err_out.getvalue(), r'import bad\)syntax')
1230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRegexpMatches(err_out.getvalue(), 'SyntaxError')
1240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_addpackage_import_bad_exec(self):
1260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Issue 10642
1270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pth_dir, pth_fn = self.make_pth("randompath\nimport nosuchmodule\n")
1280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with captured_output("stderr") as err_out:
1290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            site.addpackage(pth_dir, pth_fn, set())
1300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRegexpMatches(err_out.getvalue(), "line 2")
1310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRegexpMatches(err_out.getvalue(),
1320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            re.escape(os.path.join(pth_dir, pth_fn)))
1330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # XXX: ditto previous XXX comment.
1340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRegexpMatches(err_out.getvalue(), 'Traceback')
1350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRegexpMatches(err_out.getvalue(), 'ImportError')
1360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    @unittest.skipIf(sys.platform == "win32", "Windows does not raise an "
1380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      "error for file paths containing null characters")
1390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_addpackage_import_bad_pth_file(self):
1400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Issue 5258
1410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pth_dir, pth_fn = self.make_pth("abc\x00def\n")
1420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with captured_output("stderr") as err_out:
1430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            site.addpackage(pth_dir, pth_fn, set())
1440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRegexpMatches(err_out.getvalue(), "line 1")
1450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRegexpMatches(err_out.getvalue(),
1460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            re.escape(os.path.join(pth_dir, pth_fn)))
1470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # XXX: ditto previous XXX comment.
1480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRegexpMatches(err_out.getvalue(), 'Traceback')
1490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertRegexpMatches(err_out.getvalue(), 'TypeError')
1500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_addsitedir(self):
1520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Same tests for test_addpackage since addsitedir() essentially just
1530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # calls addpackage() for every .pth file in the directory
1540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pth_file = PthFile()
1550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pth_file.cleanup(prep=True) # Make sure that nothing is pre-existing
1560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                    # that is tested for
1570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        try:
1580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            pth_file.create()
1590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            site.addsitedir(pth_file.base_dir, set())
1600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.pth_file_tests(pth_file)
1610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        finally:
1620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            pth_file.cleanup()
1630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    @unittest.skipUnless(site.ENABLE_USER_SITE, "requires access to PEP 370 "
1650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                          "user-site (site.ENABLE_USER_SITE)")
1660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_s_option(self):
1670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        usersite = site.USER_SITE
1680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertIn(usersite, sys.path)
1690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        env = os.environ.copy()
1710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        rc = subprocess.call([sys.executable, '-c',
1720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            'import sys; sys.exit(%r in sys.path)' % usersite],
1730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            env=env)
1740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(rc, 1, "%r is not in sys.path (sys.exit returned %r)"
1750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                % (usersite, rc))
1760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        env = os.environ.copy()
1780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        rc = subprocess.call([sys.executable, '-s', '-c',
1790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            'import sys; sys.exit(%r in sys.path)' % usersite],
1800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            env=env)
1810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(rc, 0)
1820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        env = os.environ.copy()
1840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        env["PYTHONNOUSERSITE"] = "1"
1850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        rc = subprocess.call([sys.executable, '-c',
1860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            'import sys; sys.exit(%r in sys.path)' % usersite],
1870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            env=env)
1880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(rc, 0)
1890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        env = os.environ.copy()
1910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        env["PYTHONUSERBASE"] = "/tmp"
1920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        rc = subprocess.call([sys.executable, '-c',
1930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            'import sys, site; sys.exit(site.USER_BASE.startswith("/tmp"))'],
1940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            env=env)
1950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(rc, 1)
1960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_getuserbase(self):
1980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        site.USER_BASE = None
1990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        user_base = site.getuserbase()
2000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # the call sets site.USER_BASE
2020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(site.USER_BASE, user_base)
2030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # let's set PYTHONUSERBASE and see if it uses it
2050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        site.USER_BASE = None
2060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        import sysconfig
2070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        sysconfig._CONFIG_VARS = None
2080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with EnvironmentVarGuard() as environ:
2100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            environ['PYTHONUSERBASE'] = 'xoxo'
2110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertTrue(site.getuserbase().startswith('xoxo'),
2120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                            site.getuserbase())
2130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_getusersitepackages(self):
2150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        site.USER_SITE = None
2160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        site.USER_BASE = None
2170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        user_site = site.getusersitepackages()
2180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # the call sets USER_BASE *and* USER_SITE
2200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(site.USER_SITE, user_site)
2210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(user_site.startswith(site.USER_BASE), user_site)
2220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_getsitepackages(self):
2240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        site.PREFIXES = ['xoxo']
2250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        dirs = site.getsitepackages()
2260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if sys.platform in ('os2emx', 'riscos'):
2280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(len(dirs), 1)
2290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            wanted = os.path.join('xoxo', 'Lib', 'site-packages')
2300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(dirs[0], wanted)
2310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif (sys.platform == "darwin" and
2320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            sysconfig.get_config_var("PYTHONFRAMEWORK")):
2330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            # OS X framework builds
2340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            site.PREFIXES = ['Python.framework']
2350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            dirs = site.getsitepackages()
2360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(len(dirs), 3)
2370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            wanted = os.path.join('/Library',
2380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                  sysconfig.get_config_var("PYTHONFRAMEWORK"),
2390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                  sys.version[:3],
2400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                  'site-packages')
2410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(dirs[2], wanted)
2420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif os.sep == '/':
2430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            # OS X non-framwework builds, Linux, FreeBSD, etc
2440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(len(dirs), 2)
2450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            wanted = os.path.join('xoxo', 'lib', 'python' + sys.version[:3],
2460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                  'site-packages')
2470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(dirs[0], wanted)
2480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            wanted = os.path.join('xoxo', 'lib', 'site-python')
2490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(dirs[1], wanted)
2500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
2510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            # other platforms
2520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(len(dirs), 2)
2530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(dirs[0], 'xoxo')
2540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            wanted = os.path.join('xoxo', 'lib', 'site-packages')
2550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertEqual(dirs[1], wanted)
2560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass PthFile(object):
2580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Helper class for handling testing of .pth files"""
2590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __init__(self, filename_base=TESTFN, imported="time",
2610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    good_dirname="__testdir__", bad_dirname="__bad"):
2620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Initialize instance variables"""
2630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.filename = filename_base + ".pth"
2640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.base_dir = os.path.abspath('')
2650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.file_path = os.path.join(self.base_dir, self.filename)
2660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.imported = imported
2670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.good_dirname = good_dirname
2680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.bad_dirname = bad_dirname
2690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.good_dir_path = os.path.join(self.base_dir, self.good_dirname)
2700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.bad_dir_path = os.path.join(self.base_dir, self.bad_dirname)
2710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def create(self):
2730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Create a .pth file with a comment, blank lines, an ``import
2740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        <self.imported>``, a line with self.good_dirname, and a line with
2750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.bad_dirname.
2760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Creation of the directory for self.good_dir_path (based off of
2780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.good_dirname) is also performed.
2790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Make sure to call self.cleanup() to undo anything done by this method.
2810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
2830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        FILE = open(self.file_path, 'w')
2840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        try:
2850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            print>>FILE, "#import @bad module name"
2860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            print>>FILE, "\n"
2870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            print>>FILE, "import %s" % self.imported
2880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            print>>FILE, self.good_dirname
2890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            print>>FILE, self.bad_dirname
2900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        finally:
2910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            FILE.close()
2920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        os.mkdir(self.good_dir_path)
2930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def cleanup(self, prep=False):
2950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Make sure that the .pth file is deleted, self.imported is not in
2960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        sys.modules, and that both self.good_dirname and self.bad_dirname are
2970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        not existing directories."""
2980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if os.path.exists(self.file_path):
2990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            os.remove(self.file_path)
3000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if prep:
3010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.imported_module = sys.modules.get(self.imported)
3020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if self.imported_module:
3030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                del sys.modules[self.imported]
3040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
3050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if self.imported_module:
3060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                sys.modules[self.imported] = self.imported_module
3070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if os.path.exists(self.good_dir_path):
3080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            os.rmdir(self.good_dir_path)
3090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if os.path.exists(self.bad_dir_path):
3100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            os.rmdir(self.bad_dir_path)
3110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass ImportSideEffectTests(unittest.TestCase):
3130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Test side-effects from importing 'site'."""
3140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def setUp(self):
3160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Make a copy of sys.path"""
3170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.sys_path = sys.path[:]
3180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def tearDown(self):
3200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Restore sys.path"""
3210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        sys.path[:] = self.sys_path
3220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_abs__file__(self):
3240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Make sure all imported modules have their __file__ attribute
3250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # as an absolute path.
3260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Handled by abs__file__()
3270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        site.abs__file__()
3280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for module in (sys, os, __builtin__):
3290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            try:
3300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.assertTrue(os.path.isabs(module.__file__), repr(module))
3310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            except AttributeError:
3320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                continue
3330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # We could try everything in sys.modules; however, when regrtest.py
3340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # runs something like test_frozen before test_site, then we will
3350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # be testing things loaded *after* test_site did path normalization
3360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_no_duplicate_paths(self):
3380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # No duplicate paths should exist in sys.path
3390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Handled by removeduppaths()
3400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        site.removeduppaths()
3410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        seen_paths = set()
3420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for path in sys.path:
3430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertNotIn(path, seen_paths)
3440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            seen_paths.add(path)
3450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_add_build_dir(self):
3470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Test that the build directory's Modules directory is used when it
3480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # should be.
3490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # XXX: implement
3500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pass
3510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_setting_quit(self):
3530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # 'quit' and 'exit' should be injected into __builtin__
3540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(hasattr(__builtin__, "quit"))
3550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(hasattr(__builtin__, "exit"))
3560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_setting_copyright(self):
3580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # 'copyright' and 'credits' should be in __builtin__
3590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(hasattr(__builtin__, "copyright"))
3600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(hasattr(__builtin__, "credits"))
3610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_setting_help(self):
3630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # 'help' should be set in __builtin__
3640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(hasattr(__builtin__, "help"))
3650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_aliasing_mbcs(self):
3670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if sys.platform == "win32":
3680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            import locale
3690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if locale.getdefaultlocale()[1].startswith('cp'):
3700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                for value in encodings.aliases.aliases.itervalues():
3710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    if value == "mbcs":
3720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        break
3730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                else:
3740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    self.fail("did not alias mbcs")
3750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_setdefaultencoding_removed(self):
3770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Make sure sys.setdefaultencoding is gone
3780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(not hasattr(sys, "setdefaultencoding"))
3790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_sitecustomize_executed(self):
3810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # If sitecustomize is available, it should have been imported.
3820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if "sitecustomize" not in sys.modules:
3830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            try:
3840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                import sitecustomize
3850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            except ImportError:
3860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                pass
3870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            else:
3880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.fail("sitecustomize not imported automatically")
3890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef test_main():
3910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    run_unittest(HelperFunctionsTests, ImportSideEffectTests)
3920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiif __name__ == "__main__":
3940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    test_main()
395