Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions Lib/distutils/command/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@

from site import USER_BASE
from site import USER_SITE
HAS_USER_SITE = True

HAS_USER_SITE = (USER_SITE is not None)

WINDOWS_SCHEME = {
'purelib': '$base/Lib/site-packages',
Expand Down Expand Up @@ -169,8 +170,9 @@ def initialize_options(self):
self.install_lib = None # set to either purelib or platlib
self.install_scripts = None
self.install_data = None
self.install_userbase = USER_BASE
self.install_usersite = USER_SITE
if HAS_USER_SITE:
self.install_userbase = USER_BASE
self.install_usersite = USER_SITE

self.compile = None
self.optimize = None
Expand Down Expand Up @@ -343,8 +345,9 @@ def finalize_options(self):
# Convert directories from Unix /-separated syntax to the local
# convention.
self.convert_paths('lib', 'purelib', 'platlib',
'scripts', 'data', 'headers',
'userbase', 'usersite')
'scripts', 'data', 'headers')
if HAS_USER_SITE:
self.convert_paths('userbase', 'usersite')

# Deprecated
# Well, we're not actually fully completely finalized yet: we still
Expand Down
8 changes: 5 additions & 3 deletions Lib/distutils/tests/test_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from test.support import captured_stdout, run_unittest

from distutils import sysconfig
from distutils.command.install import install
from distutils.command.install import install, HAS_USER_SITE
from distutils.command import install as install_module
from distutils.command.build_ext import build_ext
from distutils.command.install import INSTALL_SCHEMES
Expand Down Expand Up @@ -66,6 +66,7 @@ def check_path(got, expected):
check_path(cmd.install_scripts, os.path.join(destination, "bin"))
check_path(cmd.install_data, destination)

@unittest.skipUnless(HAS_USER_SITE, 'need user site')
def test_user_site(self):
# test install with --user
# preparing the environment for the test
Expand Down Expand Up @@ -93,8 +94,9 @@ def cleanup():

self.addCleanup(cleanup)

for key in ('nt_user', 'unix_user'):
self.assertIn(key, INSTALL_SCHEMES)
if HAS_USER_SITE:
for key in ('nt_user', 'unix_user'):
self.assertIn(key, INSTALL_SCHEMES)

dist = Distribution({'name': 'xx'})
cmd = install(dist)
Expand Down
24 changes: 17 additions & 7 deletions Lib/site.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,10 @@ def _getuserbase():
if env_base:
return env_base

# VxWorks has no home directories
if sys.platform == "vxworks":
return None

def joinuser(*args):
return os.path.expanduser(os.path.join(*args))

