test_site.py 23.7 KB
Newer Older
1 2 3 4 5 6 7
"""Tests for 'site'.

Tests assume the initial paths in sys.path once the interpreter has begun
executing have not been removed.

"""
import unittest
8
import test.support
9 10
from test.support import (captured_stderr, TESTFN, EnvironmentVarGuard,
                          change_cwd)
11
import builtins
12 13
import os
import sys
14
import re
15
import encodings
16 17
import urllib.request
import urllib.error
18
import shutil
19
import subprocess
20
import sysconfig
21
import tempfile
22 23
from copy import copy

24 25 26 27 28 29 30
# These tests are not particularly useful if Python was invoked with -S.
# If you add tests that are useful under -S, this skip should be moved
# to the class level.
if sys.flags.no_site:
    raise unittest.SkipTest("Python was invoked with -S")

import site
31

32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52

OLD_SYS_PATH = None


def setUpModule():
    global OLD_SYS_PATH
    OLD_SYS_PATH = sys.path[:]

    if site.ENABLE_USER_SITE and not os.path.isdir(site.USER_SITE):
        # need to add user site directory for tests
        try:
            os.makedirs(site.USER_SITE)
            # modify sys.path: will be restored by tearDownModule()
            site.addsitedir(site.USER_SITE)
        except PermissionError as exc:
            raise unittest.SkipTest('unable to create user site directory (%r): %s'
                                    % (site.USER_SITE, exc))


def tearDownModule():
    sys.path[:] = OLD_SYS_PATH
53

54

55 56 57 58 59 60 61
class HelperFunctionsTests(unittest.TestCase):
    """Tests for helper functions.
    """

    def setUp(self):
        """Save a copy of sys.path"""
        self.sys_path = sys.path[:]
62 63 64
        self.old_base = site.USER_BASE
        self.old_site = site.USER_SITE
        self.old_prefixes = site.PREFIXES
65
        self.original_vars = sysconfig._CONFIG_VARS
66
        self.old_vars = copy(sysconfig._CONFIG_VARS)
67

68
    def tearDown(self):
69
        """Restore sys.path"""
70
        sys.path[:] = self.sys_path
71 72 73
        site.USER_BASE = self.old_base
        site.USER_SITE = self.old_site
        site.PREFIXES = self.old_prefixes
74 75 76
        sysconfig._CONFIG_VARS = self.original_vars
        sysconfig._CONFIG_VARS.clear()
        sysconfig._CONFIG_VARS.update(self.old_vars)
77

78 79 80 81 82 83 84
    def test_makepath(self):
        # Test makepath() have an absolute path for its first return value
        # and a case-normalized version of the absolute path for its
        # second value.
        path_parts = ("Beginning", "End")
        original_dir = os.path.join(*path_parts)
        abs_dir, norm_dir = site.makepath(*path_parts)
85
        self.assertEqual(os.path.abspath(original_dir), abs_dir)
86
        if original_dir == os.path.normcase(original_dir):
87
            self.assertEqual(abs_dir, norm_dir)
88
        else:
89
            self.assertEqual(os.path.normcase(abs_dir), norm_dir)
90 91 92 93

    def test_init_pathinfo(self):
        dir_set = site._init_pathinfo()
        for entry in [site.makepath(path)[1] for path in sys.path
94
                        if path and os.path.exists(path)]:
95 96 97
            self.assertIn(entry, dir_set,
                          "%s from sys.path not found in set returned "
                          "by _init_pathinfo(): %s" % (entry, dir_set))
98

99 100
    def pth_file_tests(self, pth_file):
        """Contain common code for testing results of reading a .pth file"""
101 102
        self.assertIn(pth_file.imported, sys.modules,
                      "%s not in sys.modules" % pth_file.imported)
103 104
        self.assertIn(site.makepath(pth_file.good_dir_path)[0], sys.path)
        self.assertFalse(os.path.exists(pth_file.bad_dir_path))
105

106 107
    def test_addpackage(self):
        # Make sure addpackage() imports if the line starts with 'import',
108 109 110 111
        # adds directories to sys.path for any line in the file that is not a
        # comment or import that is a valid directory name for where the .pth
        # file resides; invalid directories are not added
        pth_file = PthFile()
112 113
        pth_file.cleanup(prep=True)  # to make sure that nothing is
                                      # pre-existing that shouldn't be
