Skip to content
Merged
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
89 changes: 68 additions & 21 deletions Lib/site.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
import os
import builtins
import _sitebuiltins
import io

# Prefixes for site-packages; add additional prefixes like /usr/local here
PREFIXES = [sys.prefix, sys.exec_prefix]
Expand All @@ -87,6 +88,11 @@
USER_BASE = None


def _trace(message):
if sys.flags.verbose:
print(message, file=sys.stderr)


def makepath(*paths):
dir = os.path.join(*paths)
try:
Expand All @@ -99,8 +105,15 @@ def makepath(*paths):
def abs_paths():
"""Set all module __file__ and __cached__ attributes to an absolute path"""
for m in set(sys.modules.values()):
if (getattr(getattr(m, '__loader__', None), '__module__', None) not in
('_frozen_importlib', '_frozen_importlib_external')):
loader_module = None
try:
loader_module = m.__loader__.__module__
except AttributeError:
try:
loader_module = m.__spec__.loader.__module__
except AttributeError:
pass
if loader_module not in {'_frozen_importlib', '_frozen_importlib_external'}:
continue # don't mess with a PEP 302-supplied __file__
try:
m.__file__ = os.path.abspath(m.__file__)
Expand Down Expand Up @@ -155,14 +168,19 @@ def addpackage(sitedir, name, known_paths):
else:
reset = False
fullname = os.path.join(sitedir, name)
_trace(f"Processing .pth file: {fullname!r}")
try:
f = open(fullname, "r")
# locale encoding is not ideal especially on Windows. But we have used
# it for a long time. setuptools uses the locale encoding too.
f = io.TextIOWrapper(io.open_code(fullname), encoding="locale")
except OSError:
return
with f:
for n, line in enumerate(f):
if line.startswith("#"):
continue
if line.strip() == "":
continue
try:
if line.startswith(("import ", "import\t")):
exec(line)
Expand All @@ -189,6 +207,7 @@ def addpackage(sitedir, name, known_paths):
def addsitedir(sitedir, known_paths=None):
"""Add 'sitedir' argument to sys.path if missing and handle .pth files in
'sitedir'"""
_trace(f"Adding directory: {sitedir!r}")
if known_paths is None:
known_paths = _init_pathinfo()
reset = True
Expand Down Expand Up @@ -247,6 +266,10 @@ def _getuserbase():
if env_base:
return env_base

# Emscripten, VxWorks, and WASI have no home directories
if sys.platform in {"emscripten", "vxworks", "wasi"}:
return None

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

Expand All @@ -265,9 +288,9 @@ def joinuser(*args):
def _get_path(userbase):
version = sys.version_info

# XXX RUSTPYTHON: we replace pythonx.y with rustpythonx.y
if os.name == 'nt':
return f'{userbase}\\RustPython{version[0]}{version[1]}\\site-packages'
ver_nodot = sys.winver.replace('.', '')
return f'{userbase}\\RustPython{ver_nodot}\\site-packages'

if sys.platform == 'darwin' and sys._framework:
return f'{userbase}/lib/rustpython/site-packages'
Expand All @@ -294,11 +317,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 All @@ -310,6 +336,7 @@ def addusersitepackages(known_paths):
"""
# get the per user site-package path
# this call will also make sure USER_BASE and USER_SITE are set
_trace("Processing user site-packages")
user_site = getusersitepackages()

if ENABLE_USER_SITE and os.path.isdir(user_site):
Expand All @@ -335,17 +362,23 @@ def getsitepackages(prefixes=None):
seen.add(prefix)

if os.sep == '/':
sitepackages.append(os.path.join(prefix, "lib",
# XXX changed for RustPython
"rustpython%d.%d" % sys.version_info[:2],
"site-packages"))
libdirs = [sys.platlibdir]
if sys.platlibdir != "lib":
libdirs.append("lib")

for libdir in libdirs:
path = os.path.join(prefix, libdir,
"python%d.%d" % sys.version_info[:2],
"site-packages")
sitepackages.append(path)
else:
sitepackages.append(prefix)
sitepackages.append(os.path.join(prefix, "lib", "site-packages"))
sitepackages.append(os.path.join(prefix, "Lib", "site-packages"))
return sitepackages

def addsitepackages(known_paths, prefixes=None):
"""Add site-packages to sys.path"""
_trace("Processing global site-packages")
for sitedir in getsitepackages(prefixes):
if os.path.isdir(sitedir):
addsitedir(sitedir, known_paths)
Expand Down Expand Up @@ -382,8 +415,10 @@ def setcopyright():
files, dirs = [], []
# Not all modules are required to have a __file__ attribute. See
# PEP 420 for more details.
if hasattr(os, '__file__'):
here = getattr(sys, '_stdlib_dir', None)
if not here and hasattr(os, '__file__'):
here = os.path.dirname(os.__file__)
if here:
files.extend(["LICENSE.txt", "LICENSE"])
dirs.extend([os.path.join(here, os.pardir), here, os.curdir])
builtins.license = _sitebuiltins._Printer(
Expand Down Expand Up @@ -441,7 +476,16 @@ def register_readline():
readline.read_history_file(history)
except OSError:
pass
atexit.register(readline.write_history_file, history)

def write_history():
try:
readline.write_history_file(history)
except OSError:
# bpo-19891, bpo-41193: Home directory does not exist
# or is not writable, or the filesystem is read-only.
pass

atexit.register(write_history)

sys.__interactivehook__ = register_readline

Expand All @@ -450,7 +494,7 @@ def venv(known_paths):

env = os.environ
if sys.platform == 'darwin' and '__PYVENV_LAUNCHER__' in env:
executable = os.environ['__PYVENV_LAUNCHER__']
executable = sys._base_executable = os.environ['__PYVENV_LAUNCHER__']
else:
executable = sys.executable
exe_dir, _ = os.path.split(os.path.abspath(executable))
Expand Down Expand Up @@ -582,7 +626,7 @@ def _script():
Exit codes with --user-base or --user-site:
0 - user site directory is enabled
1 - user site directory is disabled by user
2 - uses site directory is disabled by super user
2 - user site directory is disabled by super user
or for security reasons
>2 - unknown error
"""
Expand All @@ -594,11 +638,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