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