114
        try:
115 116
            pth_file.create()
            site.addpackage(pth_file.base_dir, pth_file.filename, set())
117
            self.pth_file_tests(pth_file)
118
        finally:
119
            pth_file.cleanup()
120

121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
    def make_pth(self, contents, pth_dir='.', pth_name=TESTFN):
        # Create a .pth file and return its (abspath, basename).
        pth_dir = os.path.abspath(pth_dir)
        pth_basename = pth_name + '.pth'
        pth_fn = os.path.join(pth_dir, pth_basename)
        pth_file = open(pth_fn, 'w', encoding='utf-8')
        self.addCleanup(lambda: os.remove(pth_fn))
        pth_file.write(contents)
        pth_file.close()
        return pth_dir, pth_basename

    def test_addpackage_import_bad_syntax(self):
        # Issue 10642
        pth_dir, pth_fn = self.make_pth("import bad)syntax\n")
        with captured_stderr() as err_out:
            site.addpackage(pth_dir, pth_fn, set())
        self.assertRegex(err_out.getvalue(), "line 1")
138 139
        self.assertRegex(err_out.getvalue(),
            re.escape(os.path.join(pth_dir, pth_fn)))
140 141 142 143 144 145 146 147 148 149 150 151 152
        # XXX: the previous two should be independent checks so that the
        # order doesn't matter.  The next three could be a single check
        # but my regex foo isn't good enough to write it.
        self.assertRegex(err_out.getvalue(), 'Traceback')
        self.assertRegex(err_out.getvalue(), r'import bad\)syntax')
        self.assertRegex(err_out.getvalue(), 'SyntaxError')

    def test_addpackage_import_bad_exec(self):
        # Issue 10642
        pth_dir, pth_fn = self.make_pth("randompath\nimport nosuchmodule\n")
        with captured_stderr() as err_out:
            site.addpackage(pth_dir, pth_fn, set())
        self.assertRegex(err_out.getvalue(), "line 2")
153 154
        self.assertRegex(err_out.getvalue(),
            re.escape(os.path.join(pth_dir, pth_fn)))
155 156
        # XXX: ditto previous XXX comment.
        self.assertRegex(err_out.getvalue(), 'Traceback')
157
        self.assertRegex(err_out.getvalue(), 'ModuleNotFoundError')
158 159 160 161 162

    def test_addpackage_import_bad_pth_file(self):
        # Issue 5258
        pth_dir, pth_fn = self.make_pth("abc\x00def\n")
        with captured_stderr() as err_out:
163 164 165 166 167
            self.assertFalse(site.addpackage(pth_dir, pth_fn, set()))
        self.assertEqual(err_out.getvalue(), "")
        for path in sys.path:
            if isinstance(path, str):
                self.assertNotIn("abc\x00def", path)
168

169
    def test_addsitedir(self):
170 171 172
        # Same tests for test_addpackage since addsitedir() essentially just
        # calls addpackage() for every .pth file in the directory
        pth_file = PthFile()
173 174
        pth_file.cleanup(prep=True) # Make sure that nothing is pre-existing
                                    # that is tested for
175
        try:
176
            pth_file.create()
177
            site.addsitedir(pth_file.base_dir, set())
178
            self.pth_file_tests(pth_file)
179
        finally:
180 181
            pth_file.cleanup()

182 183 184 185
    def test_getuserbase(self):
        self.assertEqual(site._getuserbase(), sysconfig._getuserbase())

    def test_get_path(self):
186 187 188 189
        if sys.platform == 'darwin' and sys._framework:
            scheme = 'osx_framework_user'
        else:
            scheme = os.name + '_user'
190
        self.assertEqual(site._get_path(site._getuserbase()),
191
                         sysconfig.get_path('purelib', scheme))
192

193 194
    @unittest.skipUnless(site.ENABLE_USER_SITE, "requires access to PEP 370 "
                          "user-site (site.ENABLE_USER_SITE)")
195
    def test_s_option(self):
196
        # (ncoghlan) Change this to use script_helper...
197
        usersite = site.USER_SITE
198
        self.assertIn(usersite, sys.path)
199

200
        env = os.environ.copy()
201
        rc = subprocess.call([sys.executable, '-c',
202 203
            'import sys; sys.exit(%r in sys.path)' % usersite],
            env=env)
204 205
        self.assertEqual(rc, 1)

