Skip to content

Commit

Permalink
Remove more type ignore comments (#297)
Browse files Browse the repository at this point in the history
* Change `Session.virtualenv` to not return None.

* Change `KeywordLocals` to a mapping

* Change manifest to be a required argument

* Change `Session.bin` to optional.

* Allow `int` as a module to `discover_manifest`

* Improve code coverage

* Fix CI issues
  • Loading branch information
Peilonrayz authored Mar 16, 2020
1 parent ca6f2c2 commit 98148d7
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 17 deletions.
2 changes: 1 addition & 1 deletion nox/_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def _session_completer(
) -> List[str]:
global_config = parsed_args
module = load_nox_module(global_config)
manifest = discover_manifest(module, global_config) # type: ignore
manifest = discover_manifest(module, global_config)
filtered_manifest = filter_manifest(manifest, global_config)
if isinstance(filtered_manifest, int):
return []
Expand Down
11 changes: 9 additions & 2 deletions nox/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# limitations under the License.

import argparse
import collections.abc
import itertools
from typing import Any, Iterable, Iterator, List, Mapping, Set, Tuple, Union

Expand Down Expand Up @@ -243,7 +244,7 @@ def notify(self, session: Union[str, SessionRunner]) -> bool:
raise ValueError("Session {} not found.".format(session))


class KeywordLocals:
class KeywordLocals(collections.abc.Mapping):
"""Eval locals using keywords.
When looking up a local variable the variable name is compared against
Expand All @@ -261,11 +262,17 @@ def __getitem__(self, variable_name: str) -> bool:
return True
return False

def __iter__(self) -> Iterator[str]:
return iter(self._keywords)

def __len__(self) -> int:
return len(self._keywords)


def keyword_match(expression: str, keywords: Iterable[str]) -> Any:
"""See if an expression matches the given set of keywords."""
locals = KeywordLocals(set(keywords))
return eval(expression, {}, locals) # type: ignore
return eval(expression, {}, locals)


def _null_session_func_(session: Session) -> None:
Expand Down
28 changes: 16 additions & 12 deletions nox/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def __dict__(self) -> "Dict[str, SessionRunner]": # type: ignore
@property
def env(self) -> dict:
"""A dictionary of environment variables to pass into all commands."""
return self._runner.venv.env # type: ignore
return self.virtualenv.env

@property
def posargs(self) -> List[str]:
Expand All @@ -118,19 +118,22 @@ def posargs(self) -> List[str]:
return self._runner.global_config.posargs

@property
def virtualenv(self) -> Optional[ProcessEnv]:
def virtualenv(self) -> ProcessEnv:
"""The virtualenv that all commands are run in."""
return self._runner.venv
venv = self._runner.venv
if venv is None:
raise ValueError("A virtualenv has not been created for this session")
return venv

@property
def python(self) -> Optional[Union[str, Sequence[str], bool]]:
"""The python version passed into ``@nox.session``."""
return self._runner.func.python

@property
def bin(self) -> str:
def bin(self) -> Optional[str]:
"""The bin directory for the virtualenv."""
return self._runner.venv.bin # type: ignore
return self.virtualenv.bin

@property
def interactive(self) -> bool:
Expand Down Expand Up @@ -233,10 +236,10 @@ def _run(self, *args: str, env: Mapping[str, str] = None, **kwargs: Any) -> Any:
kwargs.setdefault("external", "error")

# Allow all external programs when running outside a sandbox.
if not self.virtualenv.is_sandboxed: # type: ignore
if not self.virtualenv.is_sandboxed:
kwargs["external"] = True

if args[0] in self.virtualenv.allowed_globals: # type: ignore
if args[0] in self.virtualenv.allowed_globals:
kwargs["external"] = True

# Run a shell command.
Expand Down Expand Up @@ -268,7 +271,8 @@ def conda_install(self, *args: str, **kwargs: Any) -> None:
.. _conda install:
"""
if not isinstance(self.virtualenv, CondaEnv):
venv = self._runner.venv
if not isinstance(venv, CondaEnv):
raise ValueError(
"A session without a conda environment can not install dependencies from conda."
)
Expand All @@ -283,7 +287,7 @@ def conda_install(self, *args: str, **kwargs: Any) -> None:
"install",
"--yes",
"--prefix",
self.virtualenv.location,
venv.location,
*args,
external="error",
**kwargs
Expand Down Expand Up @@ -314,7 +318,7 @@ def install(self, *args: str, **kwargs: Any) -> None:
.. _pip: https://pip.readthedocs.org
"""
if not isinstance(self.virtualenv, (CondaEnv, VirtualEnv)):
if not isinstance(self._runner.venv, (CondaEnv, VirtualEnv)):
raise ValueError(
"A session without a virtualenv can not install dependencies."
)
Expand All @@ -337,7 +341,7 @@ def notify(self, target: "Union[str, SessionRunner]") -> None:
may be specified as the appropriate string (same as used for
``nox -s``) or using the function object.
"""
self._runner.manifest.notify(target) # type: ignore
self._runner.manifest.notify(target)

def log(self, *args: Any, **kwargs: Any) -> None:
"""Outputs a log during the session."""
Expand All @@ -359,7 +363,7 @@ def __init__(
signatures: List[str],
func: Func,
global_config: argparse.Namespace,
manifest: "Optional[Manifest]" = None,
manifest: "Manifest",
) -> None:
self.name = name
self.signatures = signatures
Expand Down
4 changes: 3 additions & 1 deletion nox/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ def merge_noxfile_options(
return module


def discover_manifest(module: types.ModuleType, global_config: Namespace) -> Manifest:
def discover_manifest(
module: Union[types.ModuleType, int], global_config: Namespace
) -> Manifest:
"""Discover all session functions in the noxfile module.
Args:
Expand Down
13 changes: 12 additions & 1 deletion tests/test_manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import nox
import pytest
from nox._decorators import Func
from nox.manifest import Manifest, _null_session_func
from nox.manifest import KeywordLocals, Manifest, _null_session_func


def create_mock_sessions():
Expand Down Expand Up @@ -301,3 +301,14 @@ def test_null_session_function():
session = mock.Mock(spec=("skip",))
_null_session_func(session)
assert session.skip.called


def test_keyword_locals_length():
kw = KeywordLocals({"foo", "bar"})
assert len(kw) == 2


def test_keyword_locals_iter():
values = ["foo", "bar"]
kw = KeywordLocals(values)
assert list(kw) == values
8 changes: 8 additions & 0 deletions tests/test_sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ def test_properties(self):
assert session.bin is runner.venv.bin
assert session.python is runner.func.python

def test_virtualenv_as_none(self):
session, runner = self.make_session_and_runner()

runner.venv = None

with pytest.raises(ValueError, match="virtualenv"):
_ = session.virtualenv

def test_interactive(self):
session, runner = self.make_session_and_runner()

Expand Down

0 comments on commit 98148d7

Please sign in to comment.