def test_add_session_multiple_pythons(): manifest = Manifest({}, create_mock_config()) def session_func(): pass func = Func(session_func, python=["3.5", "3.6"]) for session in manifest.make_session("my_session", func): manifest.add_session(session) assert len(manifest) == 2
def test_add_session_multiple_pythons(): manifest = Manifest({}, mock.sentinel.CONFIG) def session_func(): pass func = Func(session_func, python=["3.5", "3.6"]) for session in manifest.make_session("my_session", func): manifest.add_session(session) assert len(manifest) == 2
def test_notify_with_posargs(): cfg = create_mock_config() manifest = Manifest({}, cfg) session = manifest.make_session("my_session", Func(lambda session: None))[0] manifest.add_session(session) # delete my_session from the queue manifest.filter_by_name(()) assert session.posargs == cfg.posargs assert manifest.notify("my_session", posargs=["--an-arg"]) assert session.posargs == ["--an-arg"]
def test_add_session_parametrized_multiple_pythons(): manifest = Manifest({}, create_mock_config()) # Define a session with parameters. @nox.parametrize("param", ("a", "b")) def my_session(session, param): pass func = Func(my_session, python=["2.7", "3.6"]) # Add the session to the manifest. for session in manifest.make_session("my_session", func): manifest.add_session(session) assert len(manifest) == 4
def test_extra_pythons(python, extra_pythons, expected): cfg = create_mock_config() cfg.extra_pythons = extra_pythons manifest = Manifest({}, cfg) def session_func(): pass func = Func(session_func, python=python) for session in manifest.make_session("my_session", func): manifest.add_session(session) assert expected == [session.func.python for session in manifest._all_sessions]
def test_add_session_parametrized(): manifest = Manifest({}, mock.sentinel.CONFIG) # Define a session with parameters. @nox.parametrize("param", ("a", "b", "c")) def my_session(session, param): pass func = Func(my_session, python=None) # Add the session to the manifest. for session in manifest.make_session("my_session", func): manifest.add_session(session) assert len(manifest) == 3
def test_extra_pythons(python, extra_pythons, expected): cfg = mock.sentinel.CONFIG cfg.force_venv_backend = None cfg.default_venv_backend = None cfg.extra_pythons = extra_pythons manifest = Manifest({}, cfg) def session_func(): pass func = Func(session_func, python=python) for session in manifest.make_session("my_session", func): manifest.add_session(session) assert expected == [ session.func.python for session in manifest._all_sessions ]
def make_session(self, name: str, func: Func, multi: bool = False) -> list[SessionRunner]: """Create a session object from the session function. Args: name (str): The name of the session. func (function): The session function. multi (bool): Whether the function is a member of a set of sessions with different interpreters. Returns: Sequence[~nox.session.Session]: A sequence of Session objects bound to this manifest and configuration. """ sessions = [] # If the backend is "none", we won't parametrize `python`. backend = (self._config.force_venv_backend or func.venv_backend or self._config.default_venv_backend) if backend == "none" and isinstance(func.python, (list, tuple, set)): # we can not log a warning here since the session is maybe deselected. # instead let's set a flag, to warn later when session is actually run. func.should_warn[WARN_PYTHONS_IGNORED] = func.python func.python = False if self._config.extra_pythons: # If extra python is provided, expand the func.python list to # include additional python interpreters extra_pythons: list[str] = self._config.extra_pythons if isinstance(func.python, (list, tuple, set)): func.python = _unique_list(*func.python, *extra_pythons) elif not multi and func.python: # If this is multi, but there is only a single interpreter, it # is the reentrant case. The extra_python interpreter shouldn't # be added in that case. If func.python is False, the session # has no backend; if None, it uses the same interpreter as Nox. # Otherwise, add the extra specified python. assert isinstance(func.python, str) func.python = _unique_list(func.python, *extra_pythons) # If the func has the python attribute set to a list, we'll need # to expand them. if isinstance(func.python, (list, tuple, set)): for python in func.python: single_func = func.copy() single_func.python = python sessions.extend( self.make_session(name, single_func, multi=True)) return sessions # Simple case: If this function is not parametrized, then make # a simple session. if not hasattr(func, "parametrize"): long_names = [] if not multi: long_names.append(name) if func.python: long_names.append(f"{name}-{func.python}") return [SessionRunner(name, long_names, func, self._config, self)] # Since this function is parametrized, we need to add a distinct # session for each permutation. parametrize = func.parametrize # type: ignore[attr-defined] calls = Call.generate_calls(func, parametrize) for call in calls: long_names = [] if not multi: long_names.append(f"{name}{call.session_signature}") if func.python: long_names.append( f"{name}-{func.python}{call.session_signature}") # Ensure that specifying session-python will run all parameterizations. long_names.append(f"{name}-{func.python}") sessions.append( SessionRunner(name, long_names, call, self._config, self)) # Edge case: If the parameters made it such that there were no valid # calls, add an empty, do-nothing session. if not calls: sessions.append( SessionRunner(name, [], _null_session_func, self._config, self)) # Return the list of sessions. return sessions
return eval(expression, {}, locals) def _null_session_func_(session: Session) -> None: """A no-op session for patemetrized sessions with no available params.""" session.skip("This session had no parameters available.") def _normalized_session_match(session_name: str, session: SessionRunner) -> bool: """Checks if session_name matches session.""" if session_name == session.name or session_name in session.signatures: return True for name in session.signatures: equal_rep = _normalize_arg(session_name) == _normalize_arg(name) if equal_rep: return True # Exhausted return False def _normalize_arg(arg: str) -> str: """Normalize arg for comparison.""" try: return str(ast.dump(ast.parse(arg))) except (TypeError, SyntaxError): return arg _null_session_func = Func(_null_session_func_, python=False)