206
        env = os.environ.copy()
207
        rc = subprocess.call([sys.executable, '-s', '-c',
208 209
            'import sys; sys.exit(%r in sys.path)' % usersite],
            env=env)
210 211 212
        if usersite == site.getsitepackages()[0]:
            self.assertEqual(rc, 1)
        else:
213
            self.assertEqual(rc, 0, "User site still added to path with -s")
214 215 216 217

        env = os.environ.copy()
        env["PYTHONNOUSERSITE"] = "1"
        rc = subprocess.call([sys.executable, '-c',
Benjamin Peterson's avatar
Benjamin Peterson committed
218
            'import sys; sys.exit(%r in sys.path)' % usersite],
219
            env=env)
220 221 222
        if usersite == site.getsitepackages()[0]:
            self.assertEqual(rc, 1)
        else:
223 224
            self.assertEqual(rc, 0,
                        "User site still added to path with PYTHONNOUSERSITE")
225 226 227 228 229 230

        env = os.environ.copy()
        env["PYTHONUSERBASE"] = "/tmp"
        rc = subprocess.call([sys.executable, '-c',
            'import sys, site; sys.exit(site.USER_BASE.startswith("/tmp"))'],
            env=env)
231 232
        self.assertEqual(rc, 1,
                        "User base not set by PYTHONUSERBASE")
233

234 235 236 237 238
    def test_getuserbase(self):
        site.USER_BASE = None
        user_base = site.getuserbase()

        # the call sets site.USER_BASE
239
        self.assertEqual(site.USER_BASE, user_base)
240 241 242

        # let's set PYTHONUSERBASE and see if it uses it
        site.USER_BASE = None
243 244 245
        import sysconfig
        sysconfig._CONFIG_VARS = None

246 247
        with EnvironmentVarGuard() as environ:
            environ['PYTHONUSERBASE'] = 'xoxo'
248 249
            self.assertTrue(site.getuserbase().startswith('xoxo'),
                            site.getuserbase())
250 251 252 253 254 255 256

    def test_getusersitepackages(self):
        site.USER_SITE = None
        site.USER_BASE = None
        user_site = site.getusersitepackages()

        # the call sets USER_BASE *and* USER_SITE
257
        self.assertEqual(site.USER_SITE, user_site)
258
        self.assertTrue(user_site.startswith(site.USER_BASE), user_site)
259 260 261 262

    def test_getsitepackages(self):
        site.PREFIXES = ['xoxo']
        dirs = site.getsitepackages()
263 264
        if os.sep == '/':
            # OS X, Linux, FreeBSD, etc
265
            self.assertEqual(len(dirs), 1)
266 267
            wanted = os.path.join('xoxo', 'lib',
                                  'python%d.%d' % sys.version_info[:2],
268
                                  'site-packages')
269
            self.assertEqual(dirs[0], wanted)
270
        else:
271
            # other platforms
272
            self.assertEqual(len(dirs), 2)
273
            self.assertEqual(dirs[0], 'xoxo')
274
            wanted = os.path.join('xoxo', 'lib', 'site-packages')
275
            self.assertEqual(dirs[1], wanted)
276

277 278 279 280 281 282 283 284 285
class PthFile(object):
    """Helper class for handling testing of .pth files"""

    def __init__(self, filename_base=TESTFN, imported="time",
                    good_dirname="__testdir__", bad_dirname="__bad"):
        """Initialize instance variables"""
        self.filename = filename_base + ".pth"
        self.base_dir = os.path.abspath('')
        self.file_path = os.path.join(self.base_dir, self.filename)
286
        self.imported = imported
287 288 289 290 291 292 293 294 295
        self.good_dirname = good_dirname
        self.bad_dirname = bad_dirname
        self.good_dir_path = os.path.join(self.base_dir, self.good_dirname)
        self.bad_dir_path = os.path.join(self.base_dir, self.bad_dirname)

    def create(self):
        """Create a .pth file with a comment, blank lines, an ``import
        <self.imported>``, a line with self.good_dirname, and a line with
        self.bad_dirname.
296

297 298 299 300
        Creation of the directory for self.good_dir_path (based off of
        self.good_dirname) is also performed.

        Make sure to call self.cleanup() to undo anything done by this method.
301

302
        """
303
        FILE = open(self.file_path, 'w')
304
        try:
