def _lint_pre_commit(session, rcfile, flags, paths): if "VIRTUAL_ENV" not in os.environ: session.error( "This should be running from within a virtualenv and " "'VIRTUAL_ENV' was not found as an environment variable." ) if "pre-commit" not in os.environ["VIRTUAL_ENV"]: session.error( "This should be running from within a pre-commit virtualenv and " "'VIRTUAL_ENV'({}) does not appear to be a pre-commit virtualenv.".format( os.environ["VIRTUAL_ENV"] ) ) from nox.virtualenv import VirtualEnv # Let's patch nox to make it run inside the pre-commit virtualenv try: session._runner.venv = VirtualEnv( # pylint: disable=unexpected-keyword-arg os.environ["VIRTUAL_ENV"], interpreter=session._runner.func.python, reuse_existing=True, venv=True, ) except TypeError: # This is still nox-py2 session._runner.venv = VirtualEnv( os.environ["VIRTUAL_ENV"], interpreter=session._runner.func.python, reuse_existing=True, ) _lint(session, rcfile, flags, paths, tee_output=False)
def invoke_pre_commit(session): """ DO NOT CALL THIS NOX SESSION DIRECTLY This session is called from a pre-commit hook """ if "VIRTUAL_ENV" not in os.environ: session.error( "This should be running from within a virtualenv and " "'VIRTUAL_ENV' was not found as an environment variable.") if "pre-commit" not in os.environ["VIRTUAL_ENV"]: session.error( "This should be running from within a pre-commit virtualenv and " "'VIRTUAL_ENV'({}) does not appear to be a pre-commit virtualenv.". format(os.environ["VIRTUAL_ENV"])) from nox.virtualenv import VirtualEnv # Let's patch nox to make it run inside the pre-commit virtualenv try: session._runner.venv = VirtualEnv( # pylint: disable=unexpected-keyword-arg os.environ["VIRTUAL_ENV"], interpreter=session._runner.func.python, reuse_existing=True, venv=True, ) except TypeError: # This is still nox-py2 session._runner.venv = VirtualEnv( os.environ["VIRTUAL_ENV"], interpreter=session._runner.func.python, reuse_existing=True, ) _invoke(session)
def _create_venv(self): self.venv = VirtualEnv( os.path.join(self.global_config.envdir, self.name), interpreter=self.config.interpreter, reuse_existing=(self.config.reuse_existing_virtualenv or self.global_config.reuse_existing_virtualenvs)) self.venv.create()
def _create_venv(self): if self.func.python is False: self.venv = ProcessEnv() return path = _normalize_path(self.global_config.envdir, self.friendly_name) reuse_existing = (self.func.reuse_venv or self.global_config.reuse_existing_virtualenvs) self.venv = VirtualEnv(path, interpreter=self.func.python, reuse_existing=reuse_existing) self.venv.create()
def _create_venv(self): if not self.config.virtualenv: self.venv = ProcessEnv() self._should_install_deps = False return self.venv = VirtualEnv( _normalize_path(self.global_config.envdir, self.signature or self.name), interpreter=self.config.interpreter, reuse_existing=(self.config.reuse_existing_virtualenv or self.global_config.reuse_existing_virtualenvs)) self._should_install_deps = self.venv.create()
def _create_venv(self): if self.func.python is False: self.venv = ProcessEnv() return path = _normalize_path(self.global_config.envdir, self.friendly_name) reuse_existing = ( self.func.reuse_venv or self.global_config.reuse_existing_virtualenvs ) self.venv = VirtualEnv( path, interpreter=self.func.python, reuse_existing=reuse_existing ) self.venv.create()
def flame_graph(c): c.run(f'nox --install-only -s profiling') location = Path('.nox/profiling') venv = VirtualEnv(location.resolve()) venv_bin = Path(venv.bin) scrapd = venv_bin / 'scrapd' c.run(f'sudo py-spy -d 20 --flame profile.svg -- {scrapd.resolve()} -v --pages 5')
def _patch_session(session): if USE_SYSTEM_PYTHON is False: session.log("NOT Patching nox to install against the system python") return session.log("Patching nox to install against the system python") # Let's get sys.prefix old_install_only_value = session._runner.global_config.install_only try: # Force install only to be false for the following chunk of code # For additional information as to why see: # https://github.com/theacodes/nox/pull/181 session._runner.global_config.install_only = False sys_prefix = session.run( "python", "-c" 'import sys; sys.stdout.write("{}".format(sys.prefix))', silent=True, log=False, ) # Let's patch nox to make it run and in particular, install, to the system python session._runner.venv = VirtualEnv( sys_prefix, interpreter=session._runner.func.python, reuse_existing=True) finally: session._runner.global_config.install_only = old_install_only_value
def mkdocs_bin(): """Find mkdocs binary in default venv.""" location = Path(DEFAULT_VENV_NAME) venv = VirtualEnv(location.resolve()) venv_bin = Path(venv.bin) mkdocs = venv_bin / 'mkdocs' return mkdocs
def _create_venv(self): if self.func.python is False: self.venv = ProcessEnv() return path = _normalize_path(self.global_config.envdir, self.friendly_name) reuse_existing = (self.func.reuse_venv or self.global_config.reuse_existing_virtualenvs) if not self.func.venv_backend or self.func.venv_backend == "virtualenv": self.venv = VirtualEnv(path, interpreter=self.func.python, reuse_existing=reuse_existing) elif self.func.venv_backend == "conda": self.venv = CondaEnv(path, interpreter=self.func.python, reuse_existing=reuse_existing) elif self.func.venv_backend == "venv": self.venv = VirtualEnv( path, interpreter=self.func.python, reuse_existing=reuse_existing, venv=True, ) else: raise ValueError( "Expected venv_backend one of ('virtualenv', 'conda', 'venv'), but got '{}'." .format(self.func.venv_backend)) self.venv.create()
def get_venv(venv): """ Return `Path` objects from the venv. :param str venv: venv name :return: the venv `Path`, the `bin` folder `Path` within the venv, and if specified, the `Path` object of the activate script within the venv. :rtype: a tuple of 3 `Path` objects. """ location = Path(venv) venv = VirtualEnv(location.resolve()) venv_bin = Path(venv.bin) activate = venv_bin / 'activate' return venv, venv_bin, activate
def _lint_pre_commit(session, rcfile, flags, paths): if "VIRTUAL_ENV" not in os.environ: session.error( "This should be running from within a virtualenv and " "'VIRTUAL_ENV' was not found as an environment variable.") if "pre-commit" not in os.environ["VIRTUAL_ENV"]: session.error( "This should be running from within a pre-commit virtualenv and " "'VIRTUAL_ENV'({}) does not appear to be a pre-commit virtualenv.". format(os.environ["VIRTUAL_ENV"])) # Let's patch nox to make it run inside the pre-commit virtualenv session._runner.venv = VirtualEnv( os.environ["VIRTUAL_ENV"], interpreter=session._runner.func.python, reuse_existing=True, venv=True, ) _lint(session, rcfile, flags, paths, tee_output=False)
def _create_venv(self) -> None: backend = ( self.global_config.force_venv_backend or self.func.venv_backend or self.global_config.default_venv_backend ) if backend == "none" or self.func.python is False: self.venv = PassthroughEnv() return reuse_existing = ( self.func.reuse_venv or self.global_config.reuse_existing_virtualenvs ) if backend is None or backend == "virtualenv": self.venv = VirtualEnv( self.envdir, interpreter=self.func.python, # type: ignore reuse_existing=reuse_existing, venv_params=self.func.venv_params, ) elif backend == "conda": self.venv = CondaEnv( self.envdir, interpreter=self.func.python, # type: ignore reuse_existing=reuse_existing, venv_params=self.func.venv_params, ) elif backend == "venv": self.venv = VirtualEnv( self.envdir, interpreter=self.func.python, # type: ignore reuse_existing=reuse_existing, venv=True, venv_params=self.func.venv_params, ) else: raise ValueError( "Expected venv_backend one of ('virtualenv', 'conda', 'venv'), but got '{}'.".format( backend ) ) self.venv.create()
class SessionRunner(object): def __init__(self, name, signature, func, global_config, manifest=None): self.name = name self.signature = signature self.func = func self.global_config = global_config self.manifest = manifest self.venv = None def __str__(self): return self.signature or self.name def _create_venv(self): if self.func.python is False: self.venv = ProcessEnv() return name = self.signature or self.name path = _normalize_path(self.global_config.envdir, name) reuse_existing = (self.func.reuse_venv or self.global_config.reuse_existing_virtualenvs) self.venv = VirtualEnv(path, interpreter=self.func.python, reuse_existing=reuse_existing) self.venv.create() def execute(self): session_friendly_name = self.signature or self.name logger.warning('Running session {}'.format(session_friendly_name)) try: # By default, nox should quietly change to the directory where # the nox.py file is located. cwd = py.path.local( os.path.realpath(os.path.dirname( self.global_config.noxfile))).as_cwd() with cwd: self._create_venv() session = Session(self) self.func(session) # Nothing went wrong; return a success. return Result(self, Status.SUCCESS) except _SessionQuit: return Result(self, Status.ABORTED) except _SessionSkip: return Result(self, Status.SKIPPED) except nox.command.CommandFailed: return Result(self, Status.FAILED) except KeyboardInterrupt: logger.error('Session {} interrupted.'.format(self)) raise except Exception as exc: logger.exception('Session {} raised exception {!r}'.format( self, exc)) return Result(self, Status.FAILED)
class Session(object): def __init__(self, name, signature, func, global_config): self.name = name self.signature = signature self.func = func self.global_config = global_config self._should_install_deps = True def _create_config(self): self.config = SessionConfig(posargs=self.global_config.posargs) # By default, nox should quietly change to the directory where # the nox.py file is located. cwd = os.path.realpath(os.path.dirname(self.global_config.noxfile)) self.config.chdir(cwd, debug=True) # Run the actual session function, passing it the newly-created # SessionConfig object. try: self.func(self.config) return True except _SessionQuit: return False def _create_venv(self): if not self.config.virtualenv: self.venv = ProcessEnv() self._should_install_deps = False return virtualenv_name = (self.config.virtualenv_dirname or self.signature or self.name) self.venv = VirtualEnv( _normalize_path(self.global_config.envdir, virtualenv_name), interpreter=self.config.interpreter, reuse_existing=(self.config.reuse_existing_virtualenv or self.global_config.reuse_existing_virtualenvs)) self._should_install_deps = self.venv.create() def _run_commands(self): env = self.venv.env.copy() env.update(self.config.env) for command in self.config._commands: if isinstance(command, Command): command(path_override=self.venv.bin, env_fallback=env) elif isinstance(command, InstallCommand): if not self._should_install_deps: logger.debug( 'Skipping installation of "{}".'.format(command)) continue else: command(self.venv) else: command() def execute(self): session_friendly_name = self.signature or self.name logger.warning('Running session {}'.format(session_friendly_name)) try: if not self._create_config(): logger.error( 'Session {} aborted.'.format(session_friendly_name)) return False self._create_venv() cwd = py.path.local(os.getcwd()).as_cwd() with cwd: self._run_commands() logger.success( 'Session {} successful. :)'.format(session_friendly_name)) return True except CommandFailed: logger.error('Session {} failed. :('.format(session_friendly_name)) return False except KeyboardInterrupt: logger.error( 'Session {} interrupted.'.format(session_friendly_name)) raise
class SessionRunner: def __init__( self, name: str, signatures: List[str], func: Func, global_config: argparse.Namespace, manifest: "Optional[Manifest]" = None, ) -> None: self.name = name self.signatures = signatures self.func = func self.global_config = global_config self.manifest = manifest self.venv = None # type: Optional[ProcessEnv] @property def description(self) -> Optional[str]: doc = self.func.__doc__ if doc: first_line = doc.strip().split("\n")[0] return first_line return None def __str__(self) -> str: sigs = ", ".join(self.signatures) return "Session(name={}, signatures={})".format(self.name, sigs) @property def friendly_name(self) -> str: return self.signatures[0] if self.signatures else self.name def _create_venv(self) -> None: if self.func.python is False: self.venv = ProcessEnv() return path = _normalize_path(self.global_config.envdir, self.friendly_name) reuse_existing = (self.func.reuse_venv or self.global_config.reuse_existing_virtualenvs) if not self.func.venv_backend or self.func.venv_backend == "virtualenv": self.venv = VirtualEnv( path, interpreter=self.func.python, # type: ignore reuse_existing=reuse_existing, venv_params=self.func.venv_params, ) elif self.func.venv_backend == "conda": self.venv = CondaEnv( path, interpreter=self.func.python, # type: ignore reuse_existing=reuse_existing, venv_params=self.func.venv_params, ) elif self.func.venv_backend == "venv": self.venv = VirtualEnv( path, interpreter=self.func.python, # type: ignore reuse_existing=reuse_existing, venv=True, venv_params=self.func.venv_params, ) else: raise ValueError( "Expected venv_backend one of ('virtualenv', 'conda', 'venv'), but got '{}'." .format(self.func.venv_backend)) self.venv.create() # type: ignore def execute(self) -> "Result": logger.warning("Running session {}".format(self.friendly_name)) try: # By default, nox should quietly change to the directory where # the noxfile.py file is located. cwd = py.path.local( os.path.realpath(os.path.dirname( self.global_config.noxfile))).as_cwd() with cwd: self._create_venv() session = Session(self) self.func(session) # Nothing went wrong; return a success. return Result(self, Status.SUCCESS) except nox.virtualenv.InterpreterNotFound as exc: if self.global_config.error_on_missing_interpreters: return Result(self, Status.FAILED, reason=str(exc)) else: return Result(self, Status.SKIPPED, reason=str(exc)) except _SessionQuit as exc: return Result(self, Status.ABORTED, reason=str(exc)) except _SessionSkip as exc: return Result(self, Status.SKIPPED, reason=str(exc)) except nox.command.CommandFailed: return Result(self, Status.FAILED) except KeyboardInterrupt: logger.error("Session {} interrupted.".format(self.friendly_name)) raise except Exception as exc: logger.exception("Session {} raised exception {!r}".format( self.friendly_name, exc)) return Result(self, Status.FAILED)
class SessionRunner: def __init__(self, name, signatures, func, global_config, manifest=None): self.name = name self.signatures = signatures self.func = func self.global_config = global_config self.manifest = manifest self.venv = None @property def description(self): doc = self.func.__doc__ if doc: first_line = doc.strip().split("\n")[0] return first_line return None def __str__(self): sigs = ", ".join(self.signatures) return "Session(name={}, signatures={})".format(self.name, sigs) @property def friendly_name(self): return self.signatures[0] if self.signatures else self.name def _create_venv(self): if self.func.python is False: self.venv = ProcessEnv() return path = _normalize_path(self.global_config.envdir, self.friendly_name) reuse_existing = ( self.func.reuse_venv or self.global_config.reuse_existing_virtualenvs ) self.venv = VirtualEnv( path, interpreter=self.func.python, reuse_existing=reuse_existing ) self.venv.create() def execute(self): logger.warning("Running session {}".format(self.friendly_name)) try: # By default, nox should quietly change to the directory where # the noxfile.py file is located. cwd = py.path.local( os.path.realpath(os.path.dirname(self.global_config.noxfile)) ).as_cwd() with cwd: self._create_venv() session = Session(self) self.func(session) # Nothing went wrong; return a success. return Result(self, Status.SUCCESS) except nox.virtualenv.InterpreterNotFound as exc: if self.global_config.error_on_missing_interpreters: return Result(self, Status.FAILED, reason=str(exc)) else: return Result(self, Status.SKIPPED, reason=str(exc)) except _SessionQuit as exc: return Result(self, Status.ABORTED, reason=str(exc)) except _SessionSkip as exc: return Result(self, Status.SKIPPED, reason=str(exc)) except nox.command.CommandFailed: return Result(self, Status.FAILED) except KeyboardInterrupt: logger.error("Session {} interrupted.".format(self.friendly_name)) raise except Exception as exc: logger.exception( "Session {} raised exception {!r}".format(self.friendly_name, exc) ) return Result(self, Status.FAILED)
class Session(object): def __init__(self, name, signature, func, global_config, manifest=None): self.name = name self.signature = signature self.func = func self.global_config = global_config self.manifest = manifest self._should_install_deps = True def __str__(self): return utils.coerce_str(self.signature or self.name) def _create_config(self): self.config = SessionConfig(posargs=self.global_config.posargs) # By default, nox should quietly change to the directory where # the nox.py file is located. cwd = os.path.realpath(os.path.dirname(self.global_config.noxfile)) self.config.chdir(cwd, debug=True) # Run the actual session function, passing it the newly-created # SessionConfig object. self.func(self.config) def _create_venv(self): if not self.config.virtualenv: self.venv = ProcessEnv() self._should_install_deps = False return virtualenv_name = ( self.config.virtualenv_dirname or self.signature or self.name) self.venv = VirtualEnv( _normalize_path( self.global_config.envdir, virtualenv_name), interpreter=self.config.interpreter, reuse_existing=( self.config.reuse_existing_virtualenv or self.global_config.reuse_existing_virtualenvs)) self._should_install_deps = self.venv.create() def _run_commands(self): env = self.venv.env.copy() env.update(self.config.env) for command in self.config._commands: if isinstance(command, Command): command( env_fallback=env, path_override=self.venv.bin, session=self, ) elif isinstance(command, InstallCommand): if not self._should_install_deps: logger.debug( 'Skipping installation of "{}".'.format(command)) continue else: command(self.venv) else: command() def execute(self): session_friendly_name = self.signature or self.name logger.warning('Running session {}'.format(session_friendly_name)) try: # Set up the SessionConfig object (which session functions refer # to as `session`) and then the virtualenv. self._create_config() self._create_venv() # Run the actual commands prescribed by the session. cwd = py.path.local(os.getcwd()).as_cwd() with cwd: self._run_commands() # Nothing went wrong; return a success. return Result(self, Status.SUCCESS) except _SessionQuit: return Result(self, Status.ABORTED) except _SessionSkip: return Result(self, Status.SKIPPED) except CommandFailed: return Result(self, Status.FAILED) except KeyboardInterrupt: logger.error('Session {} interrupted.'.format(self)) raise
class Session(object): def __init__(self, name, signature, func, global_config): self.name = name self.signature = signature self.func = func self.global_config = global_config def _create_config(self): self.config = SessionConfig(posargs=self.global_config.posargs) self.func(self.config) def _create_venv(self): self.venv = VirtualEnv( os.path.join(self.global_config.envdir, self.name), interpreter=self.config.interpreter, reuse_existing=(self.config.reuse_existing_virtualenv or self.global_config.reuse_existing_virtualenvs)) self.venv.create() def _install_dependencies(self): for dep in self.config._dependencies: self.venv.install(*dep) def _run_commands(self): env = self.venv.env.copy() env.update(self.config.env) for command in self.config._commands: if isinstance(command, Command): command.path = self.venv.bin command.env = env command() else: command() def execute(self): logger.warning('Running session {}'.format(self.signature or self.name)) try: self._create_config() self._create_venv() self._install_dependencies() if self.config._dir != '.': logger.info('Changing directory to {}'.format( self.config._dir)) cwd = py.path.local(self.config._dir).as_cwd() with cwd: self._run_commands() logger.success('Session {} successful. :)'.format(self.name)) return True except CommandFailed: logger.error('Session {} failed. :('.format(self.name)) return False except KeyboardInterrupt: logger.error('Session {} interrupted.'.format(self.name)) raise
class SessionRunner: def __init__( self, name: str, signatures: list[str], func: Func, global_config: argparse.Namespace, manifest: Manifest, ) -> None: self.name = name self.signatures = signatures self.func = func self.global_config = global_config self.manifest = manifest self.venv: ProcessEnv | None = None self.posargs: list[str] = global_config.posargs[:] @property def description(self) -> str | None: doc = self.func.__doc__ if doc: first_line = doc.strip().split("\n")[0] return first_line return None def __str__(self) -> str: sigs = ", ".join(self.signatures) return f"Session(name={self.name}, signatures={sigs})" @property def friendly_name(self) -> str: return self.signatures[0] if self.signatures else self.name @property def tags(self) -> list[str]: return self.func.tags @property def envdir(self) -> str: return _normalize_path(self.global_config.envdir, self.friendly_name) def _create_venv(self) -> None: backend = (self.global_config.force_venv_backend or self.func.venv_backend or self.global_config.default_venv_backend) if backend == "none" or self.func.python is False: self.venv = PassthroughEnv() return reuse_existing = (self.func.reuse_venv or self.global_config.reuse_existing_virtualenvs) if backend is None or backend == "virtualenv": self.venv = VirtualEnv( self.envdir, interpreter=self.func.python, # type: ignore[arg-type] reuse_existing=reuse_existing, venv_params=self.func.venv_params, ) elif backend in {"conda", "mamba"}: self.venv = CondaEnv( self.envdir, interpreter=self.func.python, # type: ignore[arg-type] reuse_existing=reuse_existing, venv_params=self.func.venv_params, conda_cmd=backend, ) elif backend == "venv": self.venv = VirtualEnv( self.envdir, interpreter=self.func.python, # type: ignore[arg-type] reuse_existing=reuse_existing, venv=True, venv_params=self.func.venv_params, ) else: raise ValueError( "Expected venv_backend one of ('virtualenv', 'conda', 'mamba'," f" 'venv'), but got '{backend}'.") self.venv.create() def execute(self) -> Result: logger.warning(f"Running session {self.friendly_name}") try: # By default, Nox should quietly change to the directory where # the noxfile.py file is located. cwd = py.path.local( os.path.realpath(os.path.dirname( self.global_config.noxfile))).as_cwd() with cwd: self._create_venv() session = Session(self) self.func(session) # Nothing went wrong; return a success. return Result(self, Status.SUCCESS) except nox.virtualenv.InterpreterNotFound as exc: if self.global_config.error_on_missing_interpreters: return Result(self, Status.FAILED, reason=str(exc)) else: logger.warning( "Missing interpreters will error by default on CI systems." ) return Result(self, Status.SKIPPED, reason=str(exc)) except _SessionQuit as exc: return Result(self, Status.ABORTED, reason=str(exc)) except _SessionSkip as exc: return Result(self, Status.SKIPPED, reason=str(exc)) except nox.command.CommandFailed: return Result(self, Status.FAILED) except KeyboardInterrupt: logger.error(f"Session {self.friendly_name} interrupted.") raise except Exception as exc: logger.exception( f"Session {self.friendly_name} raised exception {exc!r}") return Result(self, Status.FAILED)