ยปCore Development>Code coverage>Lib/site.py

Python code coverage for Lib/site.py

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