305 306 307 308 309
            print("#import @bad module name", file=FILE)
            print("\n", file=FILE)
            print("import %s" % self.imported, file=FILE)
            print(self.good_dirname, file=FILE)
            print(self.bad_dirname, file=FILE)
310 311 312
        finally:
            FILE.close()
        os.mkdir(self.good_dir_path)
313

314
    def cleanup(self, prep=False):
315 316 317
        """Make sure that the .pth file is deleted, self.imported is not in
        sys.modules, and that both self.good_dirname and self.bad_dirname are
        not existing directories."""
318
        if os.path.exists(self.file_path):
319
            os.remove(self.file_path)
320 321 322 323 324 325 326 327
        if prep:
            self.imported_module = sys.modules.get(self.imported)
            if self.imported_module:
                del sys.modules[self.imported]
        else:
            if self.imported_module:
                sys.modules[self.imported] = self.imported_module
        if os.path.exists(self.good_dir_path):
328
            os.rmdir(self.good_dir_path)
329
        if os.path.exists(self.bad_dir_path):
330
            os.rmdir(self.bad_dir_path)
331 332 333 334 335 336 337 338 339 340

class ImportSideEffectTests(unittest.TestCase):
    """Test side-effects from importing 'site'."""

    def setUp(self):
        """Make a copy of sys.path"""
        self.sys_path = sys.path[:]

    def tearDown(self):
        """Restore sys.path"""
341
        sys.path[:] = self.sys_path
342

Barry Warsaw's avatar
Barry Warsaw committed
343 344 345 346 347 348 349
    def test_abs_paths(self):
        # Make sure all imported modules have their __file__ and __cached__
        # attributes as absolute paths.  Arranging to put the Lib directory on
        # PYTHONPATH would cause the os module to have a relative path for
        # __file__ if abs_paths() does not get run.  sys and builtins (the
        # only other modules imported before site.py runs) do not have
        # __file__ or __cached__ because they are built-in.
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390
        try:
            parent = os.path.relpath(os.path.dirname(os.__file__))
            cwd = os.getcwd()
        except ValueError:
            # Failure to get relpath probably means we need to chdir
            # to the same drive.
            cwd, parent = os.path.split(os.path.dirname(os.__file__))
        with change_cwd(cwd):
            env = os.environ.copy()
            env['PYTHONPATH'] = parent
            code = ('import os, sys',
                # use ASCII to avoid locale issues with non-ASCII directories
                'os_file = os.__file__.encode("ascii", "backslashreplace")',
                r'sys.stdout.buffer.write(os_file + b"\n")',
                'os_cached = os.__cached__.encode("ascii", "backslashreplace")',
                r'sys.stdout.buffer.write(os_cached + b"\n")')
            command = '\n'.join(code)
            # First, prove that with -S (no 'import site'), the paths are
            # relative.
            proc = subprocess.Popen([sys.executable, '-S', '-c', command],
                                    env=env,
                                    stdout=subprocess.PIPE)
            stdout, stderr = proc.communicate()

            self.assertEqual(proc.returncode, 0)
            os__file__, os__cached__ = stdout.splitlines()[:2]
            self.assertFalse(os.path.isabs(os__file__))
            self.assertFalse(os.path.isabs(os__cached__))
            # Now, with 'import site', it works.
            proc = subprocess.Popen([sys.executable, '-c', command],
                                    env=env,
                                    stdout=subprocess.PIPE)
            stdout, stderr = proc.communicate()
            self.assertEqual(proc.returncode, 0)
            os__file__, os__cached__ = stdout.splitlines()[:2]
            self.assertTrue(os.path.isabs(os__file__),
                            "expected absolute path, got {}"
                            .format(os__file__.decode('ascii')))
            self.assertTrue(os.path.isabs(os__cached__),
                            "expected absolute path, got {}"
                            .format(os__cached__.decode('ascii')))
391

392 393 394 395 396 397 398 399 400 401 402
    def test_abs_paths_cached_None(self):
        """Test for __cached__ is None.

        Regarding to PEP 3147, __cached__ can be None.

        See also: https://bugs.python.org/issue30167
        """
        sys.modules['test'].__cached__ = None
        site.abs_paths()
        self.assertIsNone(sys.modules['test'].__cached__)

403 404 405 406 407 408
    def test_no_duplicate_paths(self):
        # No duplicate paths should exist in sys.path
        # Handled by removeduppaths()
        site.removeduppaths()
        seen_paths = set()
        for path in sys.path:
