17db96d56Sopenharmony_ci"""Append module search paths for third-party packages to sys.path.
27db96d56Sopenharmony_ci
37db96d56Sopenharmony_ci****************************************************************
47db96d56Sopenharmony_ci* This module is automatically imported during initialization. *
57db96d56Sopenharmony_ci****************************************************************
67db96d56Sopenharmony_ci
77db96d56Sopenharmony_ciThis will append site-specific paths to the module search path.  On
87db96d56Sopenharmony_ciUnix (including Mac OSX), it starts with sys.prefix and
97db96d56Sopenharmony_cisys.exec_prefix (if different) and appends
107db96d56Sopenharmony_cilib/python<version>/site-packages.
117db96d56Sopenharmony_ciOn other platforms (such as Windows), it tries each of the
127db96d56Sopenharmony_ciprefixes directly, as well as with lib/site-packages appended.  The
137db96d56Sopenharmony_ciresulting directories, if they exist, are appended to sys.path, and
147db96d56Sopenharmony_cialso inspected for path configuration files.
157db96d56Sopenharmony_ci
167db96d56Sopenharmony_ciIf a file named "pyvenv.cfg" exists one directory above sys.executable,
177db96d56Sopenharmony_cisys.prefix and sys.exec_prefix are set to that directory and
187db96d56Sopenharmony_ciit is also checked for site-packages (sys.base_prefix and
197db96d56Sopenharmony_cisys.base_exec_prefix will always be the "real" prefixes of the Python
207db96d56Sopenharmony_ciinstallation). If "pyvenv.cfg" (a bootstrap configuration file) contains
217db96d56Sopenharmony_cithe key "include-system-site-packages" set to anything other than "false"
227db96d56Sopenharmony_ci(case-insensitive), the system-level prefixes will still also be
237db96d56Sopenharmony_cisearched for site-packages; otherwise they won't.
247db96d56Sopenharmony_ci
257db96d56Sopenharmony_ciAll of the resulting site-specific directories, if they exist, are
267db96d56Sopenharmony_ciappended to sys.path, and also inspected for path configuration
277db96d56Sopenharmony_cifiles.
287db96d56Sopenharmony_ci
297db96d56Sopenharmony_ciA path configuration file is a file whose name has the form
307db96d56Sopenharmony_ci<package>.pth; its contents are additional directories (one per line)
317db96d56Sopenharmony_cito be added to sys.path.  Non-existing directories (or
327db96d56Sopenharmony_cinon-directories) are never added to sys.path; no directory is added to
337db96d56Sopenharmony_cisys.path more than once.  Blank lines and lines beginning with
347db96d56Sopenharmony_ci'#' are skipped. Lines starting with 'import' are executed.
357db96d56Sopenharmony_ci
367db96d56Sopenharmony_ciFor example, suppose sys.prefix and sys.exec_prefix are set to
377db96d56Sopenharmony_ci/usr/local and there is a directory /usr/local/lib/python2.5/site-packages
387db96d56Sopenharmony_ciwith three subdirectories, foo, bar and spam, and two path
397db96d56Sopenharmony_ciconfiguration files, foo.pth and bar.pth.  Assume foo.pth contains the
407db96d56Sopenharmony_cifollowing:
417db96d56Sopenharmony_ci
427db96d56Sopenharmony_ci  # foo package configuration
437db96d56Sopenharmony_ci  foo
447db96d56Sopenharmony_ci  bar
457db96d56Sopenharmony_ci  bletch
467db96d56Sopenharmony_ci
477db96d56Sopenharmony_ciand bar.pth contains:
487db96d56Sopenharmony_ci
497db96d56Sopenharmony_ci  # bar package configuration
507db96d56Sopenharmony_ci  bar
517db96d56Sopenharmony_ci
527db96d56Sopenharmony_ciThen the following directories are added to sys.path, in this order:
537db96d56Sopenharmony_ci
547db96d56Sopenharmony_ci  /usr/local/lib/python2.5/site-packages/bar
557db96d56Sopenharmony_ci  /usr/local/lib/python2.5/site-packages/foo
567db96d56Sopenharmony_ci
577db96d56Sopenharmony_ciNote that bletch is omitted because it doesn't exist; bar precedes foo
587db96d56Sopenharmony_cibecause bar.pth comes alphabetically before foo.pth; and spam is
597db96d56Sopenharmony_ciomitted because it is not mentioned in either path configuration file.
607db96d56Sopenharmony_ci
617db96d56Sopenharmony_ciThe readline module is also automatically configured to enable
627db96d56Sopenharmony_cicompletion for systems that support it.  This can be overridden in
637db96d56Sopenharmony_cisitecustomize, usercustomize or PYTHONSTARTUP.  Starting Python in
647db96d56Sopenharmony_ciisolated mode (-I) disables automatic readline configuration.
657db96d56Sopenharmony_ci
667db96d56Sopenharmony_ciAfter these operations, an attempt is made to import a module
677db96d56Sopenharmony_cinamed sitecustomize, which can perform arbitrary additional
687db96d56Sopenharmony_cisite-specific customizations.  If this import fails with an
697db96d56Sopenharmony_ciImportError exception, it is silently ignored.
707db96d56Sopenharmony_ci"""
717db96d56Sopenharmony_ci
727db96d56Sopenharmony_ciimport sys
737db96d56Sopenharmony_ciimport os
747db96d56Sopenharmony_ciimport builtins
757db96d56Sopenharmony_ciimport _sitebuiltins
767db96d56Sopenharmony_ciimport io
777db96d56Sopenharmony_ci
787db96d56Sopenharmony_ci# Prefixes for site-packages; add additional prefixes like /usr/local here
797db96d56Sopenharmony_ciPREFIXES = [sys.prefix, sys.exec_prefix]
807db96d56Sopenharmony_ci# Enable per user site-packages directory
817db96d56Sopenharmony_ci# set it to False to disable the feature or True to force the feature
827db96d56Sopenharmony_ciENABLE_USER_SITE = None
837db96d56Sopenharmony_ci
847db96d56Sopenharmony_ci# for distutils.commands.install
857db96d56Sopenharmony_ci# These values are initialized by the getuserbase() and getusersitepackages()
867db96d56Sopenharmony_ci# functions, through the main() function when Python starts.
877db96d56Sopenharmony_ciUSER_SITE = None
887db96d56Sopenharmony_ciUSER_BASE = None
897db96d56Sopenharmony_ci
907db96d56Sopenharmony_ci
917db96d56Sopenharmony_cidef _trace(message):
927db96d56Sopenharmony_ci    if sys.flags.verbose:
937db96d56Sopenharmony_ci        print(message, file=sys.stderr)
947db96d56Sopenharmony_ci
957db96d56Sopenharmony_ci
967db96d56Sopenharmony_cidef makepath(*paths):
977db96d56Sopenharmony_ci    dir = os.path.join(*paths)
987db96d56Sopenharmony_ci    try:
997db96d56Sopenharmony_ci        dir = os.path.abspath(dir)
1007db96d56Sopenharmony_ci    except OSError:
1017db96d56Sopenharmony_ci        pass
1027db96d56Sopenharmony_ci    return dir, os.path.normcase(dir)
1037db96d56Sopenharmony_ci
1047db96d56Sopenharmony_ci
1057db96d56Sopenharmony_cidef abs_paths():
1067db96d56Sopenharmony_ci    """Set all module __file__ and __cached__ attributes to an absolute path"""
1077db96d56Sopenharmony_ci    for m in set(sys.modules.values()):
1087db96d56Sopenharmony_ci        loader_module = None
1097db96d56Sopenharmony_ci        try:
1107db96d56Sopenharmony_ci            loader_module = m.__loader__.__module__
1117db96d56Sopenharmony_ci        except AttributeError:
1127db96d56Sopenharmony_ci            try:
1137db96d56Sopenharmony_ci                loader_module = m.__spec__.loader.__module__
1147db96d56Sopenharmony_ci            except AttributeError:
1157db96d56Sopenharmony_ci                pass
1167db96d56Sopenharmony_ci        if loader_module not in {'_frozen_importlib', '_frozen_importlib_external'}:
1177db96d56Sopenharmony_ci            continue   # don't mess with a PEP 302-supplied __file__
1187db96d56Sopenharmony_ci        try:
1197db96d56Sopenharmony_ci            m.__file__ = os.path.abspath(m.__file__)
1207db96d56Sopenharmony_ci        except (AttributeError, OSError, TypeError):
1217db96d56Sopenharmony_ci            pass
1227db96d56Sopenharmony_ci        try:
1237db96d56Sopenharmony_ci            m.__cached__ = os.path.abspath(m.__cached__)
1247db96d56Sopenharmony_ci        except (AttributeError, OSError, TypeError):
1257db96d56Sopenharmony_ci            pass
1267db96d56Sopenharmony_ci
1277db96d56Sopenharmony_ci
1287db96d56Sopenharmony_cidef removeduppaths():
1297db96d56Sopenharmony_ci    """ Remove duplicate entries from sys.path along with making them
1307db96d56Sopenharmony_ci    absolute"""
1317db96d56Sopenharmony_ci    # This ensures that the initial path provided by the interpreter contains
1327db96d56Sopenharmony_ci    # only absolute pathnames, even if we're running from the build directory.
1337db96d56Sopenharmony_ci    L = []
1347db96d56Sopenharmony_ci    known_paths = set()
1357db96d56Sopenharmony_ci    for dir in sys.path:
1367db96d56Sopenharmony_ci        # Filter out duplicate paths (on case-insensitive file systems also
1377db96d56Sopenharmony_ci        # if they only differ in case); turn relative paths into absolute
1387db96d56Sopenharmony_ci        # paths.
1397db96d56Sopenharmony_ci        dir, dircase = makepath(dir)
1407db96d56Sopenharmony_ci        if dircase not in known_paths:
1417db96d56Sopenharmony_ci            L.append(dir)
1427db96d56Sopenharmony_ci            known_paths.add(dircase)
1437db96d56Sopenharmony_ci    sys.path[:] = L
1447db96d56Sopenharmony_ci    return known_paths
1457db96d56Sopenharmony_ci
1467db96d56Sopenharmony_ci
1477db96d56Sopenharmony_cidef _init_pathinfo():
1487db96d56Sopenharmony_ci    """Return a set containing all existing file system items from sys.path."""
1497db96d56Sopenharmony_ci    d = set()
1507db96d56Sopenharmony_ci    for item in sys.path:
1517db96d56Sopenharmony_ci        try:
1527db96d56Sopenharmony_ci            if os.path.exists(item):
1537db96d56Sopenharmony_ci                _, itemcase = makepath(item)
1547db96d56Sopenharmony_ci                d.add(itemcase)
1557db96d56Sopenharmony_ci        except TypeError:
1567db96d56Sopenharmony_ci            continue
1577db96d56Sopenharmony_ci    return d
1587db96d56Sopenharmony_ci
1597db96d56Sopenharmony_ci
1607db96d56Sopenharmony_cidef addpackage(sitedir, name, known_paths):
1617db96d56Sopenharmony_ci    """Process a .pth file within the site-packages directory:
1627db96d56Sopenharmony_ci       For each line in the file, either combine it with sitedir to a path
1637db96d56Sopenharmony_ci       and add that to known_paths, or execute it if it starts with 'import '.
1647db96d56Sopenharmony_ci    """
1657db96d56Sopenharmony_ci    if known_paths is None:
1667db96d56Sopenharmony_ci        known_paths = _init_pathinfo()
1677db96d56Sopenharmony_ci        reset = True
1687db96d56Sopenharmony_ci    else:
1697db96d56Sopenharmony_ci        reset = False
1707db96d56Sopenharmony_ci    fullname = os.path.join(sitedir, name)
1717db96d56Sopenharmony_ci    _trace(f"Processing .pth file: {fullname!r}")
1727db96d56Sopenharmony_ci    try:
1737db96d56Sopenharmony_ci        # locale encoding is not ideal especially on Windows. But we have used
1747db96d56Sopenharmony_ci        # it for a long time. setuptools uses the locale encoding too.
1757db96d56Sopenharmony_ci        f = io.TextIOWrapper(io.open_code(fullname), encoding="locale")
1767db96d56Sopenharmony_ci    except OSError:
1777db96d56Sopenharmony_ci        return
1787db96d56Sopenharmony_ci    with f:
1797db96d56Sopenharmony_ci        for n, line in enumerate(f):
1807db96d56Sopenharmony_ci            if line.startswith("#"):
1817db96d56Sopenharmony_ci                continue
1827db96d56Sopenharmony_ci            if line.strip() == "":
1837db96d56Sopenharmony_ci                continue
1847db96d56Sopenharmony_ci            try:
1857db96d56Sopenharmony_ci                if line.startswith(("import ", "import\t")):
1867db96d56Sopenharmony_ci                    exec(line)
1877db96d56Sopenharmony_ci                    continue
1887db96d56Sopenharmony_ci                line = line.rstrip()
1897db96d56Sopenharmony_ci                dir, dircase = makepath(sitedir, line)
1907db96d56Sopenharmony_ci                if not dircase in known_paths and os.path.exists(dir):
1917db96d56Sopenharmony_ci                    sys.path.append(dir)
1927db96d56Sopenharmony_ci                    known_paths.add(dircase)
1937db96d56Sopenharmony_ci            except Exception:
1947db96d56Sopenharmony_ci                print("Error processing line {:d} of {}:\n".format(n+1, fullname),
1957db96d56Sopenharmony_ci                      file=sys.stderr)
1967db96d56Sopenharmony_ci                import traceback
1977db96d56Sopenharmony_ci                for record in traceback.format_exception(*sys.exc_info()):
1987db96d56Sopenharmony_ci                    for line in record.splitlines():
1997db96d56Sopenharmony_ci                        print('  '+line, file=sys.stderr)
2007db96d56Sopenharmony_ci                print("\nRemainder of file ignored", file=sys.stderr)
2017db96d56Sopenharmony_ci                break
2027db96d56Sopenharmony_ci    if reset:
2037db96d56Sopenharmony_ci        known_paths = None
2047db96d56Sopenharmony_ci    return known_paths
2057db96d56Sopenharmony_ci
2067db96d56Sopenharmony_ci
2077db96d56Sopenharmony_cidef addsitedir(sitedir, known_paths=None):
2087db96d56Sopenharmony_ci    """Add 'sitedir' argument to sys.path if missing and handle .pth files in
2097db96d56Sopenharmony_ci    'sitedir'"""
2107db96d56Sopenharmony_ci    _trace(f"Adding directory: {sitedir!r}")
2117db96d56Sopenharmony_ci    if known_paths is None:
2127db96d56Sopenharmony_ci        known_paths = _init_pathinfo()
2137db96d56Sopenharmony_ci        reset = True
2147db96d56Sopenharmony_ci    else:
2157db96d56Sopenharmony_ci        reset = False
2167db96d56Sopenharmony_ci    sitedir, sitedircase = makepath(sitedir)
2177db96d56Sopenharmony_ci    if not sitedircase in known_paths:
2187db96d56Sopenharmony_ci        sys.path.append(sitedir)        # Add path component
2197db96d56Sopenharmony_ci        known_paths.add(sitedircase)
2207db96d56Sopenharmony_ci    try:
2217db96d56Sopenharmony_ci        names = os.listdir(sitedir)
2227db96d56Sopenharmony_ci    except OSError:
2237db96d56Sopenharmony_ci        return
2247db96d56Sopenharmony_ci    names = [name for name in names if name.endswith(".pth")]
2257db96d56Sopenharmony_ci    for name in sorted(names):
2267db96d56Sopenharmony_ci        addpackage(sitedir, name, known_paths)
2277db96d56Sopenharmony_ci    if reset:
2287db96d56Sopenharmony_ci        known_paths = None
2297db96d56Sopenharmony_ci    return known_paths
2307db96d56Sopenharmony_ci
2317db96d56Sopenharmony_ci
2327db96d56Sopenharmony_cidef check_enableusersite():
2337db96d56Sopenharmony_ci    """Check if user site directory is safe for inclusion
2347db96d56Sopenharmony_ci
2357db96d56Sopenharmony_ci    The function tests for the command line flag (including environment var),
2367db96d56Sopenharmony_ci    process uid/gid equal to effective uid/gid.
2377db96d56Sopenharmony_ci
2387db96d56Sopenharmony_ci    None: Disabled for security reasons
2397db96d56Sopenharmony_ci    False: Disabled by user (command line option)
2407db96d56Sopenharmony_ci    True: Safe and enabled
2417db96d56Sopenharmony_ci    """
2427db96d56Sopenharmony_ci    if sys.flags.no_user_site:
2437db96d56Sopenharmony_ci        return False
2447db96d56Sopenharmony_ci
2457db96d56Sopenharmony_ci    if hasattr(os, "getuid") and hasattr(os, "geteuid"):
2467db96d56Sopenharmony_ci        # check process uid == effective uid
2477db96d56Sopenharmony_ci        if os.geteuid() != os.getuid():
2487db96d56Sopenharmony_ci            return None
2497db96d56Sopenharmony_ci    if hasattr(os, "getgid") and hasattr(os, "getegid"):
2507db96d56Sopenharmony_ci        # check process gid == effective gid
2517db96d56Sopenharmony_ci        if os.getegid() != os.getgid():
2527db96d56Sopenharmony_ci            return None
2537db96d56Sopenharmony_ci
2547db96d56Sopenharmony_ci    return True
2557db96d56Sopenharmony_ci
2567db96d56Sopenharmony_ci
2577db96d56Sopenharmony_ci# NOTE: sysconfig and it's dependencies are relatively large but site module
2587db96d56Sopenharmony_ci# needs very limited part of them.
2597db96d56Sopenharmony_ci# To speedup startup time, we have copy of them.
2607db96d56Sopenharmony_ci#
2617db96d56Sopenharmony_ci# See https://bugs.python.org/issue29585
2627db96d56Sopenharmony_ci
2637db96d56Sopenharmony_ci# Copy of sysconfig._getuserbase()
2647db96d56Sopenharmony_cidef _getuserbase():
2657db96d56Sopenharmony_ci    env_base = os.environ.get("PYTHONUSERBASE", None)
2667db96d56Sopenharmony_ci    if env_base:
2677db96d56Sopenharmony_ci        return env_base
2687db96d56Sopenharmony_ci
2697db96d56Sopenharmony_ci    # Emscripten, VxWorks, and WASI have no home directories
2707db96d56Sopenharmony_ci    if sys.platform in {"emscripten", "vxworks", "wasi"}:
2717db96d56Sopenharmony_ci        return None
2727db96d56Sopenharmony_ci
2737db96d56Sopenharmony_ci    def joinuser(*args):
2747db96d56Sopenharmony_ci        return os.path.expanduser(os.path.join(*args))
2757db96d56Sopenharmony_ci
2767db96d56Sopenharmony_ci    if os.name == "nt":
2777db96d56Sopenharmony_ci        base = os.environ.get("APPDATA") or "~"
2787db96d56Sopenharmony_ci        return joinuser(base, "Python")
2797db96d56Sopenharmony_ci
2807db96d56Sopenharmony_ci    if sys.platform == "darwin" and sys._framework:
2817db96d56Sopenharmony_ci        return joinuser("~", "Library", sys._framework,
2827db96d56Sopenharmony_ci                        "%d.%d" % sys.version_info[:2])
2837db96d56Sopenharmony_ci
2847db96d56Sopenharmony_ci    return joinuser("~", ".local")
2857db96d56Sopenharmony_ci
2867db96d56Sopenharmony_ci
2877db96d56Sopenharmony_ci# Same to sysconfig.get_path('purelib', os.name+'_user')
2887db96d56Sopenharmony_cidef _get_path(userbase):
2897db96d56Sopenharmony_ci    version = sys.version_info
2907db96d56Sopenharmony_ci
2917db96d56Sopenharmony_ci    if os.name == 'nt':
2927db96d56Sopenharmony_ci        ver_nodot = sys.winver.replace('.', '')
2937db96d56Sopenharmony_ci        return f'{userbase}\\Python{ver_nodot}\\site-packages'
2947db96d56Sopenharmony_ci
2957db96d56Sopenharmony_ci    if sys.platform == 'darwin' and sys._framework:
2967db96d56Sopenharmony_ci        return f'{userbase}/lib/python/site-packages'
2977db96d56Sopenharmony_ci
2987db96d56Sopenharmony_ci    return f'{userbase}/lib/python{version[0]}.{version[1]}/site-packages'
2997db96d56Sopenharmony_ci
3007db96d56Sopenharmony_ci
3017db96d56Sopenharmony_cidef getuserbase():
3027db96d56Sopenharmony_ci    """Returns the `user base` directory path.
3037db96d56Sopenharmony_ci
3047db96d56Sopenharmony_ci    The `user base` directory can be used to store data. If the global
3057db96d56Sopenharmony_ci    variable ``USER_BASE`` is not initialized yet, this function will also set
3067db96d56Sopenharmony_ci    it.
3077db96d56Sopenharmony_ci    """
3087db96d56Sopenharmony_ci    global USER_BASE
3097db96d56Sopenharmony_ci    if USER_BASE is None:
3107db96d56Sopenharmony_ci        USER_BASE = _getuserbase()
3117db96d56Sopenharmony_ci    return USER_BASE
3127db96d56Sopenharmony_ci
3137db96d56Sopenharmony_ci
3147db96d56Sopenharmony_cidef getusersitepackages():
3157db96d56Sopenharmony_ci    """Returns the user-specific site-packages directory path.
3167db96d56Sopenharmony_ci
3177db96d56Sopenharmony_ci    If the global variable ``USER_SITE`` is not initialized yet, this
3187db96d56Sopenharmony_ci    function will also set it.
3197db96d56Sopenharmony_ci    """
3207db96d56Sopenharmony_ci    global USER_SITE, ENABLE_USER_SITE
3217db96d56Sopenharmony_ci    userbase = getuserbase() # this will also set USER_BASE
3227db96d56Sopenharmony_ci
3237db96d56Sopenharmony_ci    if USER_SITE is None:
3247db96d56Sopenharmony_ci        if userbase is None:
3257db96d56Sopenharmony_ci            ENABLE_USER_SITE = False # disable user site and return None
3267db96d56Sopenharmony_ci        else:
3277db96d56Sopenharmony_ci            USER_SITE = _get_path(userbase)
3287db96d56Sopenharmony_ci
3297db96d56Sopenharmony_ci    return USER_SITE
3307db96d56Sopenharmony_ci
3317db96d56Sopenharmony_cidef addusersitepackages(known_paths):
3327db96d56Sopenharmony_ci    """Add a per user site-package to sys.path
3337db96d56Sopenharmony_ci
3347db96d56Sopenharmony_ci    Each user has its own python directory with site-packages in the
3357db96d56Sopenharmony_ci    home directory.
3367db96d56Sopenharmony_ci    """
3377db96d56Sopenharmony_ci    # get the per user site-package path
3387db96d56Sopenharmony_ci    # this call will also make sure USER_BASE and USER_SITE are set
3397db96d56Sopenharmony_ci    _trace("Processing user site-packages")
3407db96d56Sopenharmony_ci    user_site = getusersitepackages()
3417db96d56Sopenharmony_ci
3427db96d56Sopenharmony_ci    if ENABLE_USER_SITE and os.path.isdir(user_site):
3437db96d56Sopenharmony_ci        addsitedir(user_site, known_paths)
3447db96d56Sopenharmony_ci    return known_paths
3457db96d56Sopenharmony_ci
3467db96d56Sopenharmony_cidef getsitepackages(prefixes=None):
3477db96d56Sopenharmony_ci    """Returns a list containing all global site-packages directories.
3487db96d56Sopenharmony_ci
3497db96d56Sopenharmony_ci    For each directory present in ``prefixes`` (or the global ``PREFIXES``),
3507db96d56Sopenharmony_ci    this function will find its `site-packages` subdirectory depending on the
3517db96d56Sopenharmony_ci    system environment, and will return a list of full paths.
3527db96d56Sopenharmony_ci    """
3537db96d56Sopenharmony_ci    sitepackages = []
3547db96d56Sopenharmony_ci    seen = set()
3557db96d56Sopenharmony_ci
3567db96d56Sopenharmony_ci    if prefixes is None:
3577db96d56Sopenharmony_ci        prefixes = PREFIXES
3587db96d56Sopenharmony_ci
3597db96d56Sopenharmony_ci    for prefix in prefixes:
3607db96d56Sopenharmony_ci        if not prefix or prefix in seen:
3617db96d56Sopenharmony_ci            continue
3627db96d56Sopenharmony_ci        seen.add(prefix)
3637db96d56Sopenharmony_ci
3647db96d56Sopenharmony_ci        if os.sep == '/':
3657db96d56Sopenharmony_ci            libdirs = [sys.platlibdir]
3667db96d56Sopenharmony_ci            if sys.platlibdir != "lib":
3677db96d56Sopenharmony_ci                libdirs.append("lib")
3687db96d56Sopenharmony_ci
3697db96d56Sopenharmony_ci            for libdir in libdirs:
3707db96d56Sopenharmony_ci                path = os.path.join(prefix, libdir,
3717db96d56Sopenharmony_ci                                    "python%d.%d" % sys.version_info[:2],
3727db96d56Sopenharmony_ci                                    "site-packages")
3737db96d56Sopenharmony_ci                sitepackages.append(path)
3747db96d56Sopenharmony_ci        else:
3757db96d56Sopenharmony_ci            sitepackages.append(prefix)
3767db96d56Sopenharmony_ci            sitepackages.append(os.path.join(prefix, "Lib", "site-packages"))
3777db96d56Sopenharmony_ci    return sitepackages
3787db96d56Sopenharmony_ci
3797db96d56Sopenharmony_cidef addsitepackages(known_paths, prefixes=None):
3807db96d56Sopenharmony_ci    """Add site-packages to sys.path"""
3817db96d56Sopenharmony_ci    _trace("Processing global site-packages")
3827db96d56Sopenharmony_ci    for sitedir in getsitepackages(prefixes):
3837db96d56Sopenharmony_ci        if os.path.isdir(sitedir):
3847db96d56Sopenharmony_ci            addsitedir(sitedir, known_paths)
3857db96d56Sopenharmony_ci
3867db96d56Sopenharmony_ci    return known_paths
3877db96d56Sopenharmony_ci
3887db96d56Sopenharmony_cidef setquit():
3897db96d56Sopenharmony_ci    """Define new builtins 'quit' and 'exit'.
3907db96d56Sopenharmony_ci
3917db96d56Sopenharmony_ci    These are objects which make the interpreter exit when called.
3927db96d56Sopenharmony_ci    The repr of each object contains a hint at how it works.
3937db96d56Sopenharmony_ci
3947db96d56Sopenharmony_ci    """
3957db96d56Sopenharmony_ci    if os.sep == '\\':
3967db96d56Sopenharmony_ci        eof = 'Ctrl-Z plus Return'
3977db96d56Sopenharmony_ci    else:
3987db96d56Sopenharmony_ci        eof = 'Ctrl-D (i.e. EOF)'
3997db96d56Sopenharmony_ci
4007db96d56Sopenharmony_ci    builtins.quit = _sitebuiltins.Quitter('quit', eof)
4017db96d56Sopenharmony_ci    builtins.exit = _sitebuiltins.Quitter('exit', eof)
4027db96d56Sopenharmony_ci
4037db96d56Sopenharmony_ci
4047db96d56Sopenharmony_cidef setcopyright():
4057db96d56Sopenharmony_ci    """Set 'copyright' and 'credits' in builtins"""
4067db96d56Sopenharmony_ci    builtins.copyright = _sitebuiltins._Printer("copyright", sys.copyright)
4077db96d56Sopenharmony_ci    if sys.platform[:4] == 'java':
4087db96d56Sopenharmony_ci        builtins.credits = _sitebuiltins._Printer(
4097db96d56Sopenharmony_ci            "credits",
4107db96d56Sopenharmony_ci            "Jython is maintained by the Jython developers (www.jython.org).")
4117db96d56Sopenharmony_ci    else:
4127db96d56Sopenharmony_ci        builtins.credits = _sitebuiltins._Printer("credits", """\
4137db96d56Sopenharmony_ci    Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
4147db96d56Sopenharmony_ci    for supporting Python development.  See www.python.org for more information.""")
4157db96d56Sopenharmony_ci    files, dirs = [], []
4167db96d56Sopenharmony_ci    # Not all modules are required to have a __file__ attribute.  See
4177db96d56Sopenharmony_ci    # PEP 420 for more details.
4187db96d56Sopenharmony_ci    here = getattr(sys, '_stdlib_dir', None)
4197db96d56Sopenharmony_ci    if not here and hasattr(os, '__file__'):
4207db96d56Sopenharmony_ci        here = os.path.dirname(os.__file__)
4217db96d56Sopenharmony_ci    if here:
4227db96d56Sopenharmony_ci        files.extend(["LICENSE.txt", "LICENSE"])
4237db96d56Sopenharmony_ci        dirs.extend([os.path.join(here, os.pardir), here, os.curdir])
4247db96d56Sopenharmony_ci    builtins.license = _sitebuiltins._Printer(
4257db96d56Sopenharmony_ci        "license",
4267db96d56Sopenharmony_ci        "See https://www.python.org/psf/license/",
4277db96d56Sopenharmony_ci        files, dirs)
4287db96d56Sopenharmony_ci
4297db96d56Sopenharmony_ci
4307db96d56Sopenharmony_cidef sethelper():
4317db96d56Sopenharmony_ci    builtins.help = _sitebuiltins._Helper()
4327db96d56Sopenharmony_ci
4337db96d56Sopenharmony_cidef enablerlcompleter():
4347db96d56Sopenharmony_ci    """Enable default readline configuration on interactive prompts, by
4357db96d56Sopenharmony_ci    registering a sys.__interactivehook__.
4367db96d56Sopenharmony_ci
4377db96d56Sopenharmony_ci    If the readline module can be imported, the hook will set the Tab key
4387db96d56Sopenharmony_ci    as completion key and register ~/.python_history as history file.
4397db96d56Sopenharmony_ci    This can be overridden in the sitecustomize or usercustomize module,
4407db96d56Sopenharmony_ci    or in a PYTHONSTARTUP file.
4417db96d56Sopenharmony_ci    """
4427db96d56Sopenharmony_ci    def register_readline():
4437db96d56Sopenharmony_ci        import atexit
4447db96d56Sopenharmony_ci        try:
4457db96d56Sopenharmony_ci            import readline
4467db96d56Sopenharmony_ci            import rlcompleter
4477db96d56Sopenharmony_ci        except ImportError:
4487db96d56Sopenharmony_ci            return
4497db96d56Sopenharmony_ci
4507db96d56Sopenharmony_ci        # Reading the initialization (config) file may not be enough to set a
4517db96d56Sopenharmony_ci        # completion key, so we set one first and then read the file.
4527db96d56Sopenharmony_ci        readline_doc = getattr(readline, '__doc__', '')
4537db96d56Sopenharmony_ci        if readline_doc is not None and 'libedit' in readline_doc:
4547db96d56Sopenharmony_ci            readline.parse_and_bind('bind ^I rl_complete')
4557db96d56Sopenharmony_ci        else:
4567db96d56Sopenharmony_ci            readline.parse_and_bind('tab: complete')
4577db96d56Sopenharmony_ci
4587db96d56Sopenharmony_ci        try:
4597db96d56Sopenharmony_ci            readline.read_init_file()
4607db96d56Sopenharmony_ci        except OSError:
4617db96d56Sopenharmony_ci            # An OSError here could have many causes, but the most likely one
4627db96d56Sopenharmony_ci            # is that there's no .inputrc file (or .editrc file in the case of
4637db96d56Sopenharmony_ci            # Mac OS X + libedit) in the expected location.  In that case, we
4647db96d56Sopenharmony_ci            # want to ignore the exception.
4657db96d56Sopenharmony_ci            pass
4667db96d56Sopenharmony_ci
4677db96d56Sopenharmony_ci        if readline.get_current_history_length() == 0:
4687db96d56Sopenharmony_ci            # If no history was loaded, default to .python_history.
4697db96d56Sopenharmony_ci            # The guard is necessary to avoid doubling history size at
4707db96d56Sopenharmony_ci            # each interpreter exit when readline was already configured
4717db96d56Sopenharmony_ci            # through a PYTHONSTARTUP hook, see:
4727db96d56Sopenharmony_ci            # http://bugs.python.org/issue5845#msg198636
4737db96d56Sopenharmony_ci            history = os.path.join(os.path.expanduser('~'),
4747db96d56Sopenharmony_ci                                   '.python_history')
4757db96d56Sopenharmony_ci            try:
4767db96d56Sopenharmony_ci                readline.read_history_file(history)
4777db96d56Sopenharmony_ci            except OSError:
4787db96d56Sopenharmony_ci                pass
4797db96d56Sopenharmony_ci
4807db96d56Sopenharmony_ci            def write_history():
4817db96d56Sopenharmony_ci                try:
4827db96d56Sopenharmony_ci                    readline.write_history_file(history)
4837db96d56Sopenharmony_ci                except OSError:
4847db96d56Sopenharmony_ci                    # bpo-19891, bpo-41193: Home directory does not exist
4857db96d56Sopenharmony_ci                    # or is not writable, or the filesystem is read-only.
4867db96d56Sopenharmony_ci                    pass
4877db96d56Sopenharmony_ci
4887db96d56Sopenharmony_ci            atexit.register(write_history)
4897db96d56Sopenharmony_ci
4907db96d56Sopenharmony_ci    sys.__interactivehook__ = register_readline
4917db96d56Sopenharmony_ci
4927db96d56Sopenharmony_cidef venv(known_paths):
4937db96d56Sopenharmony_ci    global PREFIXES, ENABLE_USER_SITE
4947db96d56Sopenharmony_ci
4957db96d56Sopenharmony_ci    env = os.environ
4967db96d56Sopenharmony_ci    if sys.platform == 'darwin' and '__PYVENV_LAUNCHER__' in env:
4977db96d56Sopenharmony_ci        executable = sys._base_executable = os.environ['__PYVENV_LAUNCHER__']
4987db96d56Sopenharmony_ci    else:
4997db96d56Sopenharmony_ci        executable = sys.executable
5007db96d56Sopenharmony_ci    exe_dir, _ = os.path.split(os.path.abspath(executable))
5017db96d56Sopenharmony_ci    site_prefix = os.path.dirname(exe_dir)
5027db96d56Sopenharmony_ci    sys._home = None
5037db96d56Sopenharmony_ci    conf_basename = 'pyvenv.cfg'
5047db96d56Sopenharmony_ci    candidate_confs = [
5057db96d56Sopenharmony_ci        conffile for conffile in (
5067db96d56Sopenharmony_ci            os.path.join(exe_dir, conf_basename),
5077db96d56Sopenharmony_ci            os.path.join(site_prefix, conf_basename)
5087db96d56Sopenharmony_ci            )
5097db96d56Sopenharmony_ci        if os.path.isfile(conffile)
5107db96d56Sopenharmony_ci        ]
5117db96d56Sopenharmony_ci
5127db96d56Sopenharmony_ci    if candidate_confs:
5137db96d56Sopenharmony_ci        virtual_conf = candidate_confs[0]
5147db96d56Sopenharmony_ci        system_site = "true"
5157db96d56Sopenharmony_ci        # Issue 25185: Use UTF-8, as that's what the venv module uses when
5167db96d56Sopenharmony_ci        # writing the file.
5177db96d56Sopenharmony_ci        with open(virtual_conf, encoding='utf-8') as f:
5187db96d56Sopenharmony_ci            for line in f:
5197db96d56Sopenharmony_ci                if '=' in line:
5207db96d56Sopenharmony_ci                    key, _, value = line.partition('=')
5217db96d56Sopenharmony_ci                    key = key.strip().lower()
5227db96d56Sopenharmony_ci                    value = value.strip()
5237db96d56Sopenharmony_ci                    if key == 'include-system-site-packages':
5247db96d56Sopenharmony_ci                        system_site = value.lower()
5257db96d56Sopenharmony_ci                    elif key == 'home':
5267db96d56Sopenharmony_ci                        sys._home = value
5277db96d56Sopenharmony_ci
5287db96d56Sopenharmony_ci        sys.prefix = sys.exec_prefix = site_prefix
5297db96d56Sopenharmony_ci
5307db96d56Sopenharmony_ci        # Doing this here ensures venv takes precedence over user-site
5317db96d56Sopenharmony_ci        addsitepackages(known_paths, [sys.prefix])
5327db96d56Sopenharmony_ci
5337db96d56Sopenharmony_ci        # addsitepackages will process site_prefix again if its in PREFIXES,
5347db96d56Sopenharmony_ci        # but that's ok; known_paths will prevent anything being added twice
5357db96d56Sopenharmony_ci        if system_site == "true":
5367db96d56Sopenharmony_ci            PREFIXES.insert(0, sys.prefix)
5377db96d56Sopenharmony_ci        else:
5387db96d56Sopenharmony_ci            PREFIXES = [sys.prefix]
5397db96d56Sopenharmony_ci            ENABLE_USER_SITE = False
5407db96d56Sopenharmony_ci
5417db96d56Sopenharmony_ci    return known_paths
5427db96d56Sopenharmony_ci
5437db96d56Sopenharmony_ci
5447db96d56Sopenharmony_cidef execsitecustomize():
5457db96d56Sopenharmony_ci    """Run custom site specific code, if available."""
5467db96d56Sopenharmony_ci    try:
5477db96d56Sopenharmony_ci        try:
5487db96d56Sopenharmony_ci            import sitecustomize
5497db96d56Sopenharmony_ci        except ImportError as exc:
5507db96d56Sopenharmony_ci            if exc.name == 'sitecustomize':
5517db96d56Sopenharmony_ci                pass
5527db96d56Sopenharmony_ci            else:
5537db96d56Sopenharmony_ci                raise
5547db96d56Sopenharmony_ci    except Exception as err:
5557db96d56Sopenharmony_ci        if sys.flags.verbose:
5567db96d56Sopenharmony_ci            sys.excepthook(*sys.exc_info())
5577db96d56Sopenharmony_ci        else:
5587db96d56Sopenharmony_ci            sys.stderr.write(
5597db96d56Sopenharmony_ci                "Error in sitecustomize; set PYTHONVERBOSE for traceback:\n"
5607db96d56Sopenharmony_ci                "%s: %s\n" %
5617db96d56Sopenharmony_ci                (err.__class__.__name__, err))
5627db96d56Sopenharmony_ci
5637db96d56Sopenharmony_ci
5647db96d56Sopenharmony_cidef execusercustomize():
5657db96d56Sopenharmony_ci    """Run custom user specific code, if available."""
5667db96d56Sopenharmony_ci    try:
5677db96d56Sopenharmony_ci        try:
5687db96d56Sopenharmony_ci            import usercustomize
5697db96d56Sopenharmony_ci        except ImportError as exc:
5707db96d56Sopenharmony_ci            if exc.name == 'usercustomize':
5717db96d56Sopenharmony_ci                pass
5727db96d56Sopenharmony_ci            else:
5737db96d56Sopenharmony_ci                raise
5747db96d56Sopenharmony_ci    except Exception as err:
5757db96d56Sopenharmony_ci        if sys.flags.verbose:
5767db96d56Sopenharmony_ci            sys.excepthook(*sys.exc_info())
5777db96d56Sopenharmony_ci        else:
5787db96d56Sopenharmony_ci            sys.stderr.write(
5797db96d56Sopenharmony_ci                "Error in usercustomize; set PYTHONVERBOSE for traceback:\n"
5807db96d56Sopenharmony_ci                "%s: %s\n" %
5817db96d56Sopenharmony_ci                (err.__class__.__name__, err))
5827db96d56Sopenharmony_ci
5837db96d56Sopenharmony_ci
5847db96d56Sopenharmony_cidef main():
5857db96d56Sopenharmony_ci    """Add standard site-specific directories to the module search path.
5867db96d56Sopenharmony_ci
5877db96d56Sopenharmony_ci    This function is called automatically when this module is imported,
5887db96d56Sopenharmony_ci    unless the python interpreter was started with the -S flag.
5897db96d56Sopenharmony_ci    """
5907db96d56Sopenharmony_ci    global ENABLE_USER_SITE
5917db96d56Sopenharmony_ci
5927db96d56Sopenharmony_ci    orig_path = sys.path[:]
5937db96d56Sopenharmony_ci    known_paths = removeduppaths()
5947db96d56Sopenharmony_ci    if orig_path != sys.path:
5957db96d56Sopenharmony_ci        # removeduppaths() might make sys.path absolute.
5967db96d56Sopenharmony_ci        # fix __file__ and __cached__ of already imported modules too.
5977db96d56Sopenharmony_ci        abs_paths()
5987db96d56Sopenharmony_ci
5997db96d56Sopenharmony_ci    known_paths = venv(known_paths)
6007db96d56Sopenharmony_ci    if ENABLE_USER_SITE is None:
6017db96d56Sopenharmony_ci        ENABLE_USER_SITE = check_enableusersite()
6027db96d56Sopenharmony_ci    known_paths = addusersitepackages(known_paths)
6037db96d56Sopenharmony_ci    known_paths = addsitepackages(known_paths)
6047db96d56Sopenharmony_ci    setquit()
6057db96d56Sopenharmony_ci    setcopyright()
6067db96d56Sopenharmony_ci    sethelper()
6077db96d56Sopenharmony_ci    if not sys.flags.isolated:
6087db96d56Sopenharmony_ci        enablerlcompleter()
6097db96d56Sopenharmony_ci    execsitecustomize()
6107db96d56Sopenharmony_ci    if ENABLE_USER_SITE:
6117db96d56Sopenharmony_ci        execusercustomize()
6127db96d56Sopenharmony_ci
6137db96d56Sopenharmony_ci# Prevent extending of sys.path when python was started with -S and
6147db96d56Sopenharmony_ci# site is imported later.
6157db96d56Sopenharmony_ciif not sys.flags.no_site:
6167db96d56Sopenharmony_ci    main()
6177db96d56Sopenharmony_ci
6187db96d56Sopenharmony_cidef _script():
6197db96d56Sopenharmony_ci    help = """\
6207db96d56Sopenharmony_ci    %s [--user-base] [--user-site]
6217db96d56Sopenharmony_ci
6227db96d56Sopenharmony_ci    Without arguments print some useful information
6237db96d56Sopenharmony_ci    With arguments print the value of USER_BASE and/or USER_SITE separated
6247db96d56Sopenharmony_ci    by '%s'.
6257db96d56Sopenharmony_ci
6267db96d56Sopenharmony_ci    Exit codes with --user-base or --user-site:
6277db96d56Sopenharmony_ci      0 - user site directory is enabled
6287db96d56Sopenharmony_ci      1 - user site directory is disabled by user
6297db96d56Sopenharmony_ci      2 - user site directory is disabled by super user
6307db96d56Sopenharmony_ci          or for security reasons
6317db96d56Sopenharmony_ci     >2 - unknown error
6327db96d56Sopenharmony_ci    """
6337db96d56Sopenharmony_ci    args = sys.argv[1:]
6347db96d56Sopenharmony_ci    if not args:
6357db96d56Sopenharmony_ci        user_base = getuserbase()
6367db96d56Sopenharmony_ci        user_site = getusersitepackages()
6377db96d56Sopenharmony_ci        print("sys.path = [")
6387db96d56Sopenharmony_ci        for dir in sys.path:
6397db96d56Sopenharmony_ci            print("    %r," % (dir,))
6407db96d56Sopenharmony_ci        print("]")
6417db96d56Sopenharmony_ci        def exists(path):
6427db96d56Sopenharmony_ci            if path is not None and os.path.isdir(path):
6437db96d56Sopenharmony_ci                return "exists"
6447db96d56Sopenharmony_ci            else:
6457db96d56Sopenharmony_ci                return "doesn't exist"
6467db96d56Sopenharmony_ci        print(f"USER_BASE: {user_base!r} ({exists(user_base)})")
6477db96d56Sopenharmony_ci        print(f"USER_SITE: {user_site!r} ({exists(user_site)})")
6487db96d56Sopenharmony_ci        print(f"ENABLE_USER_SITE: {ENABLE_USER_SITE!r}")
6497db96d56Sopenharmony_ci        sys.exit(0)
6507db96d56Sopenharmony_ci
6517db96d56Sopenharmony_ci    buffer = []
6527db96d56Sopenharmony_ci    if '--user-base' in args:
6537db96d56Sopenharmony_ci        buffer.append(USER_BASE)
6547db96d56Sopenharmony_ci    if '--user-site' in args:
6557db96d56Sopenharmony_ci        buffer.append(USER_SITE)
6567db96d56Sopenharmony_ci
6577db96d56Sopenharmony_ci    if buffer:
6587db96d56Sopenharmony_ci        print(os.pathsep.join(buffer))
6597db96d56Sopenharmony_ci        if ENABLE_USER_SITE:
6607db96d56Sopenharmony_ci            sys.exit(0)
6617db96d56Sopenharmony_ci        elif ENABLE_USER_SITE is False:
6627db96d56Sopenharmony_ci            sys.exit(1)
6637db96d56Sopenharmony_ci        elif ENABLE_USER_SITE is None:
6647db96d56Sopenharmony_ci            sys.exit(2)
6657db96d56Sopenharmony_ci        else:
6667db96d56Sopenharmony_ci            sys.exit(3)
6677db96d56Sopenharmony_ci    else:
6687db96d56Sopenharmony_ci        import textwrap
6697db96d56Sopenharmony_ci        print(textwrap.dedent(help % (sys.argv[0], os.pathsep)))
6707db96d56Sopenharmony_ci        sys.exit(10)
6717db96d56Sopenharmony_ci
6727db96d56Sopenharmony_ciif __name__ == '__main__':
6737db96d56Sopenharmony_ci    _script()
674