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 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 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 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(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, 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 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)