409
            self.assertNotIn(path, seen_paths)
410 411
            seen_paths.add(path)

412
    @unittest.skip('test not implemented')
413 414 415 416 417 418 419
    def test_add_build_dir(self):
        # Test that the build directory's Modules directory is used when it
        # should be.
        # XXX: implement
        pass

    def test_setting_quit(self):
420
        # 'quit' and 'exit' should be injected into builtins
421 422
        self.assertTrue(hasattr(builtins, "quit"))
        self.assertTrue(hasattr(builtins, "exit"))
423 424

    def test_setting_copyright(self):
425
        # 'copyright', 'credits', and 'license' should be in builtins
426 427
        self.assertTrue(hasattr(builtins, "copyright"))
        self.assertTrue(hasattr(builtins, "credits"))
428
        self.assertTrue(hasattr(builtins, "license"))
429 430

    def test_setting_help(self):
431
        # 'help' should be set in builtins
432
        self.assertTrue(hasattr(builtins, "help"))
433 434 435 436 437

    def test_aliasing_mbcs(self):
        if sys.platform == "win32":
            import locale
            if locale.getdefaultlocale()[1].startswith('cp'):
438
                for value in encodings.aliases.aliases.values():
439 440 441 442 443 444 445
                    if value == "mbcs":
                        break
                else:
                    self.fail("did not alias mbcs")

    def test_sitecustomize_executed(self):
        # If sitecustomize is available, it should have been imported.
446
        if "sitecustomize" not in sys.modules:
447 448 449 450 451 452 453
            try:
                import sitecustomize
            except ImportError:
                pass
            else:
                self.fail("sitecustomize not imported automatically")

454
    @test.support.requires_resource('network')
455
    @test.support.system_must_validate_cert
456 457
    @unittest.skipUnless(sys.version_info[3] == 'final',
                         'only for released versions')
458 459
    @unittest.skipUnless(hasattr(urllib.request, "HTTPSHandler"),
                         'need SSL support to download license')
460
    def test_license_exists_at_url(self):
461
        # This test is a bit fragile since it depends on the format of the
462 463 464 465
        # string displayed by license in the absence of a LICENSE file.
        url = license._Printer__data.split()[1]
        req = urllib.request.Request(url, method='HEAD')
        try:
466
            with test.support.transient_internet(url):
467 468 469 470 471
                with urllib.request.urlopen(req) as data:
                    code = data.getcode()
        except urllib.error.HTTPError as e:
            code = e.code
        self.assertEqual(code, 200, msg="Can't find " + url)
472

473

474 475 476 477 478
class StartupImportTests(unittest.TestCase):

    def test_startup_imports(self):
        # This tests checks which modules are loaded by Python when it
        # initially starts upon startup.
479 480 481
        popen = subprocess.Popen([sys.executable, '-I', '-v', '-c',
                                  'import sys; print(set(sys.modules))'],
                                 stdout=subprocess.PIPE,
482 483
                                 stderr=subprocess.PIPE,
                                 encoding='utf-8')
484 485 486
        stdout, stderr = popen.communicate()
        modules = eval(stdout)

487 488
        self.assertIn('site', modules)

489
        # http://bugs.python.org/issue19205
490
        re_mods = {'re', '_sre', 'sre_compile', 'sre_constants', 'sre_parse'}
491 492 493
        # _osx_support uses the re module in many placs
        if sys.platform != 'darwin':
            self.assertFalse(modules.intersection(re_mods), stderr)
494
        # http://bugs.python.org/issue9548
495
        self.assertNotIn('locale', modules, stderr)
496 497 498
        if sys.platform != 'darwin':
            # http://bugs.python.org/issue19209
            self.assertNotIn('copyreg', modules, stderr)
499 500 501
        # http://bugs.python.org/issue19218>
        collection_mods = {'_collections', 'collections', 'functools',
                           'heapq', 'itertools', 'keyword', 'operator',
502 503
                           'reprlib', 'types', 'weakref'
                          }.difference(sys.builtin_module_names)
504
        self.assertFalse(modules.intersection(collection_mods), stderr)
505