Expand Down Expand Up @@ -311,11 +315,14 @@ def getusersitepackages():
If the global variable ``USER_SITE`` is not initialized yet, this
function will also set it.
"""
global USER_SITE
global USER_SITE, ENABLE_USER_SITE
userbase = getuserbase() # this will also set USER_BASE

if USER_SITE is None:
USER_SITE = _get_path(userbase)
if userbase is None:
ENABLE_USER_SITE = False # disable user site and return None
else:
USER_SITE = _get_path(userbase)

return USER_SITE

Expand Down Expand Up @@ -630,11 +637,14 @@ def _script():
for dir in sys.path:
print(" %r," % (dir,))
print("]")
print("USER_BASE: %r (%s)" % (user_base,
"exists" if os.path.isdir(user_base) else "doesn't exist"))
print("USER_SITE: %r (%s)" % (user_site,
"exists" if os.path.isdir(user_site) else "doesn't exist"))
print("ENABLE_USER_SITE: %r" % ENABLE_USER_SITE)
def exists(path):
if path is not None and os.path.isdir(path):
return "exists"
else:
return "doesn't exist"
print(f"USER_BASE: {user_base!r} ({exists(user_base)})")
print(f"USER_SITE: {user_site!r} ({exists(user_site)})")
print(f"ENABLE_USER_SITE: {ENABLE_USER_SITE!r}")
sys.exit(0)

buffer = []
Expand Down
115 changes: 64 additions & 51 deletions Lib/sysconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,34 +51,65 @@
'scripts': '{base}/Scripts',
'data': '{base}',
},
# NOTE: When modifying "purelib" scheme, update site._get_path() too.
'nt_user': {
'stdlib': '{userbase}/Python{py_version_nodot_plat}',
'platstdlib': '{userbase}/Python{py_version_nodot_plat}',
'purelib': '{userbase}/Python{py_version_nodot_plat}/site-packages',
'platlib': '{userbase}/Python{py_version_nodot_plat}/site-packages',
'include': '{userbase}/Python{py_version_nodot_plat}/Include',
'scripts': '{userbase}/Python{py_version_nodot_plat}/Scripts',
'data': '{userbase}',
},
'posix_user': {
'stdlib': '{userbase}/{platlibdir}/python{py_version_short}',
'platstdlib': '{userbase}/{platlibdir}/python{py_version_short}',
'purelib': '{userbase}/lib/python{py_version_short}/site-packages',
'platlib': '{userbase}/{platlibdir}/python{py_version_short}/site-packages',
'include': '{userbase}/include/python{py_version_short}',
'scripts': '{userbase}/bin',
'data': '{userbase}',
},
'osx_framework_user': {
'stdlib': '{userbase}/lib/python',
'platstdlib': '{userbase}/lib/python',
'purelib': '{userbase}/lib/python/site-packages',
'platlib': '{userbase}/lib/python/site-packages',
'include': '{userbase}/include',
'scripts': '{userbase}/bin',
'data': '{userbase}',
},
}


# NOTE: site.py has copy of this function.
# Sync it when modify this function.
def _getuserbase():
env_base = os.environ.get("PYTHONUSERBASE", None)
if env_base:
return env_base

# VxWorks has no home directories
if sys.platform == "vxworks":
return None

def joinuser(*args):
return os.path.expanduser(os.path.join(*args))

if os.name == "nt":
base = os.environ.get("APPDATA") or "~"
return joinuser(base, "Python")

if sys.platform == "darwin" and sys._framework:
return joinuser("~", "Library", sys._framework,
"%d.%d" % sys.version_info[:2])

return joinuser("~", ".local")

_HAS_USER_BASE = (_getuserbase() is not None)

if _HAS_USER_BASE:
_INSTALL_SCHEMES |= {
# NOTE: When modifying "purelib" scheme, update site._get_path() too.
'nt_user': {
'stdlib': '{userbase}/Python{py_version_nodot_plat}',
'platstdlib': '{userbase}/Python{py_version_nodot_plat}',
'purelib': '{userbase}/Python{py_version_nodot_plat}/site-packages',
'platlib': '{userbase}/Python{py_version_nodot_plat}/site-packages',
'include': '{userbase}/Python{py_version_nodot_plat}/Include',
'scripts': '{userbase}/Python{py_version_nodot_plat}/Scripts',
'data': '{userbase}',
},
'posix_user': {
'stdlib': '{userbase}/{platlibdir}/python{py_version_short}',
'platstdlib': '{userbase}/{platlibdir}/python{py_version_short}',
'purelib': '{userbase}/lib/python{py_version_short}/site-packages',
'platlib': '{userbase}/{platlibdir}/python{py_version_short}/site-packages',
'include': '{userbase}/include/python{py_version_short}',
'scripts': '{userbase}/bin',
'data': '{userbase}',
},
'osx_framework_user': {
'stdlib': '{userbase}/lib/python',
'platstdlib': '{userbase}/lib/python',
'purelib': '{userbase}/lib/python/site-packages',
'platlib': '{userbase}/lib/python/site-packages',
'include': '{userbase}/include',
'scripts': '{userbase}/bin',
'data': '{userbase}',
},
}

_SCHEME_KEYS = ('stdlib', 'platstdlib', 'purelib', 'platlib', 'include',
Expand Down Expand Up @@ -183,25 +214,6 @@ def _get_default_scheme():
return os.name


# NOTE: site.py has copy of this function.
# Sync it when modify this function.
def _getuserbase():
env_base = os.environ.get("PYTHONUSERBASE", None)
if env_base:
return env_base

def joinuser(*args):
return os.path.expanduser(os.path.join(*args))

if os.name == "nt":
base = os.environ.get("APPDATA") or "~"
return joinuser(base, "Python")

if sys.platform == "darwin" and sys._framework:
return joinuser("~", "Library", sys._framework,
"%d.%d" % sys.version_info[:2])

return joinuser("~", ".local")


def _parse_makefile(filename, vars=None):
Expand Down Expand Up @@ -557,10 +569,11 @@ def get_config_vars(*args):
SO = _CONFIG_VARS.get('EXT_SUFFIX')
if SO is not None:
_CONFIG_VARS['SO'] = SO
# Setting 'userbase' is done below the call to the
# init function to enable using 'get_config_var' in
# the init-function.
_CONFIG_VARS['userbase'] = _getuserbase()
if _HAS_USER_BASE:
# Setting 'userbase' is done below the call to the
# init function to enable using 'get_config_var' in
# the init-function.
_CONFIG_VARS['userbase'] = _getuserbase()

# Always convert srcdir to an absolute path
srcdir = _CONFIG_VARS.get('srcdir', _PROJECT_BASE)
Expand Down
5 changes: 5 additions & 0 deletions Lib/test/test_site.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import site


HAS_USER_SITE = (site.USER_SITE is not None)
OLD_SYS_PATH = None


Expand Down Expand Up @@ -195,6 +196,7 @@ def test_addsitedir(self):
def test__getuserbase(self):
self.assertEqual(site._getuserbase(), sysconfig._getuserbase())

@unittest.skipUnless(HAS_USER_SITE, 'need user site')
def test_get_path(self):
if sys.platform == 'darwin' and sys._framework:
scheme = 'osx_framework_user'
Expand Down Expand Up @@ -244,6 +246,7 @@ def test_s_option(self):
self.assertEqual(rc, 1,
"User base not set by PYTHONUSERBASE")

@unittest.skipUnless(HAS_USER_SITE, 'need user site')
def test_getuserbase(self):
site.USER_BASE = None
user_base = site.getuserbase()
Expand All @@ -261,6 +264,7 @@ def test_getuserbase(self):
self.assertTrue(site.getuserbase().startswith('xoxo'),
site.getuserbase())

@unittest.skipUnless(HAS_USER_SITE, 'need user site')
def test_getusersitepackages(self):
site.USER_SITE = None
site.USER_BASE = None
Expand Down Expand Up @@ -295,6 +299,7 @@ def test_getsitepackages(self):
wanted = os.path.join('xoxo', 'lib', 'site-packages')
self.assertEqual(dirs[1], wanted)

@unittest.skipUnless(HAS_USER_SITE, 'need user site')
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
Expand Down
19 changes: 13 additions & 6 deletions Lib/test/test_sysconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
get_scheme_names, get_config_var, _main)
import _osx_support


HAS_USER_BASE = sysconfig._HAS_USER_BASE


class TestSysConfig(unittest.TestCase):

def setUp(self):
Expand Down Expand Up @@ -230,9 +234,10 @@ def test_get_config_h_filename(self):
self.assertTrue(os.path.isfile(config_h), config_h)

def test_get_scheme_names(self):
wanted = ('nt', 'nt_user', 'osx_framework_user',
'posix_home', 'posix_prefix', 'posix_user')
self.assertEqual(get_scheme_names(), wanted)
wanted = ['nt', 'posix_home', 'posix_prefix']
if HAS_USER_BASE:
wanted.extend(['nt_user', 'osx_framework_user', 'posix_user'])
self.assertEqual(get_scheme_names(), tuple(sorted(wanted)))

@skip_unless_symlink
def test_symlink(self): # Issue 7880
Expand All @@ -244,7 +249,8 @@ def test_user_similar(self):
# Issue #8759: make sure the posix scheme for the users
# is similar to the global posix_prefix one
base = get_config_var('base')
user = get_config_var('userbase')
if HAS_USER_BASE:
user = get_config_var('userbase')
# the global scheme mirrors the distinction between prefix and
# exec-prefix but not the user scheme, so we have to adapt the paths
# before comparing (issue #9100)
Expand All @@ -259,8 +265,9 @@ def test_user_similar(self):
# before comparing
global_path = global_path.replace(sys.base_prefix, sys.prefix)
base = base.replace(sys.base_prefix, sys.prefix)
user_path = get_path(name, 'posix_user')
self.assertEqual(user_path, global_path.replace(base, user, 1))
if HAS_USER_BASE:
user_path = get_path(name, 'posix_user')
self.assertEqual(user_path, global_path.replace(base, user, 1))

def test_main(self):
# just making sure _main() runs and returns things in the stdout
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix site and sysconfig modules for VxWorks RTOS which has no home directories.