2004-06-04 22:12:51 -03:00
|
|
|
"""Tests for 'site'.
|
|
|
|
|
|
|
|
Tests assume the initial paths in sys.path once the interpreter has begun
|
|
|
|
executing have not been removed.
|
|
|
|
|
|
|
|
"""
|
|
|
|
import unittest
|
2013-09-07 17:59:17 -03:00
|
|
|
import test.support
|
2018-12-05 11:49:35 -04:00
|
|
|
from test import support
|
2024-01-07 02:30:12 -04:00
|
|
|
from test.support.script_helper import assert_python_ok
|
2020-08-06 08:51:29 -03:00
|
|
|
from test.support import os_helper
|
2020-04-29 04:36:20 -03:00
|
|
|
from test.support import socket_helper
|
2020-08-04 12:53:12 -03:00
|
|
|
from test.support import captured_stderr
|
2022-06-13 11:56:03 -03:00
|
|
|
from test.support.os_helper import TESTFN, EnvironmentVarGuard
|
2021-12-02 20:08:42 -04:00
|
|
|
import ast
|
2007-12-02 05:40:06 -04:00
|
|
|
import builtins
|
2020-03-18 14:27:32 -03:00
|
|
|
import glob
|
2020-06-12 03:20:11 -03:00
|
|
|
import io
|
2004-06-04 22:12:51 -03:00
|
|
|
import os
|
2010-12-26 20:03:13 -04:00
|
|
|
import re
|
2016-10-29 12:50:31 -03:00
|
|
|
import shutil
|
2024-01-16 14:23:05 -04:00
|
|
|
import stat
|
2008-05-06 20:45:46 -03:00
|
|
|
import subprocess
|
2020-03-18 14:27:32 -03:00
|
|
|
import sys
|
2010-01-29 07:41:03 -04:00
|
|
|
import sysconfig
|
2017-05-14 17:49:46 -03:00
|
|
|
import tempfile
|
2020-03-18 14:27:32 -03:00
|
|
|
import urllib.error
|
|
|
|
import urllib.request
|
2018-12-05 11:49:35 -04:00
|
|
|
from unittest import mock
|
2010-01-29 07:41:03 -04:00
|
|
|
from copy import copy
|
|
|
|
|
2013-12-11 18:59:44 -04:00
|
|
|
# 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
|
2004-06-04 22:12:51 -03:00
|
|
|
|
2017-04-20 08:39:39 -03:00
|
|
|
|
2020-12-20 18:27:42 -04:00
|
|
|
HAS_USER_SITE = (site.USER_SITE is not None)
|
2017-04-20 08:39:39 -03:00
|
|
|
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
|
2016-03-14 13:47:03 -03:00
|
|
|
|
2008-05-06 20:45:46 -03:00
|
|
|
|
2004-06-04 22:12:51 -03:00
|
|
|
class HelperFunctionsTests(unittest.TestCase):
|
|
|
|
"""Tests for helper functions.
|
|
|
|
"""
|
|
|
|
|
|
|
|
def setUp(self):
|
|
|
|
"""Save a copy of sys.path"""
|
|
|
|
self.sys_path = sys.path[:]
|
2009-08-20 18:28:05 -03:00
|
|
|
self.old_base = site.USER_BASE
|
|
|
|
self.old_site = site.USER_SITE
|
|
|
|
self.old_prefixes = site.PREFIXES
|
2012-04-04 18:31:16 -03:00
|
|
|
self.original_vars = sysconfig._CONFIG_VARS
|
2010-01-29 07:41:03 -04:00
|
|
|
self.old_vars = copy(sysconfig._CONFIG_VARS)
|
2004-06-04 22:12:51 -03:00
|
|
|
|
Merged revisions 63208-63209,63211-63212,63214-63217,63219-63224,63226-63227,63229-63232,63234-63235,63237-63239,63241,63243-63246,63250-63254,63256-63259,63261,63263-63264,63266-63267,63269-63270,63272-63273,63275-63276,63278,63280-63281,63283-63284,63286-63287,63289-63290,63292-63293,63295-63296,63298-63299,63301-63302,63304-63305,63307,63309-63314,63316-63322,63324-63325,63327-63335,63337-63338,63340-63342,63344-63346,63348 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r63208 | georg.brandl | 2008-05-13 15:04:54 -0400 (Tue, 13 May 2008) | 2 lines
#2831: add start argument to enumerate(). Patch by Scott Dial and me.
........
r63209 | marc-andre.lemburg | 2008-05-13 15:10:45 -0400 (Tue, 13 May 2008) | 3 lines
Remove leftovers from reverted setuptools checkin (they were added in r45525).
........
r63211 | georg.brandl | 2008-05-13 17:32:03 -0400 (Tue, 13 May 2008) | 2 lines
Fix a refleak in the _warnings module.
........
r63212 | andrew.kuchling | 2008-05-13 20:46:41 -0400 (Tue, 13 May 2008) | 1 line
List all the removes and renamed modules
........
r63214 | brett.cannon | 2008-05-13 21:09:40 -0400 (Tue, 13 May 2008) | 2 lines
Rewrap some lines in test_py3kwarn.
........
r63219 | georg.brandl | 2008-05-14 02:34:15 -0400 (Wed, 14 May 2008) | 2 lines
Add NEWS entry for #2831.
........
r63220 | neal.norwitz | 2008-05-14 02:47:56 -0400 (Wed, 14 May 2008) | 3 lines
Fix "refleak" by restoring the tearDown method removed by accident (AFAICT)
in r62788.
........
r63221 | georg.brandl | 2008-05-14 03:18:22 -0400 (Wed, 14 May 2008) | 2 lines
Fix another "refleak" by clearing the filters after test.
........
r63222 | neal.norwitz | 2008-05-14 03:21:42 -0400 (Wed, 14 May 2008) | 5 lines
Install the json package and tests as well as the lib2to3 tests
so the tests work when run from an install directory.
They are currently skipped on the daily runs (not from the buildbots)
for checking refleaks, etc.
........
r63256 | andrew.kuchling | 2008-05-14 21:10:24 -0400 (Wed, 14 May 2008) | 1 line
Note some removals and a rename
........
r63311 | brett.cannon | 2008-05-15 00:36:53 -0400 (Thu, 15 May 2008) | 2 lines
Add a snippet for the deprecation directive for docs.
........
r63313 | gregory.p.smith | 2008-05-15 00:56:18 -0400 (Thu, 15 May 2008) | 5 lines
disable the crashing test. I will also file a bug. This crash does
not appear to be a new bug, its just that the test coverage went up
recently exposing it. (I verified that by testing this test code on
an older Modules/_bsddb.c)
........
r63320 | georg.brandl | 2008-05-15 11:08:32 -0400 (Thu, 15 May 2008) | 2 lines
#2863: add gen.__name__ and add this name to generator repr().
........
r63324 | andrew.kuchling | 2008-05-15 16:07:39 -0400 (Thu, 15 May 2008) | 1 line
Import class from distutils.cmd, not .core, to avoid circular import
........
r63327 | alexandre.vassalotti | 2008-05-15 16:31:42 -0400 (Thu, 15 May 2008) | 2 lines
Fixed typo in a doctest of test_genexps.
........
r63332 | benjamin.peterson | 2008-05-15 18:34:33 -0400 (Thu, 15 May 2008) | 2 lines
add Mac modules to the list of deprecated ones
........
r63333 | benjamin.peterson | 2008-05-15 18:41:16 -0400 (Thu, 15 May 2008) | 2 lines
fix typos in whatsnew
........
r63348 | benjamin.peterson | 2008-05-15 22:24:49 -0400 (Thu, 15 May 2008) | 2 lines
make test_platform a bit more assertive (We'll see what the buildbots say.)
........
2008-05-16 01:39:54 -03:00
|
|
|
def tearDown(self):
|
2004-06-04 22:12:51 -03:00
|
|
|
"""Restore sys.path"""
|
Note that a number of the changes listed below were not applicable to the Py3k branch, and hence the corresponding
files are unchanged in this checkin. This checkin is also the first time the environment checking in regrtest has
been forward ported to the Py3k branch.
This checkin causes test_xmlrpc to fail - see issue 7165 (it's a bug in the 3.x version of xmlrpc.server)
I am also getting a failure in test_telnetlib, but it isn't clear yet if that is due to these changes.
Recorded merge of revisions 75400-75401,75404,75406,75414,75416,75422,75425-75428,75435,75439,75441-75444,75447-75449,75451-75453,75455-75458,75460-75469,75471-75473,75475-75477,75479-75481,75483,75486-75489 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r75400 | r.david.murray | 2009-10-14 23:58:07 +1000 (Wed, 14 Oct 2009) | 6 lines
Enhanced Issue 7058 patch, which will not be backported. Refactors the
code, adds checks for stdin/out/err, cwd, and sys.path, and adds a new
section in the summary for tests that modify the environment (thanks to
Ezio Melotti for that suggestion).
........
r75453 | nick.coghlan | 2009-10-17 16:33:05 +1000 (Sat, 17 Oct 2009) | 1 line
Correctly restore sys.stdout in test_descr
........
r75456 | nick.coghlan | 2009-10-17 17:30:40 +1000 (Sat, 17 Oct 2009) | 1 line
Enhancement to the new environment checking code to print the changed items under -vv. Also includes a small tweak to allow underscores in the names of resources.
........
r75457 | nick.coghlan | 2009-10-17 17:34:27 +1000 (Sat, 17 Oct 2009) | 1 line
Formatting tweak so that before and after values are vertically aligned
........
r75458 | nick.coghlan | 2009-10-17 18:21:21 +1000 (Sat, 17 Oct 2009) | 1 line
Check and revert expected sys.path alterations
........
r75461 | nick.coghlan | 2009-10-18 00:40:54 +1000 (Sun, 18 Oct 2009) | 1 line
Restore original sys.path when running TTK tests
........
r75462 | nick.coghlan | 2009-10-18 01:09:41 +1000 (Sun, 18 Oct 2009) | 1 line
Don't invoke reload(sys) and use StringIO objects instead of real files to capture stdin and stdout when needed (ensures all sys attributes remain unmodified after test_xmlrpc runs)
........
r75463 | nick.coghlan | 2009-10-18 01:23:08 +1000 (Sun, 18 Oct 2009) | 1 line
Revert changes made to environment in test_httpservers
........
r75465 | nick.coghlan | 2009-10-18 01:45:52 +1000 (Sun, 18 Oct 2009) | 1 line
Move restoration of the os.environ object into the context manager where it belongs
........
r75466 | nick.coghlan | 2009-10-18 01:48:16 +1000 (Sun, 18 Oct 2009) | 1 line
Also check and restore identity of sys.path, sys.argv and os.environ rather than just their values (this picked up a few more misbehaving tests)
........
r75467 | nick.coghlan | 2009-10-18 01:57:42 +1000 (Sun, 18 Oct 2009) | 1 line
Avoid replacing existing modules and sys.path in import tests
........
r75468 | nick.coghlan | 2009-10-18 02:19:51 +1000 (Sun, 18 Oct 2009) | 1 line
Don't replace sys.path in test_site
........
r75481 | nick.coghlan | 2009-10-18 15:38:48 +1000 (Sun, 18 Oct 2009) | 1 line
Using CleanImport to revert a reload of the os module doesn't work due to function registrations in copy_reg. The perils of reloading modules even for tests...
........
r75486 | nick.coghlan | 2009-10-18 20:29:10 +1000 (Sun, 18 Oct 2009) | 1 line
Silence a deprecation warning by using the appropriate replacement construct
........
r75489 | nick.coghlan | 2009-10-18 20:56:21 +1000 (Sun, 18 Oct 2009) | 1 line
Restore sys.path in test_tk
........
2009-10-18 10:19:33 -03:00
|
|
|
sys.path[:] = self.sys_path
|
2009-08-20 18:28:05 -03:00
|
|
|
site.USER_BASE = self.old_base
|
|
|
|
site.USER_SITE = self.old_site
|
|
|
|
site.PREFIXES = self.old_prefixes
|
2012-04-04 18:31:16 -03:00
|
|
|
sysconfig._CONFIG_VARS = self.original_vars
|
2021-05-20 07:25:37 -03:00
|
|
|
# _CONFIG_VARS is None before get_config_vars() is called
|
|
|
|
if sysconfig._CONFIG_VARS is not None:
|
|
|
|
sysconfig._CONFIG_VARS.clear()
|
|
|
|
sysconfig._CONFIG_VARS.update(self.old_vars)
|
2004-06-27 00:02:18 -03:00
|
|
|
|
2004-06-04 22:12:51 -03:00
|
|
|
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)
|
2009-06-30 20:06:06 -03:00
|
|
|
self.assertEqual(os.path.abspath(original_dir), abs_dir)
|
2004-06-04 22:12:51 -03:00
|
|
|
if original_dir == os.path.normcase(original_dir):
|
2009-06-30 20:06:06 -03:00
|
|
|
self.assertEqual(abs_dir, norm_dir)
|
2004-06-04 22:12:51 -03:00
|
|
|
else:
|
2009-06-30 20:06:06 -03:00
|
|
|
self.assertEqual(os.path.normcase(abs_dir), norm_dir)
|
2004-06-04 22:12:51 -03:00
|
|
|
|
|
|
|
def test_init_pathinfo(self):
|
|
|
|
dir_set = site._init_pathinfo()
|
|
|
|
for entry in [site.makepath(path)[1] for path in sys.path
|
2016-04-08 19:04:28 -03:00
|
|
|
if path and os.path.exists(path)]:
|
2010-01-23 11:40:09 -04:00
|
|
|
self.assertIn(entry, dir_set,
|
|
|
|
"%s from sys.path not found in set returned "
|
|
|
|
"by _init_pathinfo(): %s" % (entry, dir_set))
|
2004-06-27 00:02:18 -03:00
|
|
|
|
2004-07-13 04:12:25 -03:00
|
|
|
def pth_file_tests(self, pth_file):
|
|
|
|
"""Contain common code for testing results of reading a .pth file"""
|
2010-01-23 11:40:09 -04:00
|
|
|
self.assertIn(pth_file.imported, sys.modules,
|
|
|
|
"%s not in sys.modules" % pth_file.imported)
|
2009-11-01 19:55:40 -04:00
|
|
|
self.assertIn(site.makepath(pth_file.good_dir_path)[0], sys.path)
|
|
|
|
self.assertFalse(os.path.exists(pth_file.bad_dir_path))
|
2004-07-13 04:12:25 -03:00
|
|
|
|
2004-06-04 22:12:51 -03:00
|
|
|
def test_addpackage(self):
|
|
|
|
# Make sure addpackage() imports if the line starts with 'import',
|
2004-07-09 23:10:45 -03:00
|
|
|
# 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()
|
2004-07-13 04:12:25 -03:00
|
|
|
pth_file.cleanup(prep=True) # to make sure that nothing is
|
|
|
|
# pre-existing that shouldn't be
|
2004-06-04 22:12:51 -03:00
|
|
|
try:
|
2004-07-09 23:10:45 -03:00
|
|
|
pth_file.create()
|
|
|
|
site.addpackage(pth_file.base_dir, pth_file.filename, set())
|
2004-07-13 04:12:25 -03:00
|
|
|
self.pth_file_tests(pth_file)
|
2004-06-04 22:12:51 -03:00
|
|
|
finally:
|
2004-07-09 23:10:45 -03:00
|
|
|
pth_file.cleanup()
|
2004-06-27 00:02:18 -03:00
|
|
|
|
2010-12-26 15:54:29 -04:00
|
|
|
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)
|
2019-03-05 04:06:26 -04:00
|
|
|
with open(pth_fn, 'w', encoding='utf-8') as pth_file:
|
|
|
|
self.addCleanup(lambda: os.remove(pth_fn))
|
|
|
|
pth_file.write(contents)
|
2010-12-26 15:54:29 -04:00
|
|
|
return pth_dir, pth_basename
|
|
|
|
|
|
|
|
def test_addpackage_import_bad_syntax(self):
|
|
|
|
# Issue 10642
|
2018-12-17 11:34:14 -04:00
|
|
|
pth_dir, pth_fn = self.make_pth("import bad-syntax\n")
|
2010-12-26 15:54:29 -04:00
|
|
|
with captured_stderr() as err_out:
|
|
|
|
site.addpackage(pth_dir, pth_fn, set())
|
|
|
|
self.assertRegex(err_out.getvalue(), "line 1")
|
2010-12-26 20:03:13 -04:00
|
|
|
self.assertRegex(err_out.getvalue(),
|
|
|
|
re.escape(os.path.join(pth_dir, pth_fn)))
|
2010-12-26 15:54:29 -04:00
|
|
|
# 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')
|
2018-12-17 11:34:14 -04:00
|
|
|
self.assertRegex(err_out.getvalue(), r'import bad-syntax')
|
2010-12-26 15:54:29 -04:00
|
|
|
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")
|
2010-12-26 20:03:13 -04:00
|
|
|
self.assertRegex(err_out.getvalue(),
|
|
|
|
re.escape(os.path.join(pth_dir, pth_fn)))
|
2010-12-26 15:54:29 -04:00
|
|
|
# XXX: ditto previous XXX comment.
|
|
|
|
self.assertRegex(err_out.getvalue(), 'Traceback')
|
2016-09-07 20:56:15 -03:00
|
|
|
self.assertRegex(err_out.getvalue(), 'ModuleNotFoundError')
|
2010-12-26 15:54:29 -04:00
|
|
|
|
2020-09-19 16:13:29 -03:00
|
|
|
def test_addpackage_empty_lines(self):
|
|
|
|
# Issue 33689
|
|
|
|
pth_dir, pth_fn = self.make_pth("\n\n \n\n")
|
|
|
|
known_paths = site.addpackage(pth_dir, pth_fn, set())
|
|
|
|
self.assertEqual(known_paths, set())
|
|
|
|
|
2010-12-26 15:54:29 -04:00
|
|
|
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:
|
2018-09-18 05:28:51 -03:00
|
|
|
self.assertFalse(site.addpackage(pth_dir, pth_fn, set()))
|
2021-04-06 21:02:07 -03:00
|
|
|
self.maxDiff = None
|
2018-09-18 05:28:51 -03:00
|
|
|
self.assertEqual(err_out.getvalue(), "")
|
|
|
|
for path in sys.path:
|
|
|
|
if isinstance(path, str):
|
|
|
|
self.assertNotIn("abc\x00def", path)
|
2010-12-26 15:54:29 -04:00
|
|
|
|
2004-06-04 22:12:51 -03:00
|
|
|
def test_addsitedir(self):
|
2004-07-09 23:10:45 -03:00
|
|
|
# Same tests for test_addpackage since addsitedir() essentially just
|
|
|
|
# calls addpackage() for every .pth file in the directory
|
|
|
|
pth_file = PthFile()
|
2004-07-13 04:12:25 -03:00
|
|
|
pth_file.cleanup(prep=True) # Make sure that nothing is pre-existing
|
|
|
|
# that is tested for
|
2004-06-04 22:12:51 -03:00
|
|
|
try:
|
2004-07-13 04:12:25 -03:00
|
|
|
pth_file.create()
|
2004-07-09 23:10:45 -03:00
|
|
|
site.addsitedir(pth_file.base_dir, set())
|
2004-07-13 04:12:25 -03:00
|
|
|
self.pth_file_tests(pth_file)
|
2004-06-04 22:12:51 -03:00
|
|
|
finally:
|
2004-07-09 23:10:45 -03:00
|
|
|
pth_file.cleanup()
|
|
|
|
|
2024-01-16 14:23:05 -04:00
|
|
|
def test_addsitedir_dotfile(self):
|
|
|
|
pth_file = PthFile('.dotfile')
|
|
|
|
pth_file.cleanup(prep=True)
|
|
|
|
try:
|
|
|
|
pth_file.create()
|
|
|
|
site.addsitedir(pth_file.base_dir, set())
|
|
|
|
self.assertNotIn(site.makepath(pth_file.good_dir_path)[0], sys.path)
|
|
|
|
self.assertIn(pth_file.base_dir, sys.path)
|
|
|
|
finally:
|
|
|
|
pth_file.cleanup()
|
|
|
|
|
|
|
|
@unittest.skipUnless(hasattr(os, 'chflags'), 'test needs os.chflags()')
|
|
|
|
def test_addsitedir_hidden_flags(self):
|
|
|
|
pth_file = PthFile()
|
|
|
|
pth_file.cleanup(prep=True)
|
|
|
|
try:
|
|
|
|
pth_file.create()
|
|
|
|
st = os.stat(pth_file.file_path)
|
|
|
|
os.chflags(pth_file.file_path, st.st_flags | stat.UF_HIDDEN)
|
|
|
|
site.addsitedir(pth_file.base_dir, set())
|
|
|
|
self.assertNotIn(site.makepath(pth_file.good_dir_path)[0], sys.path)
|
|
|
|
self.assertIn(pth_file.base_dir, sys.path)
|
|
|
|
finally:
|
|
|
|
pth_file.cleanup()
|
|
|
|
|
|
|
|
@unittest.skipUnless(sys.platform == 'win32', 'test needs Windows')
|
|
|
|
@support.requires_subprocess()
|
|
|
|
def test_addsitedir_hidden_file_attribute(self):
|
|
|
|
pth_file = PthFile()
|
|
|
|
pth_file.cleanup(prep=True)
|
|
|
|
try:
|
|
|
|
pth_file.create()
|
|
|
|
subprocess.check_call(['attrib', '+H', pth_file.file_path])
|
|
|
|
site.addsitedir(pth_file.base_dir, set())
|
|
|
|
self.assertNotIn(site.makepath(pth_file.good_dir_path)[0], sys.path)
|
|
|
|
self.assertIn(pth_file.base_dir, sys.path)
|
|
|
|
finally:
|
|
|
|
pth_file.cleanup()
|
|
|
|
|
2019-03-03 12:05:19 -04:00
|
|
|
# This tests _getuserbase, hence the double underline
|
|
|
|
# to distinguish from a test for getuserbase
|
|
|
|
def test__getuserbase(self):
|
2017-06-28 12:31:53 -03:00
|
|
|
self.assertEqual(site._getuserbase(), sysconfig._getuserbase())
|
|
|
|
|
2020-12-20 18:27:42 -04:00
|
|
|
@unittest.skipUnless(HAS_USER_SITE, 'need user site')
|
2017-06-28 12:31:53 -03:00
|
|
|
def test_get_path(self):
|
2017-07-28 09:28:19 -03:00
|
|
|
if sys.platform == 'darwin' and sys._framework:
|
|
|
|
scheme = 'osx_framework_user'
|
|
|
|
else:
|
|
|
|
scheme = os.name + '_user'
|
2022-06-17 19:28:23 -03:00
|
|
|
self.assertEqual(os.path.normpath(site._get_path(site._getuserbase())),
|
2017-07-28 09:28:19 -03:00
|
|
|
sysconfig.get_path('purelib', scheme))
|
2017-06-28 12:31:53 -03:00
|
|
|
|
2011-10-31 20:16:35 -03:00
|
|
|
@unittest.skipUnless(site.ENABLE_USER_SITE, "requires access to PEP 370 "
|
|
|
|
"user-site (site.ENABLE_USER_SITE)")
|
2022-01-25 03:09:06 -04:00
|
|
|
@support.requires_subprocess()
|
2008-05-06 20:45:46 -03:00
|
|
|
def test_s_option(self):
|
2017-05-23 01:36:03 -03:00
|
|
|
# (ncoghlan) Change this to use script_helper...
|
2022-06-17 19:28:23 -03:00
|
|
|
usersite = os.path.normpath(site.USER_SITE)
|
2009-11-01 19:55:40 -04:00
|
|
|
self.assertIn(usersite, sys.path)
|
2008-05-06 20:45:46 -03:00
|
|
|
|
2011-01-03 13:51:11 -04:00
|
|
|
env = os.environ.copy()
|
2008-05-06 20:45:46 -03:00
|
|
|
rc = subprocess.call([sys.executable, '-c',
|
2011-01-03 13:51:11 -04:00
|
|
|
'import sys; sys.exit(%r in sys.path)' % usersite],
|
|
|
|
env=env)
|
2008-05-06 20:45:46 -03:00
|
|
|
self.assertEqual(rc, 1)
|
|
|
|
|
2011-01-03 13:51:11 -04:00
|
|
|
env = os.environ.copy()
|
2008-05-06 20:45:46 -03:00
|
|
|
rc = subprocess.call([sys.executable, '-s', '-c',
|
2011-01-03 13:51:11 -04:00
|
|
|
'import sys; sys.exit(%r in sys.path)' % usersite],
|
|
|
|
env=env)
|
2013-10-23 17:03:22 -03:00
|
|
|
if usersite == site.getsitepackages()[0]:
|
|
|
|
self.assertEqual(rc, 1)
|
|
|
|
else:
|
2017-05-23 01:36:03 -03:00
|
|
|
self.assertEqual(rc, 0, "User site still added to path with -s")
|
2008-05-06 20:45:46 -03:00
|
|
|
|
|
|
|
env = os.environ.copy()
|
|
|
|
env["PYTHONNOUSERSITE"] = "1"
|
|
|
|
rc = subprocess.call([sys.executable, '-c',
|
Merged revisions 64365,64370,64406,64408-64409,64412,64416-64417,64420-64421,64425-64428 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r64365 | raymond.hettinger | 2008-06-17 19:56:57 -0500 (Tue, 17 Jun 2008) | 1 line
Fix double decref.
........
r64370 | mark.dickinson | 2008-06-18 04:20:17 -0500 (Wed, 18 Jun 2008) | 2 lines
Typo fix
........
r64406 | andrew.kuchling | 2008-06-19 09:02:30 -0500 (Thu, 19 Jun 2008) | 1 line
Only include update_lines_cols() function when it's actually going to be used
........
r64408 | amaury.forgeotdarc | 2008-06-19 14:57:39 -0500 (Thu, 19 Jun 2008) | 2 lines
test_macos can be skipped on non-mac platforms.
........
r64409 | andrew.kuchling | 2008-06-19 15:33:31 -0500 (Thu, 19 Jun 2008) | 1 line
Put threading in front of thread
........
r64412 | amaury.forgeotdarc | 2008-06-19 16:17:12 -0500 (Thu, 19 Jun 2008) | 3 lines
In test_site, correctly escape backslashes in path names.
This allows the test to pass when the username begins with a lowercase 't'...
........
r64416 | vinay.sajip | 2008-06-19 17:40:17 -0500 (Thu, 19 Jun 2008) | 2 lines
Bug #3136: fileConfig()'s disabling of old loggers is now conditional via an optional disable_existing_loggers parameter, but the default value is such that the old behaviour is preserved.
Thanks to Leandro Lucarella for the patch.
........
r64417 | vinay.sajip | 2008-06-19 17:41:08 -0500 (Thu, 19 Jun 2008) | 1 line
Updated with fix for #3136.
........
r64420 | andrew.kuchling | 2008-06-19 21:05:57 -0500 (Thu, 19 Jun 2008) | 1 line
Various items
........
r64421 | andrew.kuchling | 2008-06-19 21:11:42 -0500 (Thu, 19 Jun 2008) | 1 line
Fix comment typos
........
r64425 | andrew.kuchling | 2008-06-20 06:39:54 -0500 (Fri, 20 Jun 2008) | 1 line
Various items
........
r64426 | mark.dickinson | 2008-06-20 09:53:43 -0500 (Fri, 20 Jun 2008) | 4 lines
Issue #3004: Minor fix to slice.indices(). slice(-10).indices(9) now
returns (0, 0, 1) instead of (0, -1, 1), and slice(None, 10, -1).indices(10)
returns (9, 9, -1) instead of (9, 10, -1).
........
r64427 | mark.dickinson | 2008-06-20 10:17:41 -0500 (Fri, 20 Jun 2008) | 2 lines
Fix outdated count of the number of new math module functions.
........
r64428 | mark.dickinson | 2008-06-20 10:26:19 -0500 (Fri, 20 Jun 2008) | 2 lines
Fix another typo in math_sum comment
........
2008-07-02 13:11:42 -03:00
|
|
|
'import sys; sys.exit(%r in sys.path)' % usersite],
|
2008-05-06 20:45:46 -03:00
|
|
|
env=env)
|
2013-10-23 17:03:22 -03:00
|
|
|
if usersite == site.getsitepackages()[0]:
|
|
|
|
self.assertEqual(rc, 1)
|
|
|
|
else:
|
2017-05-23 01:36:03 -03:00
|
|
|
self.assertEqual(rc, 0,
|
|
|
|
"User site still added to path with PYTHONNOUSERSITE")
|
2008-05-06 20:45:46 -03:00
|
|
|
|
|
|
|
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)
|
2017-05-23 01:36:03 -03:00
|
|
|
self.assertEqual(rc, 1,
|
|
|
|
"User base not set by PYTHONUSERBASE")
|
2008-05-06 20:45:46 -03:00
|
|
|
|
2020-12-20 18:27:42 -04:00
|
|
|
@unittest.skipUnless(HAS_USER_SITE, 'need user site')
|
2009-08-20 18:28:05 -03:00
|
|
|
def test_getuserbase(self):
|
|
|
|
site.USER_BASE = None
|
|
|
|
user_base = site.getuserbase()
|
|
|
|
|
|
|
|
# the call sets site.USER_BASE
|
2010-11-20 15:04:17 -04:00
|
|
|
self.assertEqual(site.USER_BASE, user_base)
|
2009-08-20 18:28:05 -03:00
|
|
|
|
|
|
|
# let's set PYTHONUSERBASE and see if it uses it
|
|
|
|
site.USER_BASE = None
|
2010-01-29 07:41:03 -04:00
|
|
|
import sysconfig
|
|
|
|
sysconfig._CONFIG_VARS = None
|
|
|
|
|
2009-08-20 18:28:05 -03:00
|
|
|
with EnvironmentVarGuard() as environ:
|
|
|
|
environ['PYTHONUSERBASE'] = 'xoxo'
|
2009-11-01 19:55:40 -04:00
|
|
|
self.assertTrue(site.getuserbase().startswith('xoxo'),
|
|
|
|
site.getuserbase())
|
2009-08-20 18:28:05 -03:00
|
|
|
|
2020-12-20 18:27:42 -04:00
|
|
|
@unittest.skipUnless(HAS_USER_SITE, 'need user site')
|
2009-08-20 18:28:05 -03:00
|
|
|
def test_getusersitepackages(self):
|
|
|
|
site.USER_SITE = None
|
|
|
|
site.USER_BASE = None
|
|
|
|
user_site = site.getusersitepackages()
|
|
|
|
|
|
|
|
# the call sets USER_BASE *and* USER_SITE
|
2010-11-20 15:04:17 -04:00
|
|
|
self.assertEqual(site.USER_SITE, user_site)
|
2009-11-01 19:55:40 -04:00
|
|
|
self.assertTrue(user_site.startswith(site.USER_BASE), user_site)
|
2018-12-05 11:49:35 -04:00
|
|
|
self.assertEqual(site.USER_BASE, site.getuserbase())
|
2009-08-20 18:28:05 -03:00
|
|
|
|
|
|
|
def test_getsitepackages(self):
|
|
|
|
site.PREFIXES = ['xoxo']
|
|
|
|
dirs = site.getsitepackages()
|
2018-01-30 06:14:09 -04:00
|
|
|
if os.sep == '/':
|
|
|
|
# OS X, Linux, FreeBSD, etc
|
2020-03-10 05:53:09 -03:00
|
|
|
if sys.platlibdir != "lib":
|
|
|
|
self.assertEqual(len(dirs), 2)
|
|
|
|
wanted = os.path.join('xoxo', sys.platlibdir,
|
2024-07-11 18:00:28 -03:00
|
|
|
f'python{sysconfig._get_python_version_abi()}',
|
2020-03-10 05:53:09 -03:00
|
|
|
'site-packages')
|
|
|
|
self.assertEqual(dirs[0], wanted)
|
|
|
|
else:
|
|
|
|
self.assertEqual(len(dirs), 1)
|
2016-02-11 07:10:36 -04:00
|
|
|
wanted = os.path.join('xoxo', 'lib',
|
2024-07-11 18:00:28 -03:00
|
|
|
f'python{sysconfig._get_python_version_abi()}',
|
2009-08-20 18:28:05 -03:00
|
|
|
'site-packages')
|
2020-03-10 05:53:09 -03:00
|
|
|
self.assertEqual(dirs[-1], wanted)
|
2009-08-20 18:28:05 -03:00
|
|
|
else:
|
2012-02-05 19:58:18 -04:00
|
|
|
# other platforms
|
2010-08-17 05:35:41 -03:00
|
|
|
self.assertEqual(len(dirs), 2)
|
2010-11-20 15:04:17 -04:00
|
|
|
self.assertEqual(dirs[0], 'xoxo')
|
2009-10-27 18:24:21 -03:00
|
|
|
wanted = os.path.join('xoxo', 'lib', 'site-packages')
|
2021-12-02 20:08:42 -04:00
|
|
|
self.assertEqual(os.path.normcase(dirs[1]),
|
|
|
|
os.path.normcase(wanted))
|
2009-08-20 18:28:05 -03:00
|
|
|
|
2020-12-20 18:27:42 -04:00
|
|
|
@unittest.skipUnless(HAS_USER_SITE, 'need user site')
|
2018-12-05 11:49:35 -04:00
|
|
|
def test_no_home_directory(self):
|
|
|
|
# bpo-10496: getuserbase() and getusersitepackages() must not fail if
|
|
|
|
# the current user has no home directory (if expanduser() returns the
|
|
|
|
# path unchanged).
|
|
|
|
site.USER_SITE = None
|
|
|
|
site.USER_BASE = None
|
|
|
|
|
|
|
|
with EnvironmentVarGuard() as environ, \
|
|
|
|
mock.patch('os.path.expanduser', lambda path: path):
|
|
|
|
|
|
|
|
del environ['PYTHONUSERBASE']
|
|
|
|
del environ['APPDATA']
|
|
|
|
|
|
|
|
user_base = site.getuserbase()
|
|
|
|
self.assertTrue(user_base.startswith('~' + os.sep),
|
|
|
|
user_base)
|
|
|
|
|
|
|
|
user_site = site.getusersitepackages()
|
|
|
|
self.assertTrue(user_site.startswith(user_base), user_site)
|
|
|
|
|
|
|
|
with mock.patch('os.path.isdir', return_value=False) as mock_isdir, \
|
|
|
|
mock.patch.object(site, 'addsitedir') as mock_addsitedir, \
|
|
|
|
support.swap_attr(site, 'ENABLE_USER_SITE', True):
|
|
|
|
|
|
|
|
# addusersitepackages() must not add user_site to sys.path
|
|
|
|
# if it is not an existing directory
|
|
|
|
known_paths = set()
|
|
|
|
site.addusersitepackages(known_paths)
|
|
|
|
|
|
|
|
mock_isdir.assert_called_once_with(user_site)
|
|
|
|
mock_addsitedir.assert_not_called()
|
|
|
|
self.assertFalse(known_paths)
|
|
|
|
|
2024-01-07 02:30:12 -04:00
|
|
|
def test_gethistoryfile(self):
|
|
|
|
filename = 'file'
|
|
|
|
rc, out, err = assert_python_ok('-c',
|
|
|
|
f'import site; assert site.gethistoryfile() == "{filename}"',
|
|
|
|
PYTHON_HISTORY=filename)
|
|
|
|
self.assertEqual(rc, 0)
|
|
|
|
|
|
|
|
# Check that PYTHON_HISTORY is ignored in isolated mode.
|
|
|
|
rc, out, err = assert_python_ok('-I', '-c',
|
|
|
|
f'import site; assert site.gethistoryfile() != "{filename}"',
|
|
|
|
PYTHON_HISTORY=filename)
|
|
|
|
self.assertEqual(rc, 0)
|
|
|
|
|
2020-06-12 03:20:11 -03:00
|
|
|
def test_trace(self):
|
|
|
|
message = "bla-bla-bla"
|
|
|
|
for verbose, out in (True, message + "\n"), (False, ""):
|
|
|
|
with mock.patch('sys.flags', mock.Mock(verbose=verbose)), \
|
|
|
|
mock.patch('sys.stderr', io.StringIO()):
|
|
|
|
site._trace(message)
|
|
|
|
self.assertEqual(sys.stderr.getvalue(), out)
|
|
|
|
|
2018-12-05 11:49:35 -04:00
|
|
|
|
2004-07-09 23:10:45 -03:00
|
|
|
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)
|
2004-07-13 04:12:25 -03:00
|
|
|
self.imported = imported
|
2004-07-09 23:10:45 -03:00
|
|
|
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.
|
2004-07-18 03:16:08 -03:00
|
|
|
|
2004-07-09 23:10:45 -03:00
|
|
|
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.
|
2004-07-18 03:16:08 -03:00
|
|
|
|
2004-07-09 23:10:45 -03:00
|
|
|
"""
|
2005-05-27 11:58:06 -03:00
|
|
|
FILE = open(self.file_path, 'w')
|
2004-07-09 23:10:45 -03:00
|
|
|
try:
|
2007-02-09 01:37:30 -04:00
|
|
|
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)
|
2004-07-09 23:10:45 -03:00
|
|
|
finally:
|
|
|
|
FILE.close()
|
|
|
|
os.mkdir(self.good_dir_path)
|
2004-06-04 22:12:51 -03:00
|
|
|
|
2004-07-13 04:12:25 -03:00
|
|
|
def cleanup(self, prep=False):
|
2004-07-09 23:10:45 -03:00
|
|
|
"""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."""
|
2004-07-13 04:12:25 -03:00
|
|
|
if os.path.exists(self.file_path):
|
2004-07-09 23:10:45 -03:00
|
|
|
os.remove(self.file_path)
|
2004-07-13 04:12:25 -03:00
|
|
|
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):
|
2004-07-09 23:10:45 -03:00
|
|
|
os.rmdir(self.good_dir_path)
|
2004-07-13 04:12:25 -03:00
|
|
|
if os.path.exists(self.bad_dir_path):
|
2004-07-09 23:10:45 -03:00
|
|
|
os.rmdir(self.bad_dir_path)
|
2004-06-04 22:12:51 -03:00
|
|
|
|
|
|
|
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"""
|
Note that a number of the changes listed below were not applicable to the Py3k branch, and hence the corresponding
files are unchanged in this checkin. This checkin is also the first time the environment checking in regrtest has
been forward ported to the Py3k branch.
This checkin causes test_xmlrpc to fail - see issue 7165 (it's a bug in the 3.x version of xmlrpc.server)
I am also getting a failure in test_telnetlib, but it isn't clear yet if that is due to these changes.
Recorded merge of revisions 75400-75401,75404,75406,75414,75416,75422,75425-75428,75435,75439,75441-75444,75447-75449,75451-75453,75455-75458,75460-75469,75471-75473,75475-75477,75479-75481,75483,75486-75489 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r75400 | r.david.murray | 2009-10-14 23:58:07 +1000 (Wed, 14 Oct 2009) | 6 lines
Enhanced Issue 7058 patch, which will not be backported. Refactors the
code, adds checks for stdin/out/err, cwd, and sys.path, and adds a new
section in the summary for tests that modify the environment (thanks to
Ezio Melotti for that suggestion).
........
r75453 | nick.coghlan | 2009-10-17 16:33:05 +1000 (Sat, 17 Oct 2009) | 1 line
Correctly restore sys.stdout in test_descr
........
r75456 | nick.coghlan | 2009-10-17 17:30:40 +1000 (Sat, 17 Oct 2009) | 1 line
Enhancement to the new environment checking code to print the changed items under -vv. Also includes a small tweak to allow underscores in the names of resources.
........
r75457 | nick.coghlan | 2009-10-17 17:34:27 +1000 (Sat, 17 Oct 2009) | 1 line
Formatting tweak so that before and after values are vertically aligned
........
r75458 | nick.coghlan | 2009-10-17 18:21:21 +1000 (Sat, 17 Oct 2009) | 1 line
Check and revert expected sys.path alterations
........
r75461 | nick.coghlan | 2009-10-18 00:40:54 +1000 (Sun, 18 Oct 2009) | 1 line
Restore original sys.path when running TTK tests
........
r75462 | nick.coghlan | 2009-10-18 01:09:41 +1000 (Sun, 18 Oct 2009) | 1 line
Don't invoke reload(sys) and use StringIO objects instead of real files to capture stdin and stdout when needed (ensures all sys attributes remain unmodified after test_xmlrpc runs)
........
r75463 | nick.coghlan | 2009-10-18 01:23:08 +1000 (Sun, 18 Oct 2009) | 1 line
Revert changes made to environment in test_httpservers
........
r75465 | nick.coghlan | 2009-10-18 01:45:52 +1000 (Sun, 18 Oct 2009) | 1 line
Move restoration of the os.environ object into the context manager where it belongs
........
r75466 | nick.coghlan | 2009-10-18 01:48:16 +1000 (Sun, 18 Oct 2009) | 1 line
Also check and restore identity of sys.path, sys.argv and os.environ rather than just their values (this picked up a few more misbehaving tests)
........
r75467 | nick.coghlan | 2009-10-18 01:57:42 +1000 (Sun, 18 Oct 2009) | 1 line
Avoid replacing existing modules and sys.path in import tests
........
r75468 | nick.coghlan | 2009-10-18 02:19:51 +1000 (Sun, 18 Oct 2009) | 1 line
Don't replace sys.path in test_site
........
r75481 | nick.coghlan | 2009-10-18 15:38:48 +1000 (Sun, 18 Oct 2009) | 1 line
Using CleanImport to revert a reload of the os module doesn't work due to function registrations in copy_reg. The perils of reloading modules even for tests...
........
r75486 | nick.coghlan | 2009-10-18 20:29:10 +1000 (Sun, 18 Oct 2009) | 1 line
Silence a deprecation warning by using the appropriate replacement construct
........
r75489 | nick.coghlan | 2009-10-18 20:56:21 +1000 (Sun, 18 Oct 2009) | 1 line
Restore sys.path in test_tk
........
2009-10-18 10:19:33 -03:00
|
|
|
sys.path[:] = self.sys_path
|
2004-06-04 22:12:51 -03:00
|
|
|
|
2018-10-01 09:10:37 -03:00
|
|
|
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__)
|
|
|
|
|
2004-06-04 22:12:51 -03:00
|
|
|
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:
|
2010-01-18 20:09:57 -04:00
|
|
|
self.assertNotIn(path, seen_paths)
|
2004-06-04 22:12:51 -03:00
|
|
|
seen_paths.add(path)
|
|
|
|
|
2013-12-08 02:20:35 -04:00
|
|
|
@unittest.skip('test not implemented')
|
2004-06-04 22:12:51 -03:00
|
|
|
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):
|
2007-12-02 05:40:06 -04:00
|
|
|
# 'quit' and 'exit' should be injected into builtins
|
2009-06-30 20:06:06 -03:00
|
|
|
self.assertTrue(hasattr(builtins, "quit"))
|
|
|
|
self.assertTrue(hasattr(builtins, "exit"))
|
2004-06-04 22:12:51 -03:00
|
|
|
|
|
|
|
def test_setting_copyright(self):
|
2013-09-07 17:59:17 -03:00
|
|
|
# 'copyright', 'credits', and 'license' should be in builtins
|
2009-06-30 20:06:06 -03:00
|
|
|
self.assertTrue(hasattr(builtins, "copyright"))
|
|
|
|
self.assertTrue(hasattr(builtins, "credits"))
|
2013-09-07 17:59:17 -03:00
|
|
|
self.assertTrue(hasattr(builtins, "license"))
|
2004-06-04 22:12:51 -03:00
|
|
|
|
|
|
|
def test_setting_help(self):
|
2007-12-02 05:40:06 -04:00
|
|
|
# 'help' should be set in builtins
|
2009-06-30 20:06:06 -03:00
|
|
|
self.assertTrue(hasattr(builtins, "help"))
|
2004-06-04 22:12:51 -03:00
|
|
|
|
|
|
|
def test_sitecustomize_executed(self):
|
|
|
|
# If sitecustomize is available, it should have been imported.
|
2006-08-18 19:13:04 -03:00
|
|
|
if "sitecustomize" not in sys.modules:
|
2004-06-04 22:12:51 -03:00
|
|
|
try:
|
|
|
|
import sitecustomize
|
|
|
|
except ImportError:
|
|
|
|
pass
|
|
|
|
else:
|
|
|
|
self.fail("sitecustomize not imported automatically")
|
|
|
|
|
2023-10-18 02:05:41 -03:00
|
|
|
@support.requires_subprocess()
|
|
|
|
def test_customization_modules_on_startup(self):
|
|
|
|
mod_names = [
|
|
|
|
'sitecustomize'
|
|
|
|
]
|
|
|
|
|
|
|
|
if site.ENABLE_USER_SITE:
|
|
|
|
mod_names.append('usercustomize')
|
|
|
|
|
|
|
|
temp_dir = tempfile.mkdtemp()
|
|
|
|
self.addCleanup(os_helper.rmtree, temp_dir)
|
|
|
|
|
|
|
|
with EnvironmentVarGuard() as environ:
|
|
|
|
environ['PYTHONPATH'] = temp_dir
|
|
|
|
|
|
|
|
for module_name in mod_names:
|
|
|
|
os_helper.rmtree(temp_dir)
|
|
|
|
os.mkdir(temp_dir)
|
|
|
|
|
|
|
|
customize_path = os.path.join(temp_dir, f'{module_name}.py')
|
|
|
|
eyecatcher = f'EXECUTED_{module_name}'
|
|
|
|
|
|
|
|
with open(customize_path, 'w') as f:
|
|
|
|
f.write(f'print("{eyecatcher}")')
|
|
|
|
|
|
|
|
output = subprocess.check_output([sys.executable, '-c', '""'])
|
|
|
|
self.assertIn(eyecatcher, output.decode('utf-8'))
|
|
|
|
|
|
|
|
# -S blocks any site-packages
|
|
|
|
output = subprocess.check_output([sys.executable, '-S', '-c', '""'])
|
|
|
|
self.assertNotIn(eyecatcher, output.decode('utf-8'))
|
|
|
|
|
|
|
|
# -s blocks user site-packages
|
|
|
|
if 'usercustomize' == module_name:
|
|
|
|
output = subprocess.check_output([sys.executable, '-s', '-c', '""'])
|
|
|
|
self.assertNotIn(eyecatcher, output.decode('utf-8'))
|
|
|
|
|
|
|
|
|
2014-03-27 03:31:39 -03:00
|
|
|
@unittest.skipUnless(hasattr(urllib.request, "HTTPSHandler"),
|
|
|
|
'need SSL support to download license')
|
2023-09-03 09:21:43 -03:00
|
|
|
@test.support.requires_resource('network')
|
|
|
|
@test.support.system_must_validate_cert
|
2013-09-14 14:28:37 -03:00
|
|
|
def test_license_exists_at_url(self):
|
2014-03-27 03:43:26 -03:00
|
|
|
# This test is a bit fragile since it depends on the format of the
|
2013-09-14 14:28:37 -03:00
|
|
|
# string displayed by license in the absence of a LICENSE file.
|
|
|
|
url = license._Printer__data.split()[1]
|
|
|
|
req = urllib.request.Request(url, method='HEAD')
|
2020-10-05 13:24:00 -03:00
|
|
|
# Reset global urllib.request._opener
|
|
|
|
self.addCleanup(urllib.request.urlcleanup)
|
2013-09-14 14:28:37 -03:00
|
|
|
try:
|
2020-04-29 04:36:20 -03:00
|
|
|
with socket_helper.transient_internet(url):
|
2013-09-14 14:28:37 -03:00
|
|
|
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)
|
2013-09-07 17:59:17 -03:00
|
|
|
|
2004-06-04 22:12:51 -03:00
|
|
|
|
2013-10-11 19:24:55 -03:00
|
|
|
class StartupImportTests(unittest.TestCase):
|
|
|
|
|
2022-01-25 03:09:06 -04:00
|
|
|
@support.requires_subprocess()
|
2013-10-11 19:24:55 -03:00
|
|
|
def test_startup_imports(self):
|
2020-03-18 14:27:32 -03:00
|
|
|
# Get sys.path in isolated mode (python3 -I)
|
2021-12-02 20:08:42 -04:00
|
|
|
popen = subprocess.Popen([sys.executable, '-X', 'utf8', '-I',
|
|
|
|
'-c', 'import sys; print(repr(sys.path))'],
|
2020-03-18 14:27:32 -03:00
|
|
|
stdout=subprocess.PIPE,
|
2021-12-02 20:08:42 -04:00
|
|
|
encoding='utf-8',
|
|
|
|
errors='surrogateescape')
|
2020-03-18 14:27:32 -03:00
|
|
|
stdout = popen.communicate()[0]
|
|
|
|
self.assertEqual(popen.returncode, 0, repr(stdout))
|
2021-12-02 20:08:42 -04:00
|
|
|
isolated_paths = ast.literal_eval(stdout)
|
2020-03-18 14:27:32 -03:00
|
|
|
|
|
|
|
# bpo-27807: Even with -I, the site module executes all .pth files
|
|
|
|
# found in sys.path (see site.addpackage()). Skip the test if at least
|
|
|
|
# one .pth file is found.
|
|
|
|
for path in isolated_paths:
|
2020-06-20 05:10:31 -03:00
|
|
|
pth_files = glob.glob(os.path.join(glob.escape(path), "*.pth"))
|
2020-03-18 14:27:32 -03:00
|
|
|
if pth_files:
|
|
|
|
self.skipTest(f"found {len(pth_files)} .pth files in: {path}")
|
|
|
|
|
2013-10-11 19:24:55 -03:00
|
|
|
# This tests checks which modules are loaded by Python when it
|
|
|
|
# initially starts upon startup.
|
2021-12-02 20:08:42 -04:00
|
|
|
popen = subprocess.Popen([sys.executable, '-X', 'utf8', '-I', '-v',
|
|
|
|
'-c', 'import sys; print(set(sys.modules))'],
|
2013-10-12 07:32:21 -03:00
|
|
|
stdout=subprocess.PIPE,
|
2016-09-17 16:22:41 -03:00
|
|
|
stderr=subprocess.PIPE,
|
2021-12-02 20:08:42 -04:00
|
|
|
encoding='utf-8',
|
|
|
|
errors='surrogateescape')
|
2013-10-12 07:32:21 -03:00
|
|
|
stdout, stderr = popen.communicate()
|
2020-03-18 14:27:32 -03:00
|
|
|
self.assertEqual(popen.returncode, 0, (stdout, stderr))
|
2021-12-02 20:08:42 -04:00
|
|
|
modules = ast.literal_eval(stdout)
|
2013-10-12 07:32:21 -03:00
|
|
|
|
2013-10-11 19:24:55 -03:00
|
|
|
self.assertIn('site', modules)
|
|
|
|
|
2013-10-11 20:27:08 -03:00
|
|
|
# http://bugs.python.org/issue19205
|
2022-04-02 05:35:13 -03:00
|
|
|
re_mods = {'re', '_sre', 're._compiler', 're._constants', 're._parser'}
|
2019-05-05 06:06:30 -03:00
|
|
|
self.assertFalse(modules.intersection(re_mods), stderr)
|
|
|
|
|
2013-10-11 20:27:08 -03:00
|
|
|
# http://bugs.python.org/issue9548
|
2013-10-12 07:32:21 -03:00
|
|
|
self.assertNotIn('locale', modules, stderr)
|
2019-05-05 06:06:30 -03:00
|
|
|
|
|
|
|
# http://bugs.python.org/issue19209
|
|
|
|
self.assertNotIn('copyreg', modules, stderr)
|
|
|
|
|
|
|
|
# http://bugs.python.org/issue19218
|
2013-10-12 21:04:20 -03:00
|
|
|
collection_mods = {'_collections', 'collections', 'functools',
|
|
|
|
'heapq', 'itertools', 'keyword', 'operator',
|
2014-04-15 15:37:54 -03:00
|
|
|
'reprlib', 'types', 'weakref'
|
|
|
|
}.difference(sys.builtin_module_names)
|
2017-07-28 04:02:10 -03:00
|
|
|
self.assertFalse(modules.intersection(collection_mods), stderr)
|
2013-10-11 20:00:51 -03:00
|
|
|
|
2022-01-25 03:09:06 -04:00
|
|
|
@support.requires_subprocess()
|
2016-09-17 18:35:32 -03:00
|
|
|
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")
|
|
|
|
|
2022-01-25 03:09:06 -04:00
|
|
|
@support.requires_subprocess()
|
2016-09-17 18:35:32 -03:00
|
|
|
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")
|
|
|
|
|
2022-01-25 03:09:06 -04:00
|
|
|
@support.requires_subprocess()
|
2016-09-17 18:35:32 -03:00
|
|
|
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()")
|
|
|
|
|
2017-05-14 17:49:46 -03:00
|
|
|
class _pthFileTests(unittest.TestCase):
|
|
|
|
|
2021-12-11 11:06:17 -04:00
|
|
|
if sys.platform == 'win32':
|
|
|
|
def _create_underpth_exe(self, lines, exe_pth=True):
|
|
|
|
import _winapi
|
|
|
|
temp_dir = tempfile.mkdtemp()
|
|
|
|
self.addCleanup(os_helper.rmtree, temp_dir)
|
|
|
|
exe_file = os.path.join(temp_dir, os.path.split(sys.executable)[1])
|
|
|
|
dll_src_file = _winapi.GetModuleFileName(sys.dllhandle)
|
|
|
|
dll_file = os.path.join(temp_dir, os.path.split(dll_src_file)[1])
|
|
|
|
shutil.copy(sys.executable, exe_file)
|
|
|
|
shutil.copy(dll_src_file, dll_file)
|
2022-06-24 07:48:53 -03:00
|
|
|
for fn in glob.glob(os.path.join(os.path.split(dll_src_file)[0], "vcruntime*.dll")):
|
|
|
|
shutil.copy(fn, os.path.join(temp_dir, os.path.split(fn)[1]))
|
2021-12-11 11:06:17 -04:00
|
|
|
if exe_pth:
|
|
|
|
_pth_file = os.path.splitext(exe_file)[0] + '._pth'
|
|
|
|
else:
|
|
|
|
_pth_file = os.path.splitext(dll_file)[0] + '._pth'
|
2023-09-10 19:04:35 -03:00
|
|
|
with open(_pth_file, 'w', encoding='utf8') as f:
|
2021-12-11 11:06:17 -04:00
|
|
|
for line in lines:
|
|
|
|
print(line, file=f)
|
|
|
|
return exe_file
|
|
|
|
else:
|
|
|
|
def _create_underpth_exe(self, lines, exe_pth=True):
|
|
|
|
if not exe_pth:
|
|
|
|
raise unittest.SkipTest("library ._pth file not supported on this platform")
|
|
|
|
temp_dir = tempfile.mkdtemp()
|
|
|
|
self.addCleanup(os_helper.rmtree, temp_dir)
|
|
|
|
exe_file = os.path.join(temp_dir, os.path.split(sys.executable)[1])
|
|
|
|
os.symlink(sys.executable, exe_file)
|
|
|
|
_pth_file = exe_file + '._pth'
|
|
|
|
with open(_pth_file, 'w') as f:
|
|
|
|
for line in lines:
|
|
|
|
print(line, file=f)
|
|
|
|
return exe_file
|
2016-10-29 12:50:31 -03:00
|
|
|
|
2017-02-04 19:19:29 -04:00
|
|
|
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
|
|
|
|
|
2024-01-02 20:30:53 -04:00
|
|
|
def _get_pth_lines(self, libpath: str, *, import_site: bool):
|
|
|
|
pth_lines = ['fake-path-name']
|
|
|
|
# include 200 lines of `libpath` in _pth lines (or fewer
|
|
|
|
# if the `libpath` is long enough to get close to 32KB
|
|
|
|
# see https://github.com/python/cpython/issues/113628)
|
|
|
|
encoded_libpath_length = len(libpath.encode("utf-8"))
|
|
|
|
repetitions = min(200, 30000 // encoded_libpath_length)
|
|
|
|
if repetitions <= 2:
|
|
|
|
self.skipTest(
|
|
|
|
f"Python stdlib path is too long ({encoded_libpath_length:,} bytes)")
|
|
|
|
pth_lines.extend(libpath for _ in range(repetitions))
|
|
|
|
pth_lines.extend(['', '# comment'])
|
|
|
|
if import_site:
|
|
|
|
pth_lines.append('import site')
|
|
|
|
return pth_lines
|
|
|
|
|
2022-01-25 03:09:06 -04:00
|
|
|
@support.requires_subprocess()
|
2021-12-11 09:43:40 -04:00
|
|
|
def test_underpth_basic(self):
|
|
|
|
pth_lines = ['#.', '# ..', *sys.path, '.', '..']
|
|
|
|
exe_file = self._create_underpth_exe(pth_lines)
|
|
|
|
sys_path = self._calc_sys_path_for_underpth_nosite(
|
|
|
|
os.path.dirname(exe_file),
|
|
|
|
pth_lines)
|
|
|
|
|
2023-09-10 19:04:35 -03:00
|
|
|
output = subprocess.check_output([exe_file, '-X', 'utf8', '-c',
|
2021-12-11 09:43:40 -04:00
|
|
|
'import sys; print("\\n".join(sys.path) if sys.flags.no_site else "")'
|
2021-12-11 11:06:17 -04:00
|
|
|
], encoding='utf-8', errors='surrogateescape')
|
2021-12-11 09:43:40 -04:00
|
|
|
actual_sys_path = output.rstrip().split('\n')
|
|
|
|
self.assertTrue(actual_sys_path, "sys.flags.no_site was False")
|
|
|
|
self.assertEqual(
|
|
|
|
actual_sys_path,
|
|
|
|
sys_path,
|
|
|
|
"sys.path is incorrect"
|
|
|
|
)
|
|
|
|
|
2022-01-25 03:09:06 -04:00
|
|
|
@support.requires_subprocess()
|
2016-10-29 12:50:31 -03:00
|
|
|
def test_underpth_nosite_file(self):
|
2021-09-17 19:31:31 -03:00
|
|
|
libpath = test.support.STDLIB_DIR
|
2016-10-29 12:50:31 -03:00
|
|
|
exe_prefix = os.path.dirname(sys.executable)
|
2024-01-02 20:30:53 -04:00
|
|
|
pth_lines = self._get_pth_lines(libpath, import_site=False)
|
2017-02-04 19:19:29 -04:00
|
|
|
exe_file = self._create_underpth_exe(pth_lines)
|
|
|
|
sys_path = self._calc_sys_path_for_underpth_nosite(
|
|
|
|
os.path.dirname(exe_file),
|
|
|
|
pth_lines)
|
2016-10-27 18:28:07 -03:00
|
|
|
|
2017-05-14 17:49:46 -03:00
|
|
|
env = os.environ.copy()
|
|
|
|
env['PYTHONPATH'] = 'from-env'
|
2021-12-11 11:06:17 -04:00
|
|
|
env['PATH'] = '{}{}{}'.format(exe_prefix, os.pathsep, os.getenv('PATH'))
|
2017-05-23 20:25:25 -03:00
|
|
|
output = subprocess.check_output([exe_file, '-c',
|
|
|
|
'import sys; print("\\n".join(sys.path) if sys.flags.no_site else "")'
|
2021-12-11 11:06:17 -04:00
|
|
|
], env=env, encoding='utf-8', errors='surrogateescape')
|
2017-05-23 20:25:25 -03:00
|
|
|
actual_sys_path = output.rstrip().split('\n')
|
2018-02-04 12:14:47 -04:00
|
|
|
self.assertTrue(actual_sys_path, "sys.flags.no_site was False")
|
2017-05-23 20:25:25 -03:00
|
|
|
self.assertEqual(
|
|
|
|
actual_sys_path,
|
|
|
|
sys_path,
|
|
|
|
"sys.path is incorrect"
|
|
|
|
)
|
2016-10-27 18:28:07 -03:00
|
|
|
|
2022-01-25 03:09:06 -04:00
|
|
|
@support.requires_subprocess()
|
2016-10-27 18:28:07 -03:00
|
|
|
def test_underpth_file(self):
|
2021-09-17 19:31:31 -03:00
|
|
|
libpath = test.support.STDLIB_DIR
|
2016-10-29 12:50:31 -03:00
|
|
|
exe_prefix = os.path.dirname(sys.executable)
|
2024-01-02 20:30:53 -04:00
|
|
|
exe_file = self._create_underpth_exe(
|
|
|
|
self._get_pth_lines(libpath, import_site=True))
|
2017-02-04 19:19:29 -04:00
|
|
|
sys_prefix = os.path.dirname(exe_file)
|
2017-05-14 17:49:46 -03:00
|
|
|
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)
|
2017-02-04 19:19:29 -04:00
|
|
|
self.assertTrue(rc, "sys.path is incorrect")
|
2016-10-27 18:28:07 -03:00
|
|
|
|
2022-01-25 03:09:06 -04:00
|
|
|
@support.requires_subprocess()
|
2020-07-15 18:56:49 -03:00
|
|
|
def test_underpth_dll_file(self):
|
2021-09-17 19:31:31 -03:00
|
|
|
libpath = test.support.STDLIB_DIR
|
2020-07-15 18:56:49 -03:00
|
|
|
exe_prefix = os.path.dirname(sys.executable)
|
2024-01-02 20:30:53 -04:00
|
|
|
exe_file = self._create_underpth_exe(
|
|
|
|
self._get_pth_lines(libpath, import_site=True), exe_pth=False)
|
2020-07-15 18:56:49 -03:00
|
|
|
sys_prefix = os.path.dirname(exe_file)
|
|
|
|
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)
|
|
|
|
self.assertTrue(rc, "sys.path is incorrect")
|
|
|
|
|
|
|
|
|
2004-06-04 22:12:51 -03:00
|
|
|
if __name__ == "__main__":
|
2013-06-12 22:25:59 -03:00
|
|
|
unittest.main()
|