506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522
    def test_startup_interactivehook(self):
        r = subprocess.Popen([sys.executable, '-c',
            'import sys; sys.exit(hasattr(sys, "__interactivehook__"))']).wait()
        self.assertTrue(r, "'__interactivehook__' not added by site")

    def test_startup_interactivehook_isolated(self):
        # issue28192 readline is not automatically enabled in isolated mode
        r = subprocess.Popen([sys.executable, '-I', '-c',
            'import sys; sys.exit(hasattr(sys, "__interactivehook__"))']).wait()
        self.assertFalse(r, "'__interactivehook__' added in isolated mode")

    def test_startup_interactivehook_isolated_explicit(self):
        # issue28192 readline can be explicitly enabled in isolated mode
        r = subprocess.Popen([sys.executable, '-I', '-c',
            'import site, sys; site.enablerlcompleter(); sys.exit(hasattr(sys, "__interactivehook__"))']).wait()
        self.assertTrue(r, "'__interactivehook__' not added by enablerlcompleter()")

523 524 525 526

@unittest.skipUnless(sys.platform == 'win32', "only supported on Windows")
class _pthFileTests(unittest.TestCase):

527
    def _create_underpth_exe(self, lines):
528 529 530
        temp_dir = tempfile.mkdtemp()
        self.addCleanup(test.support.rmtree, temp_dir)
        exe_file = os.path.join(temp_dir, os.path.split(sys.executable)[1])
531 532
        shutil.copy(sys.executable, exe_file)
        _pth_file = os.path.splitext(exe_file)[0] + '._pth'
533 534 535 536
        with open(_pth_file, 'w') as f:
            for line in lines:
                print(line, file=f)
        return exe_file
537

538 539 540 541 542 543 544 545 546
    def _calc_sys_path_for_underpth_nosite(self, sys_prefix, lines):
        sys_path = []
        for line in lines:
            if not line or line[0] == '#':
                continue
            abs_path = os.path.abspath(os.path.join(sys_prefix, line))
            sys_path.append(abs_path)
        return sys_path

547 548 549
    def test_underpth_nosite_file(self):
        libpath = os.path.dirname(os.path.dirname(encodings.__file__))
        exe_prefix = os.path.dirname(sys.executable)
550
        pth_lines = [
551 552
            'fake-path-name',
            *[libpath for _ in range(200)],
553
            '',
554
            '# comment',
555 556 557 558 559
        ]
        exe_file = self._create_underpth_exe(pth_lines)
        sys_path = self._calc_sys_path_for_underpth_nosite(
            os.path.dirname(exe_file),
            pth_lines)
560

561 562 563
        env = os.environ.copy()
        env['PYTHONPATH'] = 'from-env'
        env['PATH'] = '{};{}'.format(exe_prefix, os.getenv('PATH'))
564 565 566 567
        output = subprocess.check_output([exe_file, '-c',
            'import sys; print("\\n".join(sys.path) if sys.flags.no_site else "")'
        ], env=env, encoding='ansi')
        actual_sys_path = output.rstrip().split('\n')
568
        self.assertTrue(actual_sys_path, "sys.flags.no_site was False")
569 570 571 572 573
        self.assertEqual(
            actual_sys_path,
            sys_path,
            "sys.path is incorrect"
        )
574 575

    def test_underpth_file(self):
576 577 578 579 580
        libpath = os.path.dirname(os.path.dirname(encodings.__file__))
        exe_prefix = os.path.dirname(sys.executable)
        exe_file = self._create_underpth_exe([
            'fake-path-name',
            *[libpath for _ in range(200)],
581
            '',
582 583 584
            '# comment',
            'import site'
        ])
585
        sys_prefix = os.path.dirname(exe_file)
586 587 588 589 590 591 592 593 594 595 596
        env = os.environ.copy()
        env['PYTHONPATH'] = 'from-env'
        env['PATH'] = '{};{}'.format(exe_prefix, os.getenv('PATH'))
        rc = subprocess.call([exe_file, '-c',
            'import sys; sys.exit(not sys.flags.no_site and '
            '%r in sys.path and %r in sys.path and %r not in sys.path and '
            'all("\\r" not in p and "\\n" not in p for p in sys.path))' % (
                os.path.join(sys_prefix, 'fake-path-name'),
                libpath,
                os.path.join(sys_prefix, 'from-env'),
            )], env=env)
597
        self.assertTrue(rc, "sys.path is incorrect")
598

599

600
if __name__ == "__main__":
601
    unittest.main()