xref: /aosp_15_r20/prebuilts/build-tools/common/py3-stdlib/site.py (revision cda5da8d549138a6648c5ee6d7a49cf8f4a657be)
1*cda5da8dSAndroid Build Coastguard Worker"""Append module search paths for third-party packages to sys.path.
2*cda5da8dSAndroid Build Coastguard Worker
3*cda5da8dSAndroid Build Coastguard Worker****************************************************************
4*cda5da8dSAndroid Build Coastguard Worker* This module is automatically imported during initialization. *
5*cda5da8dSAndroid Build Coastguard Worker****************************************************************
6*cda5da8dSAndroid Build Coastguard Worker
7*cda5da8dSAndroid Build Coastguard WorkerThis will append site-specific paths to the module search path.  On
8*cda5da8dSAndroid Build Coastguard WorkerUnix (including Mac OSX), it starts with sys.prefix and
9*cda5da8dSAndroid Build Coastguard Workersys.exec_prefix (if different) and appends
10*cda5da8dSAndroid Build Coastguard Workerlib/python<version>/site-packages.
11*cda5da8dSAndroid Build Coastguard WorkerOn other platforms (such as Windows), it tries each of the
12*cda5da8dSAndroid Build Coastguard Workerprefixes directly, as well as with lib/site-packages appended.  The
13*cda5da8dSAndroid Build Coastguard Workerresulting directories, if they exist, are appended to sys.path, and
14*cda5da8dSAndroid Build Coastguard Workeralso inspected for path configuration files.
15*cda5da8dSAndroid Build Coastguard Worker
16*cda5da8dSAndroid Build Coastguard WorkerIf a file named "pyvenv.cfg" exists one directory above sys.executable,
17*cda5da8dSAndroid Build Coastguard Workersys.prefix and sys.exec_prefix are set to that directory and
18*cda5da8dSAndroid Build Coastguard Workerit is also checked for site-packages (sys.base_prefix and
19*cda5da8dSAndroid Build Coastguard Workersys.base_exec_prefix will always be the "real" prefixes of the Python
20*cda5da8dSAndroid Build Coastguard Workerinstallation). If "pyvenv.cfg" (a bootstrap configuration file) contains
21*cda5da8dSAndroid Build Coastguard Workerthe key "include-system-site-packages" set to anything other than "false"
22*cda5da8dSAndroid Build Coastguard Worker(case-insensitive), the system-level prefixes will still also be
23*cda5da8dSAndroid Build Coastguard Workersearched for site-packages; otherwise they won't.
24*cda5da8dSAndroid Build Coastguard Worker
25*cda5da8dSAndroid Build Coastguard WorkerAll of the resulting site-specific directories, if they exist, are
26*cda5da8dSAndroid Build Coastguard Workerappended to sys.path, and also inspected for path configuration
27*cda5da8dSAndroid Build Coastguard Workerfiles.
28*cda5da8dSAndroid Build Coastguard Worker
29*cda5da8dSAndroid Build Coastguard WorkerA path configuration file is a file whose name has the form
30*cda5da8dSAndroid Build Coastguard Worker<package>.pth; its contents are additional directories (one per line)
31*cda5da8dSAndroid Build Coastguard Workerto be added to sys.path.  Non-existing directories (or
32*cda5da8dSAndroid Build Coastguard Workernon-directories) are never added to sys.path; no directory is added to
33*cda5da8dSAndroid Build Coastguard Workersys.path more than once.  Blank lines and lines beginning with
34*cda5da8dSAndroid Build Coastguard Worker'#' are skipped. Lines starting with 'import' are executed.
35*cda5da8dSAndroid Build Coastguard Worker
36*cda5da8dSAndroid Build Coastguard WorkerFor example, suppose sys.prefix and sys.exec_prefix are set to
37*cda5da8dSAndroid Build Coastguard Worker/usr/local and there is a directory /usr/local/lib/python2.5/site-packages
38*cda5da8dSAndroid Build Coastguard Workerwith three subdirectories, foo, bar and spam, and two path
39*cda5da8dSAndroid Build Coastguard Workerconfiguration files, foo.pth and bar.pth.  Assume foo.pth contains the
40*cda5da8dSAndroid Build Coastguard Workerfollowing:
41*cda5da8dSAndroid Build Coastguard Worker
42*cda5da8dSAndroid Build Coastguard Worker  # foo package configuration
43*cda5da8dSAndroid Build Coastguard Worker  foo
44*cda5da8dSAndroid Build Coastguard Worker  bar
45*cda5da8dSAndroid Build Coastguard Worker  bletch
46*cda5da8dSAndroid Build Coastguard Worker
47*cda5da8dSAndroid Build Coastguard Workerand bar.pth contains:
48*cda5da8dSAndroid Build Coastguard Worker
49*cda5da8dSAndroid Build Coastguard Worker  # bar package configuration
50*cda5da8dSAndroid Build Coastguard Worker  bar
51*cda5da8dSAndroid Build Coastguard Worker
52*cda5da8dSAndroid Build Coastguard WorkerThen the following directories are added to sys.path, in this order:
53*cda5da8dSAndroid Build Coastguard Worker
54*cda5da8dSAndroid Build Coastguard Worker  /usr/local/lib/python2.5/site-packages/bar
55*cda5da8dSAndroid Build Coastguard Worker  /usr/local/lib/python2.5/site-packages/foo
56*cda5da8dSAndroid Build Coastguard Worker
57*cda5da8dSAndroid Build Coastguard WorkerNote that bletch is omitted because it doesn't exist; bar precedes foo
58*cda5da8dSAndroid Build Coastguard Workerbecause bar.pth comes alphabetically before foo.pth; and spam is
59*cda5da8dSAndroid Build Coastguard Workeromitted because it is not mentioned in either path configuration file.
60*cda5da8dSAndroid Build Coastguard Worker
61*cda5da8dSAndroid Build Coastguard WorkerThe readline module is also automatically configured to enable
62*cda5da8dSAndroid Build Coastguard Workercompletion for systems that support it.  This can be overridden in
63*cda5da8dSAndroid Build Coastguard Workersitecustomize, usercustomize or PYTHONSTARTUP.  Starting Python in
64*cda5da8dSAndroid Build Coastguard Workerisolated mode (-I) disables automatic readline configuration.
65*cda5da8dSAndroid Build Coastguard Worker
66*cda5da8dSAndroid Build Coastguard WorkerAfter these operations, an attempt is made to import a module
67*cda5da8dSAndroid Build Coastguard Workernamed sitecustomize, which can perform arbitrary additional
68*cda5da8dSAndroid Build Coastguard Workersite-specific customizations.  If this import fails with an
69*cda5da8dSAndroid Build Coastguard WorkerImportError exception, it is silently ignored.
70*cda5da8dSAndroid Build Coastguard Worker"""
71*cda5da8dSAndroid Build Coastguard Worker
72*cda5da8dSAndroid Build Coastguard Workerimport sys
73*cda5da8dSAndroid Build Coastguard Workerimport os
74*cda5da8dSAndroid Build Coastguard Workerimport builtins
75*cda5da8dSAndroid Build Coastguard Workerimport _sitebuiltins
76*cda5da8dSAndroid Build Coastguard Workerimport io
77*cda5da8dSAndroid Build Coastguard Worker
78*cda5da8dSAndroid Build Coastguard Worker# Prefixes for site-packages; add additional prefixes like /usr/local here
79*cda5da8dSAndroid Build Coastguard WorkerPREFIXES = [sys.prefix, sys.exec_prefix]
80*cda5da8dSAndroid Build Coastguard Worker# Enable per user site-packages directory
81*cda5da8dSAndroid Build Coastguard Worker# set it to False to disable the feature or True to force the feature
82*cda5da8dSAndroid Build Coastguard WorkerENABLE_USER_SITE = None
83*cda5da8dSAndroid Build Coastguard Worker
84*cda5da8dSAndroid Build Coastguard Worker# for distutils.commands.install
85*cda5da8dSAndroid Build Coastguard Worker# These values are initialized by the getuserbase() and getusersitepackages()
86*cda5da8dSAndroid Build Coastguard Worker# functions, through the main() function when Python starts.
87*cda5da8dSAndroid Build Coastguard WorkerUSER_SITE = None
88*cda5da8dSAndroid Build Coastguard WorkerUSER_BASE = None
89*cda5da8dSAndroid Build Coastguard Worker
90*cda5da8dSAndroid Build Coastguard Worker
91*cda5da8dSAndroid Build Coastguard Workerdef _trace(message):
92*cda5da8dSAndroid Build Coastguard Worker    if sys.flags.verbose:
93*cda5da8dSAndroid Build Coastguard Worker        print(message, file=sys.stderr)
94*cda5da8dSAndroid Build Coastguard Worker
95*cda5da8dSAndroid Build Coastguard Worker
96*cda5da8dSAndroid Build Coastguard Workerdef makepath(*paths):
97*cda5da8dSAndroid Build Coastguard Worker    dir = os.path.join(*paths)
98*cda5da8dSAndroid Build Coastguard Worker    try:
99*cda5da8dSAndroid Build Coastguard Worker        dir = os.path.abspath(dir)
100*cda5da8dSAndroid Build Coastguard Worker    except OSError:
101*cda5da8dSAndroid Build Coastguard Worker        pass
102*cda5da8dSAndroid Build Coastguard Worker    return dir, os.path.normcase(dir)
103*cda5da8dSAndroid Build Coastguard Worker
104*cda5da8dSAndroid Build Coastguard Worker
105*cda5da8dSAndroid Build Coastguard Workerdef abs_paths():
106*cda5da8dSAndroid Build Coastguard Worker    """Set all module __file__ and __cached__ attributes to an absolute path"""
107*cda5da8dSAndroid Build Coastguard Worker    for m in set(sys.modules.values()):
108*cda5da8dSAndroid Build Coastguard Worker        loader_module = None
109*cda5da8dSAndroid Build Coastguard Worker        try:
110*cda5da8dSAndroid Build Coastguard Worker            loader_module = m.__loader__.__module__
111*cda5da8dSAndroid Build Coastguard Worker        except AttributeError:
112*cda5da8dSAndroid Build Coastguard Worker            try:
113*cda5da8dSAndroid Build Coastguard Worker                loader_module = m.__spec__.loader.__module__
114*cda5da8dSAndroid Build Coastguard Worker            except AttributeError:
115*cda5da8dSAndroid Build Coastguard Worker                pass
116*cda5da8dSAndroid Build Coastguard Worker        if loader_module not in {'_frozen_importlib', '_frozen_importlib_external'}:
117*cda5da8dSAndroid Build Coastguard Worker            continue   # don't mess with a PEP 302-supplied __file__
118*cda5da8dSAndroid Build Coastguard Worker        try:
119*cda5da8dSAndroid Build Coastguard Worker            m.__file__ = os.path.abspath(m.__file__)
120*cda5da8dSAndroid Build Coastguard Worker        except (AttributeError, OSError, TypeError):
121*cda5da8dSAndroid Build Coastguard Worker            pass
122*cda5da8dSAndroid Build Coastguard Worker        try:
123*cda5da8dSAndroid Build Coastguard Worker            m.__cached__ = os.path.abspath(m.__cached__)
124*cda5da8dSAndroid Build Coastguard Worker        except (AttributeError, OSError, TypeError):
125*cda5da8dSAndroid Build Coastguard Worker            pass
126*cda5da8dSAndroid Build Coastguard Worker
127*cda5da8dSAndroid Build Coastguard Worker
128*cda5da8dSAndroid Build Coastguard Workerdef removeduppaths():
129*cda5da8dSAndroid Build Coastguard Worker    """ Remove duplicate entries from sys.path along with making them
130*cda5da8dSAndroid Build Coastguard Worker    absolute"""
131*cda5da8dSAndroid Build Coastguard Worker    # This ensures that the initial path provided by the interpreter contains
132*cda5da8dSAndroid Build Coastguard Worker    # only absolute pathnames, even if we're running from the build directory.
133*cda5da8dSAndroid Build Coastguard Worker    L = []
134*cda5da8dSAndroid Build Coastguard Worker    known_paths = set()
135*cda5da8dSAndroid Build Coastguard Worker    for dir in sys.path:
136*cda5da8dSAndroid Build Coastguard Worker        # Filter out duplicate paths (on case-insensitive file systems also
137*cda5da8dSAndroid Build Coastguard Worker        # if they only differ in case); turn relative paths into absolute
138*cda5da8dSAndroid Build Coastguard Worker        # paths.
139*cda5da8dSAndroid Build Coastguard Worker        dir, dircase = makepath(dir)
140*cda5da8dSAndroid Build Coastguard Worker        if dircase not in known_paths:
141*cda5da8dSAndroid Build Coastguard Worker            L.append(dir)
142*cda5da8dSAndroid Build Coastguard Worker            known_paths.add(dircase)
143*cda5da8dSAndroid Build Coastguard Worker    sys.path[:] = L
144*cda5da8dSAndroid Build Coastguard Worker    return known_paths
145*cda5da8dSAndroid Build Coastguard Worker
146*cda5da8dSAndroid Build Coastguard Worker
147*cda5da8dSAndroid Build Coastguard Workerdef _init_pathinfo():
148*cda5da8dSAndroid Build Coastguard Worker    """Return a set containing all existing file system items from sys.path."""
149*cda5da8dSAndroid Build Coastguard Worker    d = set()
150*cda5da8dSAndroid Build Coastguard Worker    for item in sys.path:
151*cda5da8dSAndroid Build Coastguard Worker        try:
152*cda5da8dSAndroid Build Coastguard Worker            if os.path.exists(item):
153*cda5da8dSAndroid Build Coastguard Worker                _, itemcase = makepath(item)
154*cda5da8dSAndroid Build Coastguard Worker                d.add(itemcase)
155*cda5da8dSAndroid Build Coastguard Worker        except TypeError:
156*cda5da8dSAndroid Build Coastguard Worker            continue
157*cda5da8dSAndroid Build Coastguard Worker    return d
158*cda5da8dSAndroid Build Coastguard Worker
159*cda5da8dSAndroid Build Coastguard Worker
160*cda5da8dSAndroid Build Coastguard Workerdef addpackage(sitedir, name, known_paths):
161*cda5da8dSAndroid Build Coastguard Worker    """Process a .pth file within the site-packages directory:
162*cda5da8dSAndroid Build Coastguard Worker       For each line in the file, either combine it with sitedir to a path
163*cda5da8dSAndroid Build Coastguard Worker       and add that to known_paths, or execute it if it starts with 'import '.
164*cda5da8dSAndroid Build Coastguard Worker    """
165*cda5da8dSAndroid Build Coastguard Worker    if known_paths is None:
166*cda5da8dSAndroid Build Coastguard Worker        known_paths = _init_pathinfo()
167*cda5da8dSAndroid Build Coastguard Worker        reset = True
168*cda5da8dSAndroid Build Coastguard Worker    else:
169*cda5da8dSAndroid Build Coastguard Worker        reset = False
170*cda5da8dSAndroid Build Coastguard Worker    fullname = os.path.join(sitedir, name)
171*cda5da8dSAndroid Build Coastguard Worker    _trace(f"Processing .pth file: {fullname!r}")
172*cda5da8dSAndroid Build Coastguard Worker    try:
173*cda5da8dSAndroid Build Coastguard Worker        # locale encoding is not ideal especially on Windows. But we have used
174*cda5da8dSAndroid Build Coastguard Worker        # it for a long time. setuptools uses the locale encoding too.
175*cda5da8dSAndroid Build Coastguard Worker        f = io.TextIOWrapper(io.open_code(fullname), encoding="locale")
176*cda5da8dSAndroid Build Coastguard Worker    except OSError:
177*cda5da8dSAndroid Build Coastguard Worker        return
178*cda5da8dSAndroid Build Coastguard Worker    with f:
179*cda5da8dSAndroid Build Coastguard Worker        for n, line in enumerate(f):
180*cda5da8dSAndroid Build Coastguard Worker            if line.startswith("#"):
181*cda5da8dSAndroid Build Coastguard Worker                continue
182*cda5da8dSAndroid Build Coastguard Worker            if line.strip() == "":
183*cda5da8dSAndroid Build Coastguard Worker                continue
184*cda5da8dSAndroid Build Coastguard Worker            try:
185*cda5da8dSAndroid Build Coastguard Worker                if line.startswith(("import ", "import\t")):
186*cda5da8dSAndroid Build Coastguard Worker                    exec(line)
187*cda5da8dSAndroid Build Coastguard Worker                    continue
188*cda5da8dSAndroid Build Coastguard Worker                line = line.rstrip()
189*cda5da8dSAndroid Build Coastguard Worker                dir, dircase = makepath(sitedir, line)
190*cda5da8dSAndroid Build Coastguard Worker                if not dircase in known_paths and os.path.exists(dir):
191*cda5da8dSAndroid Build Coastguard Worker                    sys.path.append(dir)
192*cda5da8dSAndroid Build Coastguard Worker                    known_paths.add(dircase)
193*cda5da8dSAndroid Build Coastguard Worker            except Exception:
194*cda5da8dSAndroid Build Coastguard Worker                print("Error processing line {:d} of {}:\n".format(n+1, fullname),
195*cda5da8dSAndroid Build Coastguard Worker                      file=sys.stderr)
196*cda5da8dSAndroid Build Coastguard Worker                import traceback
197*cda5da8dSAndroid Build Coastguard Worker                for record in traceback.format_exception(*sys.exc_info()):
198*cda5da8dSAndroid Build Coastguard Worker                    for line in record.splitlines():
199*cda5da8dSAndroid Build Coastguard Worker                        print('  '+line, file=sys.stderr)
200*cda5da8dSAndroid Build Coastguard Worker                print("\nRemainder of file ignored", file=sys.stderr)
201*cda5da8dSAndroid Build Coastguard Worker                break
202*cda5da8dSAndroid Build Coastguard Worker    if reset:
203*cda5da8dSAndroid Build Coastguard Worker        known_paths = None
204*cda5da8dSAndroid Build Coastguard Worker    return known_paths
205*cda5da8dSAndroid Build Coastguard Worker
206*cda5da8dSAndroid Build Coastguard Worker
207*cda5da8dSAndroid Build Coastguard Workerdef addsitedir(sitedir, known_paths=None):
208*cda5da8dSAndroid Build Coastguard Worker    """Add 'sitedir' argument to sys.path if missing and handle .pth files in
209*cda5da8dSAndroid Build Coastguard Worker    'sitedir'"""
210*cda5da8dSAndroid Build Coastguard Worker    _trace(f"Adding directory: {sitedir!r}")
211*cda5da8dSAndroid Build Coastguard Worker    if known_paths is None:
212*cda5da8dSAndroid Build Coastguard Worker        known_paths = _init_pathinfo()
213*cda5da8dSAndroid Build Coastguard Worker        reset = True
214*cda5da8dSAndroid Build Coastguard Worker    else:
215*cda5da8dSAndroid Build Coastguard Worker        reset = False
216*cda5da8dSAndroid Build Coastguard Worker    sitedir, sitedircase = makepath(sitedir)
217*cda5da8dSAndroid Build Coastguard Worker    if not sitedircase in known_paths:
218*cda5da8dSAndroid Build Coastguard Worker        sys.path.append(sitedir)        # Add path component
219*cda5da8dSAndroid Build Coastguard Worker        known_paths.add(sitedircase)
220*cda5da8dSAndroid Build Coastguard Worker    try:
221*cda5da8dSAndroid Build Coastguard Worker        names = os.listdir(sitedir)
222*cda5da8dSAndroid Build Coastguard Worker    except OSError:
223*cda5da8dSAndroid Build Coastguard Worker        return
224*cda5da8dSAndroid Build Coastguard Worker    names = [name for name in names if name.endswith(".pth")]
225*cda5da8dSAndroid Build Coastguard Worker    for name in sorted(names):
226*cda5da8dSAndroid Build Coastguard Worker        addpackage(sitedir, name, known_paths)
227*cda5da8dSAndroid Build Coastguard Worker    if reset:
228*cda5da8dSAndroid Build Coastguard Worker        known_paths = None
229*cda5da8dSAndroid Build Coastguard Worker    return known_paths
230*cda5da8dSAndroid Build Coastguard Worker
231*cda5da8dSAndroid Build Coastguard Worker
232*cda5da8dSAndroid Build Coastguard Workerdef check_enableusersite():
233*cda5da8dSAndroid Build Coastguard Worker    """Check if user site directory is safe for inclusion
234*cda5da8dSAndroid Build Coastguard Worker
235*cda5da8dSAndroid Build Coastguard Worker    The function tests for the command line flag (including environment var),
236*cda5da8dSAndroid Build Coastguard Worker    process uid/gid equal to effective uid/gid.
237*cda5da8dSAndroid Build Coastguard Worker
238*cda5da8dSAndroid Build Coastguard Worker    None: Disabled for security reasons
239*cda5da8dSAndroid Build Coastguard Worker    False: Disabled by user (command line option)
240*cda5da8dSAndroid Build Coastguard Worker    True: Safe and enabled
241*cda5da8dSAndroid Build Coastguard Worker    """
242*cda5da8dSAndroid Build Coastguard Worker    if sys.flags.no_user_site:
243*cda5da8dSAndroid Build Coastguard Worker        return False
244*cda5da8dSAndroid Build Coastguard Worker
245*cda5da8dSAndroid Build Coastguard Worker    if hasattr(os, "getuid") and hasattr(os, "geteuid"):
246*cda5da8dSAndroid Build Coastguard Worker        # check process uid == effective uid
247*cda5da8dSAndroid Build Coastguard Worker        if os.geteuid() != os.getuid():
248*cda5da8dSAndroid Build Coastguard Worker            return None
249*cda5da8dSAndroid Build Coastguard Worker    if hasattr(os, "getgid") and hasattr(os, "getegid"):
250*cda5da8dSAndroid Build Coastguard Worker        # check process gid == effective gid
251*cda5da8dSAndroid Build Coastguard Worker        if os.getegid() != os.getgid():
252*cda5da8dSAndroid Build Coastguard Worker            return None
253*cda5da8dSAndroid Build Coastguard Worker
254*cda5da8dSAndroid Build Coastguard Worker    return True
255*cda5da8dSAndroid Build Coastguard Worker
256*cda5da8dSAndroid Build Coastguard Worker
257*cda5da8dSAndroid Build Coastguard Worker# NOTE: sysconfig and it's dependencies are relatively large but site module
258*cda5da8dSAndroid Build Coastguard Worker# needs very limited part of them.
259*cda5da8dSAndroid Build Coastguard Worker# To speedup startup time, we have copy of them.
260*cda5da8dSAndroid Build Coastguard Worker#
261*cda5da8dSAndroid Build Coastguard Worker# See https://bugs.python.org/issue29585
262*cda5da8dSAndroid Build Coastguard Worker
263*cda5da8dSAndroid Build Coastguard Worker# Copy of sysconfig._getuserbase()
264*cda5da8dSAndroid Build Coastguard Workerdef _getuserbase():
265*cda5da8dSAndroid Build Coastguard Worker    env_base = os.environ.get("PYTHONUSERBASE", None)
266*cda5da8dSAndroid Build Coastguard Worker    if env_base:
267*cda5da8dSAndroid Build Coastguard Worker        return env_base
268*cda5da8dSAndroid Build Coastguard Worker
269*cda5da8dSAndroid Build Coastguard Worker    # Emscripten, VxWorks, and WASI have no home directories
270*cda5da8dSAndroid Build Coastguard Worker    if sys.platform in {"emscripten", "vxworks", "wasi"}:
271*cda5da8dSAndroid Build Coastguard Worker        return None
272*cda5da8dSAndroid Build Coastguard Worker
273*cda5da8dSAndroid Build Coastguard Worker    def joinuser(*args):
274*cda5da8dSAndroid Build Coastguard Worker        return os.path.expanduser(os.path.join(*args))
275*cda5da8dSAndroid Build Coastguard Worker
276*cda5da8dSAndroid Build Coastguard Worker    if os.name == "nt":
277*cda5da8dSAndroid Build Coastguard Worker        base = os.environ.get("APPDATA") or "~"
278*cda5da8dSAndroid Build Coastguard Worker        return joinuser(base, "Python")
279*cda5da8dSAndroid Build Coastguard Worker
280*cda5da8dSAndroid Build Coastguard Worker    if sys.platform == "darwin" and sys._framework:
281*cda5da8dSAndroid Build Coastguard Worker        return joinuser("~", "Library", sys._framework,
282*cda5da8dSAndroid Build Coastguard Worker                        "%d.%d" % sys.version_info[:2])
283*cda5da8dSAndroid Build Coastguard Worker
284*cda5da8dSAndroid Build Coastguard Worker    return joinuser("~", ".local")
285*cda5da8dSAndroid Build Coastguard Worker
286*cda5da8dSAndroid Build Coastguard Worker
287*cda5da8dSAndroid Build Coastguard Worker# Same to sysconfig.get_path('purelib', os.name+'_user')
288*cda5da8dSAndroid Build Coastguard Workerdef _get_path(userbase):
289*cda5da8dSAndroid Build Coastguard Worker    version = sys.version_info
290*cda5da8dSAndroid Build Coastguard Worker
291*cda5da8dSAndroid Build Coastguard Worker    if os.name == 'nt':
292*cda5da8dSAndroid Build Coastguard Worker        ver_nodot = sys.winver.replace('.', '')
293*cda5da8dSAndroid Build Coastguard Worker        return f'{userbase}\\Python{ver_nodot}\\site-packages'
294*cda5da8dSAndroid Build Coastguard Worker
295*cda5da8dSAndroid Build Coastguard Worker    if sys.platform == 'darwin' and sys._framework:
296*cda5da8dSAndroid Build Coastguard Worker        return f'{userbase}/lib/python/site-packages'
297*cda5da8dSAndroid Build Coastguard Worker
298*cda5da8dSAndroid Build Coastguard Worker    return f'{userbase}/lib/python{version[0]}.{version[1]}/site-packages'
299*cda5da8dSAndroid Build Coastguard Worker
300*cda5da8dSAndroid Build Coastguard Worker
301*cda5da8dSAndroid Build Coastguard Workerdef getuserbase():
302*cda5da8dSAndroid Build Coastguard Worker    """Returns the `user base` directory path.
303*cda5da8dSAndroid Build Coastguard Worker
304*cda5da8dSAndroid Build Coastguard Worker    The `user base` directory can be used to store data. If the global
305*cda5da8dSAndroid Build Coastguard Worker    variable ``USER_BASE`` is not initialized yet, this function will also set
306*cda5da8dSAndroid Build Coastguard Worker    it.
307*cda5da8dSAndroid Build Coastguard Worker    """
308*cda5da8dSAndroid Build Coastguard Worker    global USER_BASE
309*cda5da8dSAndroid Build Coastguard Worker    if USER_BASE is None:
310*cda5da8dSAndroid Build Coastguard Worker        USER_BASE = _getuserbase()
311*cda5da8dSAndroid Build Coastguard Worker    return USER_BASE
312*cda5da8dSAndroid Build Coastguard Worker
313*cda5da8dSAndroid Build Coastguard Worker
314*cda5da8dSAndroid Build Coastguard Workerdef getusersitepackages():
315*cda5da8dSAndroid Build Coastguard Worker    """Returns the user-specific site-packages directory path.
316*cda5da8dSAndroid Build Coastguard Worker
317*cda5da8dSAndroid Build Coastguard Worker    If the global variable ``USER_SITE`` is not initialized yet, this
318*cda5da8dSAndroid Build Coastguard Worker    function will also set it.
319*cda5da8dSAndroid Build Coastguard Worker    """
320*cda5da8dSAndroid Build Coastguard Worker    global USER_SITE, ENABLE_USER_SITE
321*cda5da8dSAndroid Build Coastguard Worker    userbase = getuserbase() # this will also set USER_BASE
322*cda5da8dSAndroid Build Coastguard Worker
323*cda5da8dSAndroid Build Coastguard Worker    if USER_SITE is None:
324*cda5da8dSAndroid Build Coastguard Worker        if userbase is None:
325*cda5da8dSAndroid Build Coastguard Worker            ENABLE_USER_SITE = False # disable user site and return None
326*cda5da8dSAndroid Build Coastguard Worker        else:
327*cda5da8dSAndroid Build Coastguard Worker            USER_SITE = _get_path(userbase)
328*cda5da8dSAndroid Build Coastguard Worker
329*cda5da8dSAndroid Build Coastguard Worker    return USER_SITE
330*cda5da8dSAndroid Build Coastguard Worker
331*cda5da8dSAndroid Build Coastguard Workerdef addusersitepackages(known_paths):
332*cda5da8dSAndroid Build Coastguard Worker    """Add a per user site-package to sys.path
333*cda5da8dSAndroid Build Coastguard Worker
334*cda5da8dSAndroid Build Coastguard Worker    Each user has its own python directory with site-packages in the
335*cda5da8dSAndroid Build Coastguard Worker    home directory.
336*cda5da8dSAndroid Build Coastguard Worker    """
337*cda5da8dSAndroid Build Coastguard Worker    # get the per user site-package path
338*cda5da8dSAndroid Build Coastguard Worker    # this call will also make sure USER_BASE and USER_SITE are set
339*cda5da8dSAndroid Build Coastguard Worker    _trace("Processing user site-packages")
340*cda5da8dSAndroid Build Coastguard Worker    user_site = getusersitepackages()
341*cda5da8dSAndroid Build Coastguard Worker
342*cda5da8dSAndroid Build Coastguard Worker    if ENABLE_USER_SITE and os.path.isdir(user_site):
343*cda5da8dSAndroid Build Coastguard Worker        addsitedir(user_site, known_paths)
344*cda5da8dSAndroid Build Coastguard Worker    return known_paths
345*cda5da8dSAndroid Build Coastguard Worker
346*cda5da8dSAndroid Build Coastguard Workerdef getsitepackages(prefixes=None):
347*cda5da8dSAndroid Build Coastguard Worker    """Returns a list containing all global site-packages directories.
348*cda5da8dSAndroid Build Coastguard Worker
349*cda5da8dSAndroid Build Coastguard Worker    For each directory present in ``prefixes`` (or the global ``PREFIXES``),
350*cda5da8dSAndroid Build Coastguard Worker    this function will find its `site-packages` subdirectory depending on the
351*cda5da8dSAndroid Build Coastguard Worker    system environment, and will return a list of full paths.
352*cda5da8dSAndroid Build Coastguard Worker    """
353*cda5da8dSAndroid Build Coastguard Worker    sitepackages = []
354*cda5da8dSAndroid Build Coastguard Worker    seen = set()
355*cda5da8dSAndroid Build Coastguard Worker
356*cda5da8dSAndroid Build Coastguard Worker    if prefixes is None:
357*cda5da8dSAndroid Build Coastguard Worker        prefixes = PREFIXES
358*cda5da8dSAndroid Build Coastguard Worker
359*cda5da8dSAndroid Build Coastguard Worker    for prefix in prefixes:
360*cda5da8dSAndroid Build Coastguard Worker        if not prefix or prefix in seen:
361*cda5da8dSAndroid Build Coastguard Worker            continue
362*cda5da8dSAndroid Build Coastguard Worker        seen.add(prefix)
363*cda5da8dSAndroid Build Coastguard Worker
364*cda5da8dSAndroid Build Coastguard Worker        if os.sep == '/':
365*cda5da8dSAndroid Build Coastguard Worker            libdirs = [sys.platlibdir]
366*cda5da8dSAndroid Build Coastguard Worker            if sys.platlibdir != "lib":
367*cda5da8dSAndroid Build Coastguard Worker                libdirs.append("lib")
368*cda5da8dSAndroid Build Coastguard Worker
369*cda5da8dSAndroid Build Coastguard Worker            for libdir in libdirs:
370*cda5da8dSAndroid Build Coastguard Worker                path = os.path.join(prefix, libdir,
371*cda5da8dSAndroid Build Coastguard Worker                                    "python%d.%d" % sys.version_info[:2],
372*cda5da8dSAndroid Build Coastguard Worker                                    "site-packages")
373*cda5da8dSAndroid Build Coastguard Worker                sitepackages.append(path)
374*cda5da8dSAndroid Build Coastguard Worker        else:
375*cda5da8dSAndroid Build Coastguard Worker            sitepackages.append(prefix)
376*cda5da8dSAndroid Build Coastguard Worker            sitepackages.append(os.path.join(prefix, "Lib", "site-packages"))
377*cda5da8dSAndroid Build Coastguard Worker    return sitepackages
378*cda5da8dSAndroid Build Coastguard Worker
379*cda5da8dSAndroid Build Coastguard Workerdef addsitepackages(known_paths, prefixes=None):
380*cda5da8dSAndroid Build Coastguard Worker    """Add site-packages to sys.path"""
381*cda5da8dSAndroid Build Coastguard Worker    _trace("Processing global site-packages")
382*cda5da8dSAndroid Build Coastguard Worker    for sitedir in getsitepackages(prefixes):
383*cda5da8dSAndroid Build Coastguard Worker        if os.path.isdir(sitedir):
384*cda5da8dSAndroid Build Coastguard Worker            addsitedir(sitedir, known_paths)
385*cda5da8dSAndroid Build Coastguard Worker
386*cda5da8dSAndroid Build Coastguard Worker    return known_paths
387*cda5da8dSAndroid Build Coastguard Worker
388*cda5da8dSAndroid Build Coastguard Workerdef setquit():
389*cda5da8dSAndroid Build Coastguard Worker    """Define new builtins 'quit' and 'exit'.
390*cda5da8dSAndroid Build Coastguard Worker
391*cda5da8dSAndroid Build Coastguard Worker    These are objects which make the interpreter exit when called.
392*cda5da8dSAndroid Build Coastguard Worker    The repr of each object contains a hint at how it works.
393*cda5da8dSAndroid Build Coastguard Worker
394*cda5da8dSAndroid Build Coastguard Worker    """
395*cda5da8dSAndroid Build Coastguard Worker    if os.sep == '\\':
396*cda5da8dSAndroid Build Coastguard Worker        eof = 'Ctrl-Z plus Return'
397*cda5da8dSAndroid Build Coastguard Worker    else:
398*cda5da8dSAndroid Build Coastguard Worker        eof = 'Ctrl-D (i.e. EOF)'
399*cda5da8dSAndroid Build Coastguard Worker
400*cda5da8dSAndroid Build Coastguard Worker    builtins.quit = _sitebuiltins.Quitter('quit', eof)
401*cda5da8dSAndroid Build Coastguard Worker    builtins.exit = _sitebuiltins.Quitter('exit', eof)
402*cda5da8dSAndroid Build Coastguard Worker
403*cda5da8dSAndroid Build Coastguard Worker
404*cda5da8dSAndroid Build Coastguard Workerdef setcopyright():
405*cda5da8dSAndroid Build Coastguard Worker    """Set 'copyright' and 'credits' in builtins"""
406*cda5da8dSAndroid Build Coastguard Worker    builtins.copyright = _sitebuiltins._Printer("copyright", sys.copyright)
407*cda5da8dSAndroid Build Coastguard Worker    if sys.platform[:4] == 'java':
408*cda5da8dSAndroid Build Coastguard Worker        builtins.credits = _sitebuiltins._Printer(
409*cda5da8dSAndroid Build Coastguard Worker            "credits",
410*cda5da8dSAndroid Build Coastguard Worker            "Jython is maintained by the Jython developers (www.jython.org).")
411*cda5da8dSAndroid Build Coastguard Worker    else:
412*cda5da8dSAndroid Build Coastguard Worker        builtins.credits = _sitebuiltins._Printer("credits", """\
413*cda5da8dSAndroid Build Coastguard Worker    Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
414*cda5da8dSAndroid Build Coastguard Worker    for supporting Python development.  See www.python.org for more information.""")
415*cda5da8dSAndroid Build Coastguard Worker    files, dirs = [], []
416*cda5da8dSAndroid Build Coastguard Worker    # Not all modules are required to have a __file__ attribute.  See
417*cda5da8dSAndroid Build Coastguard Worker    # PEP 420 for more details.
418*cda5da8dSAndroid Build Coastguard Worker    here = getattr(sys, '_stdlib_dir', None)
419*cda5da8dSAndroid Build Coastguard Worker    if not here and hasattr(os, '__file__'):
420*cda5da8dSAndroid Build Coastguard Worker        here = os.path.dirname(os.__file__)
421*cda5da8dSAndroid Build Coastguard Worker    if here:
422*cda5da8dSAndroid Build Coastguard Worker        files.extend(["LICENSE.txt", "LICENSE"])
423*cda5da8dSAndroid Build Coastguard Worker        dirs.extend([os.path.join(here, os.pardir), here, os.curdir])
424*cda5da8dSAndroid Build Coastguard Worker    builtins.license = _sitebuiltins._Printer(
425*cda5da8dSAndroid Build Coastguard Worker        "license",
426*cda5da8dSAndroid Build Coastguard Worker        "See https://www.python.org/psf/license/",
427*cda5da8dSAndroid Build Coastguard Worker        files, dirs)
428*cda5da8dSAndroid Build Coastguard Worker
429*cda5da8dSAndroid Build Coastguard Worker
430*cda5da8dSAndroid Build Coastguard Workerdef sethelper():
431*cda5da8dSAndroid Build Coastguard Worker    builtins.help = _sitebuiltins._Helper()
432*cda5da8dSAndroid Build Coastguard Worker
433*cda5da8dSAndroid Build Coastguard Workerdef enablerlcompleter():
434*cda5da8dSAndroid Build Coastguard Worker    """Enable default readline configuration on interactive prompts, by
435*cda5da8dSAndroid Build Coastguard Worker    registering a sys.__interactivehook__.
436*cda5da8dSAndroid Build Coastguard Worker
437*cda5da8dSAndroid Build Coastguard Worker    If the readline module can be imported, the hook will set the Tab key
438*cda5da8dSAndroid Build Coastguard Worker    as completion key and register ~/.python_history as history file.
439*cda5da8dSAndroid Build Coastguard Worker    This can be overridden in the sitecustomize or usercustomize module,
440*cda5da8dSAndroid Build Coastguard Worker    or in a PYTHONSTARTUP file.
441*cda5da8dSAndroid Build Coastguard Worker    """
442*cda5da8dSAndroid Build Coastguard Worker    def register_readline():
443*cda5da8dSAndroid Build Coastguard Worker        import atexit
444*cda5da8dSAndroid Build Coastguard Worker        try:
445*cda5da8dSAndroid Build Coastguard Worker            import readline
446*cda5da8dSAndroid Build Coastguard Worker            import rlcompleter
447*cda5da8dSAndroid Build Coastguard Worker        except ImportError:
448*cda5da8dSAndroid Build Coastguard Worker            return
449*cda5da8dSAndroid Build Coastguard Worker
450*cda5da8dSAndroid Build Coastguard Worker        # Reading the initialization (config) file may not be enough to set a
451*cda5da8dSAndroid Build Coastguard Worker        # completion key, so we set one first and then read the file.
452*cda5da8dSAndroid Build Coastguard Worker        readline_doc = getattr(readline, '__doc__', '')
453*cda5da8dSAndroid Build Coastguard Worker        if readline_doc is not None and 'libedit' in readline_doc:
454*cda5da8dSAndroid Build Coastguard Worker            readline.parse_and_bind('bind ^I rl_complete')
455*cda5da8dSAndroid Build Coastguard Worker        else:
456*cda5da8dSAndroid Build Coastguard Worker            readline.parse_and_bind('tab: complete')
457*cda5da8dSAndroid Build Coastguard Worker
458*cda5da8dSAndroid Build Coastguard Worker        try:
459*cda5da8dSAndroid Build Coastguard Worker            readline.read_init_file()
460*cda5da8dSAndroid Build Coastguard Worker        except OSError:
461*cda5da8dSAndroid Build Coastguard Worker            # An OSError here could have many causes, but the most likely one
462*cda5da8dSAndroid Build Coastguard Worker            # is that there's no .inputrc file (or .editrc file in the case of
463*cda5da8dSAndroid Build Coastguard Worker            # Mac OS X + libedit) in the expected location.  In that case, we
464*cda5da8dSAndroid Build Coastguard Worker            # want to ignore the exception.
465*cda5da8dSAndroid Build Coastguard Worker            pass
466*cda5da8dSAndroid Build Coastguard Worker
467*cda5da8dSAndroid Build Coastguard Worker        if readline.get_current_history_length() == 0:
468*cda5da8dSAndroid Build Coastguard Worker            # If no history was loaded, default to .python_history.
469*cda5da8dSAndroid Build Coastguard Worker            # The guard is necessary to avoid doubling history size at
470*cda5da8dSAndroid Build Coastguard Worker            # each interpreter exit when readline was already configured
471*cda5da8dSAndroid Build Coastguard Worker            # through a PYTHONSTARTUP hook, see:
472*cda5da8dSAndroid Build Coastguard Worker            # http://bugs.python.org/issue5845#msg198636
473*cda5da8dSAndroid Build Coastguard Worker            history = os.path.join(os.path.expanduser('~'),
474*cda5da8dSAndroid Build Coastguard Worker                                   '.python_history')
475*cda5da8dSAndroid Build Coastguard Worker            try:
476*cda5da8dSAndroid Build Coastguard Worker                readline.read_history_file(history)
477*cda5da8dSAndroid Build Coastguard Worker            except OSError:
478*cda5da8dSAndroid Build Coastguard Worker                pass
479*cda5da8dSAndroid Build Coastguard Worker
480*cda5da8dSAndroid Build Coastguard Worker            def write_history():
481*cda5da8dSAndroid Build Coastguard Worker                try:
482*cda5da8dSAndroid Build Coastguard Worker                    readline.write_history_file(history)
483*cda5da8dSAndroid Build Coastguard Worker                except OSError:
484*cda5da8dSAndroid Build Coastguard Worker                    # bpo-19891, bpo-41193: Home directory does not exist
485*cda5da8dSAndroid Build Coastguard Worker                    # or is not writable, or the filesystem is read-only.
486*cda5da8dSAndroid Build Coastguard Worker                    pass
487*cda5da8dSAndroid Build Coastguard Worker
488*cda5da8dSAndroid Build Coastguard Worker            atexit.register(write_history)
489*cda5da8dSAndroid Build Coastguard Worker
490*cda5da8dSAndroid Build Coastguard Worker    sys.__interactivehook__ = register_readline
491*cda5da8dSAndroid Build Coastguard Worker
492*cda5da8dSAndroid Build Coastguard Workerdef venv(known_paths):
493*cda5da8dSAndroid Build Coastguard Worker    global PREFIXES, ENABLE_USER_SITE
494*cda5da8dSAndroid Build Coastguard Worker
495*cda5da8dSAndroid Build Coastguard Worker    env = os.environ
496*cda5da8dSAndroid Build Coastguard Worker    if sys.platform == 'darwin' and '__PYVENV_LAUNCHER__' in env:
497*cda5da8dSAndroid Build Coastguard Worker        executable = sys._base_executable = os.environ['__PYVENV_LAUNCHER__']
498*cda5da8dSAndroid Build Coastguard Worker    else:
499*cda5da8dSAndroid Build Coastguard Worker        executable = sys.executable
500*cda5da8dSAndroid Build Coastguard Worker    exe_dir, _ = os.path.split(os.path.abspath(executable))
501*cda5da8dSAndroid Build Coastguard Worker    site_prefix = os.path.dirname(exe_dir)
502*cda5da8dSAndroid Build Coastguard Worker    sys._home = None
503*cda5da8dSAndroid Build Coastguard Worker    conf_basename = 'pyvenv.cfg'
504*cda5da8dSAndroid Build Coastguard Worker    candidate_confs = [
505*cda5da8dSAndroid Build Coastguard Worker        conffile for conffile in (
506*cda5da8dSAndroid Build Coastguard Worker            os.path.join(exe_dir, conf_basename),
507*cda5da8dSAndroid Build Coastguard Worker            os.path.join(site_prefix, conf_basename)
508*cda5da8dSAndroid Build Coastguard Worker            )
509*cda5da8dSAndroid Build Coastguard Worker        if os.path.isfile(conffile)
510*cda5da8dSAndroid Build Coastguard Worker        ]
511*cda5da8dSAndroid Build Coastguard Worker
512*cda5da8dSAndroid Build Coastguard Worker    if candidate_confs:
513*cda5da8dSAndroid Build Coastguard Worker        virtual_conf = candidate_confs[0]
514*cda5da8dSAndroid Build Coastguard Worker        system_site = "true"
515*cda5da8dSAndroid Build Coastguard Worker        # Issue 25185: Use UTF-8, as that's what the venv module uses when
516*cda5da8dSAndroid Build Coastguard Worker        # writing the file.
517*cda5da8dSAndroid Build Coastguard Worker        with open(virtual_conf, encoding='utf-8') as f:
518*cda5da8dSAndroid Build Coastguard Worker            for line in f:
519*cda5da8dSAndroid Build Coastguard Worker                if '=' in line:
520*cda5da8dSAndroid Build Coastguard Worker                    key, _, value = line.partition('=')
521*cda5da8dSAndroid Build Coastguard Worker                    key = key.strip().lower()
522*cda5da8dSAndroid Build Coastguard Worker                    value = value.strip()
523*cda5da8dSAndroid Build Coastguard Worker                    if key == 'include-system-site-packages':
524*cda5da8dSAndroid Build Coastguard Worker                        system_site = value.lower()
525*cda5da8dSAndroid Build Coastguard Worker                    elif key == 'home':
526*cda5da8dSAndroid Build Coastguard Worker                        sys._home = value
527*cda5da8dSAndroid Build Coastguard Worker
528*cda5da8dSAndroid Build Coastguard Worker        sys.prefix = sys.exec_prefix = site_prefix
529*cda5da8dSAndroid Build Coastguard Worker
530*cda5da8dSAndroid Build Coastguard Worker        # Doing this here ensures venv takes precedence over user-site
531*cda5da8dSAndroid Build Coastguard Worker        addsitepackages(known_paths, [sys.prefix])
532*cda5da8dSAndroid Build Coastguard Worker
533*cda5da8dSAndroid Build Coastguard Worker        # addsitepackages will process site_prefix again if its in PREFIXES,
534*cda5da8dSAndroid Build Coastguard Worker        # but that's ok; known_paths will prevent anything being added twice
535*cda5da8dSAndroid Build Coastguard Worker        if system_site == "true":
536*cda5da8dSAndroid Build Coastguard Worker            PREFIXES.insert(0, sys.prefix)
537*cda5da8dSAndroid Build Coastguard Worker        else:
538*cda5da8dSAndroid Build Coastguard Worker            PREFIXES = [sys.prefix]
539*cda5da8dSAndroid Build Coastguard Worker            ENABLE_USER_SITE = False
540*cda5da8dSAndroid Build Coastguard Worker
541*cda5da8dSAndroid Build Coastguard Worker    return known_paths
542*cda5da8dSAndroid Build Coastguard Worker
543*cda5da8dSAndroid Build Coastguard Worker
544*cda5da8dSAndroid Build Coastguard Workerdef execsitecustomize():
545*cda5da8dSAndroid Build Coastguard Worker    """Run custom site specific code, if available."""
546*cda5da8dSAndroid Build Coastguard Worker    try:
547*cda5da8dSAndroid Build Coastguard Worker        try:
548*cda5da8dSAndroid Build Coastguard Worker            import sitecustomize
549*cda5da8dSAndroid Build Coastguard Worker        except ImportError as exc:
550*cda5da8dSAndroid Build Coastguard Worker            if exc.name == 'sitecustomize':
551*cda5da8dSAndroid Build Coastguard Worker                pass
552*cda5da8dSAndroid Build Coastguard Worker            else:
553*cda5da8dSAndroid Build Coastguard Worker                raise
554*cda5da8dSAndroid Build Coastguard Worker    except Exception as err:
555*cda5da8dSAndroid Build Coastguard Worker        if sys.flags.verbose:
556*cda5da8dSAndroid Build Coastguard Worker            sys.excepthook(*sys.exc_info())
557*cda5da8dSAndroid Build Coastguard Worker        else:
558*cda5da8dSAndroid Build Coastguard Worker            sys.stderr.write(
559*cda5da8dSAndroid Build Coastguard Worker                "Error in sitecustomize; set PYTHONVERBOSE for traceback:\n"
560*cda5da8dSAndroid Build Coastguard Worker                "%s: %s\n" %
561*cda5da8dSAndroid Build Coastguard Worker                (err.__class__.__name__, err))
562*cda5da8dSAndroid Build Coastguard Worker
563*cda5da8dSAndroid Build Coastguard Worker
564*cda5da8dSAndroid Build Coastguard Workerdef execusercustomize():
565*cda5da8dSAndroid Build Coastguard Worker    """Run custom user specific code, if available."""
566*cda5da8dSAndroid Build Coastguard Worker    try:
567*cda5da8dSAndroid Build Coastguard Worker        try:
568*cda5da8dSAndroid Build Coastguard Worker            import usercustomize
569*cda5da8dSAndroid Build Coastguard Worker        except ImportError as exc:
570*cda5da8dSAndroid Build Coastguard Worker            if exc.name == 'usercustomize':
571*cda5da8dSAndroid Build Coastguard Worker                pass
572*cda5da8dSAndroid Build Coastguard Worker            else:
573*cda5da8dSAndroid Build Coastguard Worker                raise
574*cda5da8dSAndroid Build Coastguard Worker    except Exception as err:
575*cda5da8dSAndroid Build Coastguard Worker        if sys.flags.verbose:
576*cda5da8dSAndroid Build Coastguard Worker            sys.excepthook(*sys.exc_info())
577*cda5da8dSAndroid Build Coastguard Worker        else:
578*cda5da8dSAndroid Build Coastguard Worker            sys.stderr.write(
579*cda5da8dSAndroid Build Coastguard Worker                "Error in usercustomize; set PYTHONVERBOSE for traceback:\n"
580*cda5da8dSAndroid Build Coastguard Worker                "%s: %s\n" %
581*cda5da8dSAndroid Build Coastguard Worker                (err.__class__.__name__, err))
582*cda5da8dSAndroid Build Coastguard Worker
583*cda5da8dSAndroid Build Coastguard Worker
584*cda5da8dSAndroid Build Coastguard Workerdef main():
585*cda5da8dSAndroid Build Coastguard Worker    """Add standard site-specific directories to the module search path.
586*cda5da8dSAndroid Build Coastguard Worker
587*cda5da8dSAndroid Build Coastguard Worker    This function is called automatically when this module is imported,
588*cda5da8dSAndroid Build Coastguard Worker    unless the python interpreter was started with the -S flag.
589*cda5da8dSAndroid Build Coastguard Worker    """
590*cda5da8dSAndroid Build Coastguard Worker    global ENABLE_USER_SITE
591*cda5da8dSAndroid Build Coastguard Worker
592*cda5da8dSAndroid Build Coastguard Worker    orig_path = sys.path[:]
593*cda5da8dSAndroid Build Coastguard Worker    known_paths = removeduppaths()
594*cda5da8dSAndroid Build Coastguard Worker    if orig_path != sys.path:
595*cda5da8dSAndroid Build Coastguard Worker        # removeduppaths() might make sys.path absolute.
596*cda5da8dSAndroid Build Coastguard Worker        # fix __file__ and __cached__ of already imported modules too.
597*cda5da8dSAndroid Build Coastguard Worker        abs_paths()
598*cda5da8dSAndroid Build Coastguard Worker
599*cda5da8dSAndroid Build Coastguard Worker    known_paths = venv(known_paths)
600*cda5da8dSAndroid Build Coastguard Worker    if ENABLE_USER_SITE is None:
601*cda5da8dSAndroid Build Coastguard Worker        ENABLE_USER_SITE = check_enableusersite()
602*cda5da8dSAndroid Build Coastguard Worker    known_paths = addusersitepackages(known_paths)
603*cda5da8dSAndroid Build Coastguard Worker    known_paths = addsitepackages(known_paths)
604*cda5da8dSAndroid Build Coastguard Worker    setquit()
605*cda5da8dSAndroid Build Coastguard Worker    setcopyright()
606*cda5da8dSAndroid Build Coastguard Worker    sethelper()
607*cda5da8dSAndroid Build Coastguard Worker    if not sys.flags.isolated:
608*cda5da8dSAndroid Build Coastguard Worker        enablerlcompleter()
609*cda5da8dSAndroid Build Coastguard Worker    execsitecustomize()
610*cda5da8dSAndroid Build Coastguard Worker    if ENABLE_USER_SITE:
611*cda5da8dSAndroid Build Coastguard Worker        execusercustomize()
612*cda5da8dSAndroid Build Coastguard Worker
613*cda5da8dSAndroid Build Coastguard Worker# Prevent extending of sys.path when python was started with -S and
614*cda5da8dSAndroid Build Coastguard Worker# site is imported later.
615*cda5da8dSAndroid Build Coastguard Workerif not sys.flags.no_site:
616*cda5da8dSAndroid Build Coastguard Worker    main()
617*cda5da8dSAndroid Build Coastguard Worker
618*cda5da8dSAndroid Build Coastguard Workerdef _script():
619*cda5da8dSAndroid Build Coastguard Worker    help = """\
620*cda5da8dSAndroid Build Coastguard Worker    %s [--user-base] [--user-site]
621*cda5da8dSAndroid Build Coastguard Worker
622*cda5da8dSAndroid Build Coastguard Worker    Without arguments print some useful information
623*cda5da8dSAndroid Build Coastguard Worker    With arguments print the value of USER_BASE and/or USER_SITE separated
624*cda5da8dSAndroid Build Coastguard Worker    by '%s'.
625*cda5da8dSAndroid Build Coastguard Worker
626*cda5da8dSAndroid Build Coastguard Worker    Exit codes with --user-base or --user-site:
627*cda5da8dSAndroid Build Coastguard Worker      0 - user site directory is enabled
628*cda5da8dSAndroid Build Coastguard Worker      1 - user site directory is disabled by user
629*cda5da8dSAndroid Build Coastguard Worker      2 - user site directory is disabled by super user
630*cda5da8dSAndroid Build Coastguard Worker          or for security reasons
631*cda5da8dSAndroid Build Coastguard Worker     >2 - unknown error
632*cda5da8dSAndroid Build Coastguard Worker    """
633*cda5da8dSAndroid Build Coastguard Worker    args = sys.argv[1:]
634*cda5da8dSAndroid Build Coastguard Worker    if not args:
635*cda5da8dSAndroid Build Coastguard Worker        user_base = getuserbase()
636*cda5da8dSAndroid Build Coastguard Worker        user_site = getusersitepackages()
637*cda5da8dSAndroid Build Coastguard Worker        print("sys.path = [")
638*cda5da8dSAndroid Build Coastguard Worker        for dir in sys.path:
639*cda5da8dSAndroid Build Coastguard Worker            print("    %r," % (dir,))
640*cda5da8dSAndroid Build Coastguard Worker        print("]")
641*cda5da8dSAndroid Build Coastguard Worker        def exists(path):
642*cda5da8dSAndroid Build Coastguard Worker            if path is not None and os.path.isdir(path):
643*cda5da8dSAndroid Build Coastguard Worker                return "exists"
644*cda5da8dSAndroid Build Coastguard Worker            else:
645*cda5da8dSAndroid Build Coastguard Worker                return "doesn't exist"
646*cda5da8dSAndroid Build Coastguard Worker        print(f"USER_BASE: {user_base!r} ({exists(user_base)})")
647*cda5da8dSAndroid Build Coastguard Worker        print(f"USER_SITE: {user_site!r} ({exists(user_site)})")
648*cda5da8dSAndroid Build Coastguard Worker        print(f"ENABLE_USER_SITE: {ENABLE_USER_SITE!r}")
649*cda5da8dSAndroid Build Coastguard Worker        sys.exit(0)
650*cda5da8dSAndroid Build Coastguard Worker
651*cda5da8dSAndroid Build Coastguard Worker    buffer = []
652*cda5da8dSAndroid Build Coastguard Worker    if '--user-base' in args:
653*cda5da8dSAndroid Build Coastguard Worker        buffer.append(USER_BASE)
654*cda5da8dSAndroid Build Coastguard Worker    if '--user-site' in args:
655*cda5da8dSAndroid Build Coastguard Worker        buffer.append(USER_SITE)
656*cda5da8dSAndroid Build Coastguard Worker
657*cda5da8dSAndroid Build Coastguard Worker    if buffer:
658*cda5da8dSAndroid Build Coastguard Worker        print(os.pathsep.join(buffer))
659*cda5da8dSAndroid Build Coastguard Worker        if ENABLE_USER_SITE:
660*cda5da8dSAndroid Build Coastguard Worker            sys.exit(0)
661*cda5da8dSAndroid Build Coastguard Worker        elif ENABLE_USER_SITE is False:
662*cda5da8dSAndroid Build Coastguard Worker            sys.exit(1)
663*cda5da8dSAndroid Build Coastguard Worker        elif ENABLE_USER_SITE is None:
664*cda5da8dSAndroid Build Coastguard Worker            sys.exit(2)
665*cda5da8dSAndroid Build Coastguard Worker        else:
666*cda5da8dSAndroid Build Coastguard Worker            sys.exit(3)
667*cda5da8dSAndroid Build Coastguard Worker    else:
668*cda5da8dSAndroid Build Coastguard Worker        import textwrap
669*cda5da8dSAndroid Build Coastguard Worker        print(textwrap.dedent(help % (sys.argv[0], os.pathsep)))
670*cda5da8dSAndroid Build Coastguard Worker        sys.exit(10)
671*cda5da8dSAndroid Build Coastguard Worker
672*cda5da8dSAndroid Build Coastguard Workerif __name__ == '__main__':
673*cda5da8dSAndroid Build Coastguard Worker    _script()
674