# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/.
import ast import functools import os import subprocess import sys import tempfile from pathlib import Path from subprocess import CompletedProcess from typing import List
if name == "mach":
base_path = base_path / "_virtualenvs" return PythonVirtualenv(str(base_path / name))
def test_new_package_appears_in_pkg_resources(): try: # "carrot" was chosen as the package to use because: # * It has to be a package that doesn't exist in-scope at the start (so, # all vendored modules included in the test virtualenv aren't usage). # * It must be on our internal PyPI mirror. # Of the options, "carrot" is a small install that fits these requirements.
pkg_resources.get_distribution("carrot") assertFalse, "Expected to not find 'carrot' as the initial state of the test" except pkg_resources.DistributionNotFound: pass
with tempfile.TemporaryDirectory() as venv_dir:
subprocess.check_call(
[
sys.executable, "-m", "venv",
venv_dir,
]
)
mach_virtualenv = context.virtualenv("mach")
expected_mach_paths = [
*context.stdlib_paths,
*context.mach_requirement_paths,
*(Path(p) for p in mach_virtualenv.site_packages_dirs()),
] assert mach == expected_mach_paths
command_virtualenv = context.virtualenv("build")
expected_command_paths = [
*context.stdlib_paths,
*context.mach_requirement_paths,
*(Path(p) for p in mach_virtualenv.site_packages_dirs()),
context.command_requirement_path,
*(Path(p) for p in command_virtualenv.site_packages_dirs()),
] assert command == expected_command_paths
mach_virtualenv = context.virtualenv("mach")
expected_mach_paths = [
*context.stdlib_paths,
*context.mach_requirement_paths,
*(Path(p) for p in mach_virtualenv.site_packages_dirs()),
] assert mach == expected_mach_paths
command_virtualenv = context.virtualenv("other")
expected_command_paths = [
*context.stdlib_paths,
*context.mach_requirement_paths,
*(Path(p) for p in mach_virtualenv.site_packages_dirs()),
context.command_requirement_path,
*(Path(p) for p in command_virtualenv.site_packages_dirs()),
] assert command == expected_command_paths
with tempfile.TemporaryDirectory() as work_dir: # Get "resolved" version of path to ease comparison against "site"-added sys.path # entries, as "site" calculates the realpath of provided locations.
work_dir = Path(work_dir).resolve()
mach_requirement_paths = [
*required_mach_sys_paths,
work_dir / "mach_site_path",
]
command_requirement_path = work_dir / "command_site_path"
(work_dir / "mach_site_path").touch()
command_requirement_path.touch() yield ActivationContext(
topsrcdir,
work_dir,
original_python_path,
stdlib_paths,
system_paths,
required_mach_sys_paths,
mach_requirement_paths,
command_requirement_path,
)
@functools.lru_cache(maxsize=None) def _original_python():
current_site = MozSiteMetadata.from_runtime()
stdlib_paths, system_paths = current_site.original_python.sys_path()
stdlib_paths = [Path(path) for path in _filter_pydev_from_paths(stdlib_paths)]
system_paths = [Path(path) for path in system_paths] return current_site.original_python.python_path, stdlib_paths, system_paths
def _run_activation_script(
context: ActivationContext,
source: str,
site_name: str,
invoking_python: str,
**kwargs
) -> CompletedProcess: return subprocess.run(
[
invoking_python,
str(Path(__file__).parent / "script_site_activation.py"),
],
stdout=subprocess.PIPE,
universal_newlines=True,
env={ "TOPSRCDIR": str(context.topsrcdir), "COMMAND_SITE": site_name, "PYTHONPATH": os.pathsep.join(
str(p) for p in context.required_moz_init_sys_paths
), "MACH_SITE_PTH_REQUIREMENTS": os.pathsep.join(
str(p) for p in context.mach_requirement_paths
), "COMMAND_SITE_PTH_REQUIREMENTS": str(context.command_requirement_path), "MACH_BUILD_PYTHON_NATIVE_PACKAGE_SOURCE": source, "WORK_DIR": str(context.work_dir), # These two variables are needed on Windows so that Python initializes # properly and adds the "user site packages" to the sys.path like normal. "SYSTEMROOT": os.environ.get("SYSTEMROOT", ""), "APPDATA": os.environ.get("APPDATA", ""),
},
**kwargs,
)
def _run_activation_script_for_paths(
context: ActivationContext, source: str, site_name: str, invoking_python: str = None
) -> List[List[Path]]: """Return the states of the sys.path when activating Mach-managed sites
Three sys.path states are returned:
* The initial sys.path, equivalent to "path_to_python -c "import sys; print(sys.path)"
* The sys.path after activating the Mach site
* The sys.path after activating the command site """
output = _run_activation_script(
context,
source,
site_name,
invoking_python or context.original_python_path,
check=True,
).stdout # Filter to the last line, which will have our nested list that we want to # parse. This will avoid unrelated output, such as from virtualenv creation
output = output.splitlines()[-1] return [
[Path(path) for path in _filter_pydev_from_paths(paths)] for paths in ast.literal_eval(output)
]
def _assert_original_python_sys_path(context: ActivationContext, original: List[Path]): # Assert that initial sys.path (prior to any activations) matches expectations. assert original == [
Path(__file__).parent,
*context.required_moz_init_sys_paths,
*context.stdlib_paths,
*context.system_paths,
]
def _sys_path_of_virtualenv(virtualenv: PythonVirtualenv) -> List[Path]:
output = subprocess.run(
[virtualenv.python_path, "-c", "import sys; print(sys.path)"],
stdout=subprocess.PIPE,
universal_newlines=True,
env={ # Needed for python to initialize properly "SYSTEMROOT": os.environ.get("SYSTEMROOT", ""),
},
check=True,
).stdout return [Path(path) for path in _filter_pydev_from_paths(ast.literal_eval(output))]
def _filter_pydev_from_paths(paths: List[str]) -> List[str]: # Filter out injected "pydev" debugging tool if running within a JetBrains # debugging context. return [path for path in paths if"pydev"notin path and"JetBrains"notin path]
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.