1"""Tests for 'site'. 2 3Tests assume the initial paths in sys.path once the interpreter has begun 4executing have not been removed. 5 6""" 7import unittest 8import test.support 9from test import support 10from test.support import os_helper 11from test.support import socket_helper 12from test.support import captured_stderr 13from test.support.os_helper import TESTFN, EnvironmentVarGuard, change_cwd 14import ast 15import builtins 16import encodings 17import glob 18import io 19import os 20import re 21import shutil 22import subprocess 23import sys 24import sysconfig 25import tempfile 26import urllib.error 27import urllib.request 28from unittest import mock 29from copy import copy 30 31# These tests are not particularly useful if Python was invoked with -S. 32# If you add tests that are useful under -S, this skip should be moved 33# to the class level. 34if sys.flags.no_site: 35 raise unittest.SkipTest("Python was invoked with -S") 36 37import site 38 39 40HAS_USER_SITE = (site.USER_SITE is not None) 41OLD_SYS_PATH = None 42 43 44def setUpModule(): 45 global OLD_SYS_PATH 46 OLD_SYS_PATH = sys.path[:] 47 48 if site.ENABLE_USER_SITE and not os.path.isdir(site.USER_SITE): 49 # need to add user site directory for tests 50 try: 51 os.makedirs(site.USER_SITE) 52 # modify sys.path: will be restored by tearDownModule() 53 site.addsitedir(site.USER_SITE) 54 except PermissionError as exc: 55 raise unittest.SkipTest('unable to create user site directory (%r): %s' 56 % (site.USER_SITE, exc)) 57 58 59def tearDownModule(): 60 sys.path[:] = OLD_SYS_PATH 61 62 63class HelperFunctionsTests(unittest.TestCase): 64 """Tests for helper functions. 65 """ 66 67 def setUp(self): 68 """Save a copy of sys.path""" 69 self.sys_path = sys.path[:] 70 self.old_base = site.USER_BASE 71 self.old_site = site.USER_SITE 72 self.old_prefixes = site.PREFIXES 73 self.original_vars = sysconfig._CONFIG_VARS 74 self.old_vars = copy(sysconfig._CONFIG_VARS) 75 76 def tearDown(self): 77 """Restore sys.path""" 78 sys.path[:] = self.sys_path 79 site.USER_BASE = self.old_base 80 site.USER_SITE = self.old_site 81 site.PREFIXES = self.old_prefixes 82 sysconfig._CONFIG_VARS = self.original_vars 83 # _CONFIG_VARS is None before get_config_vars() is called 84 if sysconfig._CONFIG_VARS is not None: 85 sysconfig._CONFIG_VARS.clear() 86 sysconfig._CONFIG_VARS.update(self.old_vars) 87 88 def test_makepath(self): 89 # Test makepath() have an absolute path for its first return value 90 # and a case-normalized version of the absolute path for its 91 # second value. 92 path_parts = ("Beginning", "End") 93 original_dir = os.path.join(*path_parts) 94 abs_dir, norm_dir = site.makepath(*path_parts) 95 self.assertEqual(os.path.abspath(original_dir), abs_dir) 96 if original_dir == os.path.normcase(original_dir): 97 self.assertEqual(abs_dir, norm_dir) 98 else: 99 self.assertEqual(os.path.normcase(abs_dir), norm_dir) 100 101 def test_init_pathinfo(self): 102 dir_set = site._init_pathinfo() 103 for entry in [site.makepath(path)[1] for path in sys.path 104 if path and os.path.exists(path)]: 105 self.assertIn(entry, dir_set, 106 "%s from sys.path not found in set returned " 107 "by _init_pathinfo(): %s" % (entry, dir_set)) 108 109 def pth_file_tests(self, pth_file): 110 """Contain common code for testing results of reading a .pth file""" 111 self.assertIn(pth_file.imported, sys.modules, 112 "%s not in sys.modules" % pth_file.imported) 113 self.assertIn(site.makepath(pth_file.good_dir_path)[0], sys.path) 114 self.assertFalse(os.path.exists(pth_file.bad_dir_path)) 115 116 def test_addpackage(self): 117 # Make sure addpackage() imports if the line starts with 'import', 118 # adds directories to sys.path for any line in the file that is not a 119 # comment or import that is a valid directory name for where the .pth 120 # file resides; invalid directories are not added 121 pth_file = PthFile() 122 pth_file.cleanup(prep=True) # to make sure that nothing is 123 # pre-existing that shouldn't be 124 try: 125 pth_file.create() 126 site.addpackage(pth_file.base_dir, pth_file.filename, set()) 127 self.pth_file_tests(pth_file) 128 finally: 129 pth_file.cleanup() 130 131 def make_pth(self, contents, pth_dir='.', pth_name=TESTFN): 132 # Create a .pth file and return its (abspath, basename). 133 pth_dir = os.path.abspath(pth_dir) 134 pth_basename = pth_name + '.pth' 135 pth_fn = os.path.join(pth_dir, pth_basename) 136 with open(pth_fn, 'w', encoding='utf-8') as pth_file: 137 self.addCleanup(lambda: os.remove(pth_fn)) 138 pth_file.write(contents) 139 return pth_dir, pth_basename 140 141 def test_addpackage_import_bad_syntax(self): 142 # Issue 10642 143 pth_dir, pth_fn = self.make_pth("import bad-syntax\n") 144 with captured_stderr() as err_out: 145 site.addpackage(pth_dir, pth_fn, set()) 146 self.assertRegex(err_out.getvalue(), "line 1") 147 self.assertRegex(err_out.getvalue(), 148 re.escape(os.path.join(pth_dir, pth_fn))) 149 # XXX: the previous two should be independent checks so that the 150 # order doesn't matter. The next three could be a single check 151 # but my regex foo isn't good enough to write it. 152 self.assertRegex(err_out.getvalue(), 'Traceback') 153 self.assertRegex(err_out.getvalue(), r'import bad-syntax') 154 self.assertRegex(err_out.getvalue(), 'SyntaxError') 155 156 def test_addpackage_import_bad_exec(self): 157 # Issue 10642 158 pth_dir, pth_fn = self.make_pth("randompath\nimport nosuchmodule\n") 159 with captured_stderr() as err_out: 160 site.addpackage(pth_dir, pth_fn, set()) 161 self.assertRegex(err_out.getvalue(), "line 2") 162 self.assertRegex(err_out.getvalue(), 163 re.escape(os.path.join(pth_dir, pth_fn))) 164 # XXX: ditto previous XXX comment. 165 self.assertRegex(err_out.getvalue(), 'Traceback') 166 self.assertRegex(err_out.getvalue(), 'ModuleNotFoundError') 167 168 def test_addpackage_empty_lines(self): 169 # Issue 33689 170 pth_dir, pth_fn = self.make_pth("\n\n \n\n") 171 known_paths = site.addpackage(pth_dir, pth_fn, set()) 172 self.assertEqual(known_paths, set()) 173 174 def test_addpackage_import_bad_pth_file(self): 175 # Issue 5258 176 pth_dir, pth_fn = self.make_pth("abc\x00def\n") 177 with captured_stderr() as err_out: 178 self.assertFalse(site.addpackage(pth_dir, pth_fn, set())) 179 self.maxDiff = None 180 self.assertEqual(err_out.getvalue(), "") 181 for path in sys.path: 182 if isinstance(path, str): 183 self.assertNotIn("abc\x00def", path) 184 185 def test_addsitedir(self): 186 # Same tests for test_addpackage since addsitedir() essentially just 187 # calls addpackage() for every .pth file in the directory 188 pth_file = PthFile() 189 pth_file.cleanup(prep=True) # Make sure that nothing is pre-existing 190 # that is tested for 191 try: 192 pth_file.create() 193 site.addsitedir(pth_file.base_dir, set()) 194 self.pth_file_tests(pth_file) 195 finally: 196 pth_file.cleanup() 197 198 # This tests _getuserbase, hence the double underline 199 # to distinguish from a test for getuserbase 200 def test__getuserbase(self): 201 self.assertEqual(site._getuserbase(), sysconfig._getuserbase()) 202 203 @unittest.skipUnless(HAS_USER_SITE, 'need user site') 204 def test_get_path(self): 205 if sys.platform == 'darwin' and sys._framework: 206 scheme = 'osx_framework_user' 207 else: 208 scheme = os.name + '_user' 209 self.assertEqual(site._get_path(site._getuserbase()), 210 sysconfig.get_path('purelib', scheme)) 211 212 @unittest.skipUnless(site.ENABLE_USER_SITE, "requires access to PEP 370 " 213 "user-site (site.ENABLE_USER_SITE)") 214 def test_s_option(self): 215 # (ncoghlan) Change this to use script_helper... 216 usersite = site.USER_SITE 217 self.assertIn(usersite, sys.path) 218 219 env = os.environ.copy() 220 rc = subprocess.call([sys.executable, '-c', 221 'import sys; sys.exit(%r in sys.path)' % usersite], 222 env=env) 223 self.assertEqual(rc, 1) 224 225 env = os.environ.copy() 226 rc = subprocess.call([sys.executable, '-s', '-c', 227 'import sys; sys.exit(%r in sys.path)' % usersite], 228 env=env) 229 if usersite == site.getsitepackages()[0]: 230 self.assertEqual(rc, 1) 231 else: 232 self.assertEqual(rc, 0, "User site still added to path with -s") 233 234 env = os.environ.copy() 235 env["PYTHONNOUSERSITE"] = "1" 236 rc = subprocess.call([sys.executable, '-c', 237 'import sys; sys.exit(%r in sys.path)' % usersite], 238 env=env) 239 if usersite == site.getsitepackages()[0]: 240 self.assertEqual(rc, 1) 241 else: 242 self.assertEqual(rc, 0, 243 "User site still added to path with PYTHONNOUSERSITE") 244 245 env = os.environ.copy() 246 env["PYTHONUSERBASE"] = "/tmp" 247 rc = subprocess.call([sys.executable, '-c', 248 'import sys, site; sys.exit(site.USER_BASE.startswith("/tmp"))'], 249 env=env) 250 self.assertEqual(rc, 1, 251 "User base not set by PYTHONUSERBASE") 252 253 @unittest.skipUnless(HAS_USER_SITE, 'need user site') 254 def test_getuserbase(self): 255 site.USER_BASE = None 256 user_base = site.getuserbase() 257 258 # the call sets site.USER_BASE 259 self.assertEqual(site.USER_BASE, user_base) 260 261 # let's set PYTHONUSERBASE and see if it uses it 262 site.USER_BASE = None 263 import sysconfig 264 sysconfig._CONFIG_VARS = None 265 266 with EnvironmentVarGuard() as environ: 267 environ['PYTHONUSERBASE'] = 'xoxo' 268 self.assertTrue(site.getuserbase().startswith('xoxo'), 269 site.getuserbase()) 270 271 @unittest.skipUnless(HAS_USER_SITE, 'need user site') 272 def test_getusersitepackages(self): 273 site.USER_SITE = None 274 site.USER_BASE = None 275 user_site = site.getusersitepackages() 276 277 # the call sets USER_BASE *and* USER_SITE 278 self.assertEqual(site.USER_SITE, user_site) 279 self.assertTrue(user_site.startswith(site.USER_BASE), user_site) 280 self.assertEqual(site.USER_BASE, site.getuserbase()) 281 282 def test_getsitepackages(self): 283 site.PREFIXES = ['xoxo'] 284 dirs = site.getsitepackages() 285 if os.sep == '/': 286 # OS X, Linux, FreeBSD, etc 287 if sys.platlibdir != "lib": 288 self.assertEqual(len(dirs), 2) 289 wanted = os.path.join('xoxo', sys.platlibdir, 290 'python%d.%d' % sys.version_info[:2], 291 'site-packages') 292 self.assertEqual(dirs[0], wanted) 293 else: 294 self.assertEqual(len(dirs), 1) 295 wanted = os.path.join('xoxo', 'lib', 296 'python%d.%d' % sys.version_info[:2], 297 'site-packages') 298 self.assertEqual(dirs[-1], wanted) 299 else: 300 # other platforms 301 self.assertEqual(len(dirs), 2) 302 self.assertEqual(dirs[0], 'xoxo') 303 wanted = os.path.join('xoxo', 'lib', 'site-packages') 304 self.assertEqual(os.path.normcase(dirs[1]), 305 os.path.normcase(wanted)) 306 307 @unittest.skipUnless(HAS_USER_SITE, 'need user site') 308 def test_no_home_directory(self): 309 # bpo-10496: getuserbase() and getusersitepackages() must not fail if 310 # the current user has no home directory (if expanduser() returns the 311 # path unchanged). 312 site.USER_SITE = None 313 site.USER_BASE = None 314 315 with EnvironmentVarGuard() as environ, \ 316 mock.patch('os.path.expanduser', lambda path: path): 317 318 del environ['PYTHONUSERBASE'] 319 del environ['APPDATA'] 320 321 user_base = site.getuserbase() 322 self.assertTrue(user_base.startswith('~' + os.sep), 323 user_base) 324 325 user_site = site.getusersitepackages() 326 self.assertTrue(user_site.startswith(user_base), user_site) 327 328 with mock.patch('os.path.isdir', return_value=False) as mock_isdir, \ 329 mock.patch.object(site, 'addsitedir') as mock_addsitedir, \ 330 support.swap_attr(site, 'ENABLE_USER_SITE', True): 331 332 # addusersitepackages() must not add user_site to sys.path 333 # if it is not an existing directory 334 known_paths = set() 335 site.addusersitepackages(known_paths) 336 337 mock_isdir.assert_called_once_with(user_site) 338 mock_addsitedir.assert_not_called() 339 self.assertFalse(known_paths) 340 341 def test_trace(self): 342 message = "bla-bla-bla" 343 for verbose, out in (True, message + "\n"), (False, ""): 344 with mock.patch('sys.flags', mock.Mock(verbose=verbose)), \ 345 mock.patch('sys.stderr', io.StringIO()): 346 site._trace(message) 347 self.assertEqual(sys.stderr.getvalue(), out) 348 349 350class PthFile(object): 351 """Helper class for handling testing of .pth files""" 352 353 def __init__(self, filename_base=TESTFN, imported="time", 354 good_dirname="__testdir__", bad_dirname="__bad"): 355 """Initialize instance variables""" 356 self.filename = filename_base + ".pth" 357 self.base_dir = os.path.abspath('') 358 self.file_path = os.path.join(self.base_dir, self.filename) 359 self.imported = imported 360 self.good_dirname = good_dirname 361 self.bad_dirname = bad_dirname 362 self.good_dir_path = os.path.join(self.base_dir, self.good_dirname) 363 self.bad_dir_path = os.path.join(self.base_dir, self.bad_dirname) 364 365 def create(self): 366 """Create a .pth file with a comment, blank lines, an ``import 367 <self.imported>``, a line with self.good_dirname, and a line with 368 self.bad_dirname. 369 370 Creation of the directory for self.good_dir_path (based off of 371 self.good_dirname) is also performed. 372 373 Make sure to call self.cleanup() to undo anything done by this method. 374 375 """ 376 FILE = open(self.file_path, 'w') 377 try: 378 print("#import @bad module name", file=FILE) 379 print("\n", file=FILE) 380 print("import %s" % self.imported, file=FILE) 381 print(self.good_dirname, file=FILE) 382 print(self.bad_dirname, file=FILE) 383 finally: 384 FILE.close() 385 os.mkdir(self.good_dir_path) 386 387 def cleanup(self, prep=False): 388 """Make sure that the .pth file is deleted, self.imported is not in 389 sys.modules, and that both self.good_dirname and self.bad_dirname are 390 not existing directories.""" 391 if os.path.exists(self.file_path): 392 os.remove(self.file_path) 393 if prep: 394 self.imported_module = sys.modules.get(self.imported) 395 if self.imported_module: 396 del sys.modules[self.imported] 397 else: 398 if self.imported_module: 399 sys.modules[self.imported] = self.imported_module 400 if os.path.exists(self.good_dir_path): 401 os.rmdir(self.good_dir_path) 402 if os.path.exists(self.bad_dir_path): 403 os.rmdir(self.bad_dir_path) 404 405class ImportSideEffectTests(unittest.TestCase): 406 """Test side-effects from importing 'site'.""" 407 408 def setUp(self): 409 """Make a copy of sys.path""" 410 self.sys_path = sys.path[:] 411 412 def tearDown(self): 413 """Restore sys.path""" 414 sys.path[:] = self.sys_path 415 416 def test_abs_paths_cached_None(self): 417 """Test for __cached__ is None. 418 419 Regarding to PEP 3147, __cached__ can be None. 420 421 See also: https://bugs.python.org/issue30167 422 """ 423 sys.modules['test'].__cached__ = None 424 site.abs_paths() 425 self.assertIsNone(sys.modules['test'].__cached__) 426 427 def test_no_duplicate_paths(self): 428 # No duplicate paths should exist in sys.path 429 # Handled by removeduppaths() 430 site.removeduppaths() 431 seen_paths = set() 432 for path in sys.path: 433 self.assertNotIn(path, seen_paths) 434 seen_paths.add(path) 435 436 @unittest.skip('test not implemented') 437 def test_add_build_dir(self): 438 # Test that the build directory's Modules directory is used when it 439 # should be. 440 # XXX: implement 441 pass 442 443 def test_setting_quit(self): 444 # 'quit' and 'exit' should be injected into builtins 445 self.assertTrue(hasattr(builtins, "quit")) 446 self.assertTrue(hasattr(builtins, "exit")) 447 448 def test_setting_copyright(self): 449 # 'copyright', 'credits', and 'license' should be in builtins 450 self.assertTrue(hasattr(builtins, "copyright")) 451 self.assertTrue(hasattr(builtins, "credits")) 452 self.assertTrue(hasattr(builtins, "license")) 453 454 def test_setting_help(self): 455 # 'help' should be set in builtins 456 self.assertTrue(hasattr(builtins, "help")) 457 458 def test_aliasing_mbcs(self): 459 if sys.platform == "win32": 460 import locale 461 if locale.getdefaultlocale()[1].startswith('cp'): 462 for value in encodings.aliases.aliases.values(): 463 if value == "mbcs": 464 break 465 else: 466 self.fail("did not alias mbcs") 467 468 def test_sitecustomize_executed(self): 469 # If sitecustomize is available, it should have been imported. 470 if "sitecustomize" not in sys.modules: 471 try: 472 import sitecustomize 473 except ImportError: 474 pass 475 else: 476 self.fail("sitecustomize not imported automatically") 477 478 @test.support.requires_resource('network') 479 @test.support.system_must_validate_cert 480 @unittest.skipUnless(hasattr(urllib.request, "HTTPSHandler"), 481 'need SSL support to download license') 482 def test_license_exists_at_url(self): 483 # This test is a bit fragile since it depends on the format of the 484 # string displayed by license in the absence of a LICENSE file. 485 url = license._Printer__data.split()[1] 486 req = urllib.request.Request(url, method='HEAD') 487 # Reset global urllib.request._opener 488 self.addCleanup(urllib.request.urlcleanup) 489 try: 490 with socket_helper.transient_internet(url): 491 with urllib.request.urlopen(req) as data: 492 code = data.getcode() 493 except urllib.error.HTTPError as e: 494 code = e.code 495 self.assertEqual(code, 200, msg="Can't find " + url) 496 497 498class StartupImportTests(unittest.TestCase): 499 500 def test_startup_imports(self): 501 # Get sys.path in isolated mode (python3 -I) 502 popen = subprocess.Popen([sys.executable, '-X', 'utf8', '-I', 503 '-c', 'import sys; print(repr(sys.path))'], 504 stdout=subprocess.PIPE, 505 encoding='utf-8', 506 errors='surrogateescape') 507 stdout = popen.communicate()[0] 508 self.assertEqual(popen.returncode, 0, repr(stdout)) 509 isolated_paths = ast.literal_eval(stdout) 510 511 # bpo-27807: Even with -I, the site module executes all .pth files 512 # found in sys.path (see site.addpackage()). Skip the test if at least 513 # one .pth file is found. 514 for path in isolated_paths: 515 pth_files = glob.glob(os.path.join(glob.escape(path), "*.pth")) 516 if pth_files: 517 self.skipTest(f"found {len(pth_files)} .pth files in: {path}") 518 519 # This tests checks which modules are loaded by Python when it 520 # initially starts upon startup. 521 popen = subprocess.Popen([sys.executable, '-X', 'utf8', '-I', '-v', 522 '-c', 'import sys; print(set(sys.modules))'], 523 stdout=subprocess.PIPE, 524 stderr=subprocess.PIPE, 525 encoding='utf-8', 526 errors='surrogateescape') 527 stdout, stderr = popen.communicate() 528 self.assertEqual(popen.returncode, 0, (stdout, stderr)) 529 modules = ast.literal_eval(stdout) 530 531 self.assertIn('site', modules) 532 533 # http://bugs.python.org/issue19205 534 re_mods = {'re', '_sre', 'sre_compile', 'sre_constants', 'sre_parse'} 535 self.assertFalse(modules.intersection(re_mods), stderr) 536 537 # http://bugs.python.org/issue9548 538 self.assertNotIn('locale', modules, stderr) 539 540 # http://bugs.python.org/issue19209 541 self.assertNotIn('copyreg', modules, stderr) 542 543 # http://bugs.python.org/issue19218 544 collection_mods = {'_collections', 'collections', 'functools', 545 'heapq', 'itertools', 'keyword', 'operator', 546 'reprlib', 'types', 'weakref' 547 }.difference(sys.builtin_module_names) 548 self.assertFalse(modules.intersection(collection_mods), stderr) 549 550 def test_startup_interactivehook(self): 551 r = subprocess.Popen([sys.executable, '-c', 552 'import sys; sys.exit(hasattr(sys, "__interactivehook__"))']).wait() 553 self.assertTrue(r, "'__interactivehook__' not added by site") 554 555 def test_startup_interactivehook_isolated(self): 556 # issue28192 readline is not automatically enabled in isolated mode 557 r = subprocess.Popen([sys.executable, '-I', '-c', 558 'import sys; sys.exit(hasattr(sys, "__interactivehook__"))']).wait() 559 self.assertFalse(r, "'__interactivehook__' added in isolated mode") 560 561 def test_startup_interactivehook_isolated_explicit(self): 562 # issue28192 readline can be explicitly enabled in isolated mode 563 r = subprocess.Popen([sys.executable, '-I', '-c', 564 'import site, sys; site.enablerlcompleter(); sys.exit(hasattr(sys, "__interactivehook__"))']).wait() 565 self.assertTrue(r, "'__interactivehook__' not added by enablerlcompleter()") 566 567@unittest.skipUnless(sys.platform == 'win32', "only supported on Windows") 568class _pthFileTests(unittest.TestCase): 569 570 def _create_underpth_exe(self, lines, exe_pth=True): 571 import _winapi 572 temp_dir = tempfile.mkdtemp() 573 self.addCleanup(os_helper.rmtree, temp_dir) 574 exe_file = os.path.join(temp_dir, os.path.split(sys.executable)[1]) 575 dll_src_file = _winapi.GetModuleFileName(sys.dllhandle) 576 dll_file = os.path.join(temp_dir, os.path.split(dll_src_file)[1]) 577 shutil.copy(sys.executable, exe_file) 578 shutil.copy(dll_src_file, dll_file) 579 if exe_pth: 580 _pth_file = os.path.splitext(exe_file)[0] + '._pth' 581 else: 582 _pth_file = os.path.splitext(dll_file)[0] + '._pth' 583 with open(_pth_file, 'w') as f: 584 for line in lines: 585 print(line, file=f) 586 return exe_file 587 588 def _calc_sys_path_for_underpth_nosite(self, sys_prefix, lines): 589 sys_path = [] 590 for line in lines: 591 if not line or line[0] == '#': 592 continue 593 abs_path = os.path.abspath(os.path.join(sys_prefix, line)) 594 sys_path.append(abs_path) 595 return sys_path 596 597 def test_underpth_nosite_file(self): 598 libpath = test.support.STDLIB_DIR 599 exe_prefix = os.path.dirname(sys.executable) 600 pth_lines = [ 601 'fake-path-name', 602 *[libpath for _ in range(200)], 603 '', 604 '# comment', 605 ] 606 exe_file = self._create_underpth_exe(pth_lines) 607 sys_path = self._calc_sys_path_for_underpth_nosite( 608 os.path.dirname(exe_file), 609 pth_lines) 610 611 env = os.environ.copy() 612 env['PYTHONPATH'] = 'from-env' 613 env['PATH'] = '{};{}'.format(exe_prefix, os.getenv('PATH')) 614 output = subprocess.check_output([exe_file, '-c', 615 'import sys; print("\\n".join(sys.path) if sys.flags.no_site else "")' 616 ], env=env, encoding='ansi') 617 actual_sys_path = output.rstrip().split('\n') 618 self.assertTrue(actual_sys_path, "sys.flags.no_site was False") 619 self.assertEqual( 620 actual_sys_path, 621 sys_path, 622 "sys.path is incorrect" 623 ) 624 625 def test_underpth_file(self): 626 libpath = test.support.STDLIB_DIR 627 exe_prefix = os.path.dirname(sys.executable) 628 exe_file = self._create_underpth_exe([ 629 'fake-path-name', 630 *[libpath for _ in range(200)], 631 '', 632 '# comment', 633 'import site' 634 ]) 635 sys_prefix = os.path.dirname(exe_file) 636 env = os.environ.copy() 637 env['PYTHONPATH'] = 'from-env' 638 env['PATH'] = '{};{}'.format(exe_prefix, os.getenv('PATH')) 639 rc = subprocess.call([exe_file, '-c', 640 'import sys; sys.exit(not sys.flags.no_site and ' 641 '%r in sys.path and %r in sys.path and %r not in sys.path and ' 642 'all("\\r" not in p and "\\n" not in p for p in sys.path))' % ( 643 os.path.join(sys_prefix, 'fake-path-name'), 644 libpath, 645 os.path.join(sys_prefix, 'from-env'), 646 )], env=env) 647 self.assertTrue(rc, "sys.path is incorrect") 648 649 650 def test_underpth_dll_file(self): 651 libpath = test.support.STDLIB_DIR 652 exe_prefix = os.path.dirname(sys.executable) 653 exe_file = self._create_underpth_exe([ 654 'fake-path-name', 655 *[libpath for _ in range(200)], 656 '', 657 '# comment', 658 'import site' 659 ], exe_pth=False) 660 sys_prefix = os.path.dirname(exe_file) 661 env = os.environ.copy() 662 env['PYTHONPATH'] = 'from-env' 663 env['PATH'] = '{};{}'.format(exe_prefix, os.getenv('PATH')) 664 rc = subprocess.call([exe_file, '-c', 665 'import sys; sys.exit(not sys.flags.no_site and ' 666 '%r in sys.path and %r in sys.path and %r not in sys.path and ' 667 'all("\\r" not in p and "\\n" not in p for p in sys.path))' % ( 668 os.path.join(sys_prefix, 'fake-path-name'), 669 libpath, 670 os.path.join(sys_prefix, 'from-env'), 671 )], env=env) 672 self.assertTrue(rc, "sys.path is incorrect") 673 674 675if __name__ == "__main__": 676 unittest.main() 677