diff --git a/.flake8 b/.flake8 new file mode 100644 index 00000000..4c0072ea --- /dev/null +++ b/.flake8 @@ -0,0 +1,6 @@ +[flake8] +# Ignore black styles. +ignore = E501, W503 +# Imports +import-order-style = google +application-import-names = nox,tests diff --git a/nox.py b/nox.py index d76d6ea0..b86c7a41 100644 --- a/nox.py +++ b/nox.py @@ -17,55 +17,50 @@ import nox -ON_APPVEYOR = os.environ.get('APPVEYOR') == 'True' +ON_APPVEYOR = os.environ.get("APPVEYOR") == "True" -@nox.session(python=['3.5', '3.6', '3.7']) +@nox.session(python=["3.5", "3.6", "3.7"]) def tests(session): - session.install('-r', 'requirements-test.txt') - session.install('-e', '.[tox_to_nox]') - tests = session.posargs or ['tests/'] + session.install("-r", "requirements-test.txt") + session.install("-e", ".[tox_to_nox]") + tests = session.posargs or ["tests/"] session.run( - 'py.test', '--cov=nox', '--cov-config', '.coveragerc', - '--cov-report=', *tests) - session.notify('cover') + "py.test", "--cov=nox", "--cov-config", ".coveragerc", "--cov-report=", *tests + ) + session.notify("cover") @nox.session def cover(session): - session.install('coverage') + session.install("coverage") if ON_APPVEYOR: - fail_under = '--fail-under=99' + fail_under = "--fail-under=99" else: - fail_under = '--fail-under=100' - session.run( - 'coverage', - 'report', - fail_under, - '--show-missing', - ) - session.run('coverage', 'erase') + fail_under = "--fail-under=100" + session.run("coverage", "report", fail_under, "--show-missing") + session.run("coverage", "erase") -@nox.session +@nox.session(python="3.6") +def blacken(session): + session.install("black") + session.run("black", "nox", "tests", "nox.py", "setup.py") + + +@nox.session(python="3.6") def lint(session): - session.install('flake8', 'flake8-import-order') - session.run( - 'flake8', - '--import-order-style=google', - '--application-import-names=nox,tests', - 'nox', 'tests') + session.install("flake8", "flake8-import-order", "black") + session.run("black", "--check", "nox", "tests", "nox.py", "setup.py") + session.run("flake8", "nox", "tests") -@nox.session(python='3.6') +@nox.session(python="3.6") def docs(session): - session.run('rm', '-rf', 'docs/_build') - session.install('-r', 'requirements-test.txt') - session.install('.') - session.cd('docs') + session.run("rm", "-rf", "docs/_build") + session.install("-r", "requirements-test.txt") + session.install(".") + session.cd("docs") session.run( - 'sphinx-build', - '-b', 'html', - '-W', - '-d', '_build/doctrees', - '.', '_build/html') + "sphinx-build", "-b", "html", "-W", "-d", "_build/doctrees", ".", "_build/html" + ) diff --git a/nox/__init__.py b/nox/__init__.py index 23b0dc50..1e1c238f 100644 --- a/nox/__init__.py +++ b/nox/__init__.py @@ -15,4 +15,4 @@ from nox._parametrize import parametrize_decorator as parametrize from nox.registry import session_decorator as session -__all__ = ['parametrize', 'session'] +__all__ = ["parametrize", "session"] diff --git a/nox/_parametrize.py b/nox/_parametrize.py index 90bf4533..04cedc80 100644 --- a/nox/_parametrize.py +++ b/nox/_parametrize.py @@ -36,8 +36,7 @@ def parametrize_decorator(arg_names, arg_values_list): # Allow args to be specified as any of 'arg', 'arg,arg2' or ('arg', 'arg2') if not isinstance(arg_names, (list, tuple)): - arg_names = list( - filter(None, [arg.strip() for arg in arg_names.split(',')])) + arg_names = list(filter(None, [arg.strip() for arg in arg_names.split(",")])) # If there's only one arg_name, arg_values_list should be a single item # or list. Transform it so it'll work with the combine step. @@ -56,10 +55,9 @@ def parametrize_decorator(arg_names, arg_values_list): call_specs.append(call_spec) def inner(f): - previous_call_specs = getattr(f, 'parametrize', None) - new_call_specs = update_call_specs( - previous_call_specs, call_specs) - setattr(f, 'parametrize', new_call_specs) + previous_call_specs = getattr(f, "parametrize", None) + new_call_specs = update_call_specs(previous_call_specs, call_specs) + setattr(f, "parametrize", new_call_specs) return f return inner @@ -79,10 +77,8 @@ def update_call_specs(call_specs, new_specs): def generate_session_signature(func, call_spec): - args = [ - '{}={}'.format(k, repr(call_spec[k])) - for k in sorted(call_spec.keys())] - return '({})'.format(', '.join(args)) + args = ["{}={}".format(k, repr(call_spec[k])) for k in sorted(call_spec.keys())] + return "({})".format(", ".join(args)) def generate_calls(func, call_specs): @@ -94,6 +90,7 @@ def make_call_wrapper(call_spec): def call_wrapper(*args, **kwargs): kwargs.update(call_spec) return func(*args, **kwargs) + return call_wrapper call = make_call_wrapper(call_spec) diff --git a/nox/command.py b/nox/command.py index 8e762213..d08e088f 100644 --- a/nox/command.py +++ b/nox/command.py @@ -23,6 +23,7 @@ class CommandFailed(Exception): """Raised when an executed command returns a non-success status code.""" + def __init__(self, reason=None): super(CommandFailed, self).__init__(reason) self.reason = reason @@ -43,8 +44,8 @@ def which(program, path): if full_path: return full_path.strpath - logger.error('Program {} not found.'.format(program)) - raise CommandFailed('Program {} not found'.format(program)) + logger.error("Program {} not found.".format(program)) + raise CommandFailed("Program {} not found".format(program)) def _clean_env(env): @@ -55,27 +56,24 @@ def _clean_env(env): clean_env = {} # Ensure systemroot is passed down, otherwise Windows will explode. - clean_env['SYSTEMROOT'] = os.environ.get('SYSTEMROOT', '') + clean_env["SYSTEMROOT"] = os.environ.get("SYSTEMROOT", "") for key, value in env.items(): - key = key.decode('utf-8') if isinstance(key, bytes) else key - value = ( - value.decode('utf-8') if isinstance(value, bytes) else value) + key = key.decode("utf-8") if isinstance(key, bytes) else key + value = value.decode("utf-8") if isinstance(value, bytes) else value clean_env[key] = value return clean_env -def run(args, *, env=None, silent=False, path=None, - success_codes=None, log=True): +def run(args, *, env=None, silent=False, path=None, success_codes=None, log=True): """Run a command-line program.""" if success_codes is None: success_codes = [0] cmd, args = args[0], args[1:] - full_cmd = '{} {}'.format( - cmd, ' '.join(args)) + full_cmd = "{} {}".format(cmd, " ".join(args)) cmd_path = which(cmd, path) @@ -85,22 +83,22 @@ def run(args, *, env=None, silent=False, path=None, env = _clean_env(env) try: - return_code, output = popen( - [cmd_path] + list(args), - silent=silent, - env=env) + return_code, output = popen([cmd_path] + list(args), silent=silent, env=env) if return_code not in success_codes: - logger.error('Command {} failed with exit code {}{}'.format( - full_cmd, return_code, ':' if silent else '')) + logger.error( + "Command {} failed with exit code {}{}".format( + full_cmd, return_code, ":" if silent else "" + ) + ) if silent: sys.stderr.write(output) - raise CommandFailed('Returned code {}'.format(return_code)) + raise CommandFailed("Returned code {}".format(return_code)) return output if silent else True except KeyboardInterrupt: - logger.error('Interrupted...') + logger.error("Interrupted...") raise diff --git a/nox/logger.py b/nox/logger.py index ae3c956f..082747ae 100644 --- a/nox/logger.py +++ b/nox/logger.py @@ -32,7 +32,7 @@ def success(self, msg, *args, **kwargs): logging.setLoggerClass(LoggerWithSuccess) -logger = logging.getLogger('nox') +logger = logging.getLogger("nox") logger.setLevel(logging.DEBUG) @@ -52,13 +52,13 @@ def setup_logging(color): # pragma: no cover "%(cyan)s%(name)s > %(log_color)s%(message)s", reset=True, log_colors={ - 'DEBUG': 'cyan', - 'INFO': 'blue', - 'WARNING': 'yellow', - 'ERROR': 'red', - 'CRITICAL': 'red,bg_white', - 'SUCCESS': 'green' - } + "DEBUG": "cyan", + "INFO": "blue", + "WARNING": "yellow", + "ERROR": "red", + "CRITICAL": "red,bg_white", + "SUCCESS": "green", + }, ) handler.setFormatter(formatter) @@ -66,4 +66,4 @@ def setup_logging(color): # pragma: no cover root_logger.addHandler(handler) # Silence noisy loggers - logging.getLogger('sh').setLevel(logging.WARNING) + logging.getLogger("sh").setLevel(logging.WARNING) diff --git a/nox/main.py b/nox/main.py index ebc508cf..098dc724 100644 --- a/nox/main.py +++ b/nox/main.py @@ -42,55 +42,74 @@ def __init__(self, args): self.posargs = args.posargs self.report = args.report - if self.posargs and self.posargs[0] == '--': + if self.posargs and self.posargs[0] == "--": self.posargs.pop(0) def main(): - parser = argparse.ArgumentParser( - description='nox is a Python automation toolkit.') + parser = argparse.ArgumentParser(description="nox is a Python automation toolkit.") parser.add_argument( - '-f', '--noxfile', default='nox.py', - help='Location of the Python file containing nox sessions.') + "-f", + "--noxfile", + default="nox.py", + help="Location of the Python file containing nox sessions.", + ) parser.add_argument( - '-l', '--list-sessions', action='store_true', - help='List all available sessions and exit.') + "-l", + "--list-sessions", + action="store_true", + help="List all available sessions and exit.", + ) parser.add_argument( - '--envdir', default='.nox', - help='Directory where nox will store virtualenvs.') + "--envdir", default=".nox", help="Directory where nox will store virtualenvs." + ) parser.add_argument( - '-s', '-e', '--sessions', nargs='*', - help='Which sessions to run, by default, all sessions will run.') + "-s", + "-e", + "--sessions", + nargs="*", + help="Which sessions to run, by default, all sessions will run.", + ) parser.add_argument( - '-k', '--keywords', - help='Only run sessions that match the given expression.') + "-k", "--keywords", help="Only run sessions that match the given expression." + ) parser.add_argument( - '-r', '--reuse-existing-virtualenvs', action='store_true', - help='Re-use existing virtualenvs instead of recreating them.') + "-r", + "--reuse-existing-virtualenvs", + action="store_true", + help="Re-use existing virtualenvs instead of recreating them.", + ) parser.add_argument( - '--stop-on-first-error', action='store_true', - help='Stop after the first error.') + "--stop-on-first-error", action="store_true", help="Stop after the first error." + ) parser.add_argument( - '--report', default=None, - help='Output a report of all sessions.') + "--report", default=None, help="Output a report of all sessions." + ) parser.add_argument( - '--nocolor', default=not sys.stderr.isatty(), action='store_true', - help='Disable all color output.') + "--nocolor", + default=not sys.stderr.isatty(), + action="store_true", + help="Disable all color output.", + ) parser.add_argument( - '--forcecolor', default=False, action='store_true', - help=('Force color output, even if stdout is not an interactive ' - 'terminal.')) + "--forcecolor", + default=False, + action="store_true", + help=("Force color output, even if stdout is not an interactive " "terminal."), + ) parser.add_argument( - 'posargs', nargs=argparse.REMAINDER, - help='Arguments that are passed through to the sessions.') + "posargs", + nargs=argparse.REMAINDER, + help="Arguments that are passed through to the sessions.", + ) parser.add_argument( - '--version', action='store_true', - help='Output the nox version and exit.') + "--version", action="store_true", help="Output the nox version and exit." + ) args = parser.parse_args() if args.version: - dist = pkg_resources.get_distribution('nox') + dist = pkg_resources.get_distribution("nox") print(dist.version, file=sys.stderr) return diff --git a/nox/manifest.py b/nox/manifest.py index 3f9256fa..12b42627 100644 --- a/nox/manifest.py +++ b/nox/manifest.py @@ -27,7 +27,8 @@ def _copy_func(src, name=None): src.__globals__, name=name or src.__name__, argdefs=src.__defaults__, - closure=src.__closure__) + closure=src.__closure__, + ) dst.__dict__.update(copy.deepcopy(src.__dict__)) dst = functools.update_wrapper(dst, src) dst.__kwdefaults__ = src.__kwdefaults__ @@ -49,6 +50,7 @@ class Manifest: session functions. global_config (.nox.main.GlobalConfig): The global configuration. """ + def __init__(self, session_functions, global_config): self._all_sessions = [] self._queue = [] @@ -116,19 +118,21 @@ def filter_by_name(self, specified_sessions): """ # Filter the sessions remaining in the queue based on # whether they are individually specified. - self._queue = [x for x in self._queue if ( - x.name in specified_sessions or - x.signature in specified_sessions)] + self._queue = [ + x + for x in self._queue + if (x.name in specified_sessions or x.signature in specified_sessions) + ] # If a session was requested and was not found, complain loudly. missing_sessions = set(specified_sessions) - set( itertools.chain( [x.name for x in self._all_sessions if x.name], - [x.signature for x in self._all_sessions if x.signature])) - if missing_sessions: - raise KeyError( - 'Sessions not found: {}'.format(', '.join(missing_sessions)), + [x.signature for x in self._all_sessions if x.signature], ) + ) + if missing_sessions: + raise KeyError("Sessions not found: {}".format(", ".join(missing_sessions))) def filter_by_keywords(self, keywords): """Filter sessions using pytest-like keyword expressions. @@ -138,8 +142,8 @@ def filter_by_keywords(self, keywords): session names are checked against. """ self._queue = [ - x for x in self._queue - if keyword_match(keywords, [x.signature or x.name])] + x for x in self._queue if keyword_match(keywords, [x.signature or x.name]) + ] def make_session(self, name, func): """Create a session object from the session function. @@ -166,9 +170,9 @@ def make_session(self, name, func): # Simple case: If this function is not parametrized, then make # a simple session - if not hasattr(func, 'parametrize'): + if not hasattr(func, "parametrize"): if func.python: - long_name = '{}-{}'.format(name, func.python) + long_name = "{}-{}".format(name, func.python) else: long_name = name session = SessionRunner(name, long_name, func, self._config, self) @@ -179,21 +183,17 @@ def make_session(self, name, func): calls = generate_calls(func, func.parametrize) for call in calls: if func.python: - long_name = '{}-{}{}'.format( - name, func.python, call.session_signature) + long_name = "{}-{}{}".format(name, func.python, call.session_signature) else: - long_name = '{}{}'.format( - name, call.session_signature) + long_name = "{}{}".format(name, call.session_signature) - sessions.append( - SessionRunner(name, long_name, call, self._config, self)) + sessions.append(SessionRunner(name, long_name, 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, None, _null_session_func, self._config, self), + SessionRunner(name, None, _null_session_func, self._config, self) ) # Return the list of sessions. @@ -231,7 +231,7 @@ def notify(self, session): return True # The session was not found in the list of sessions. - raise ValueError('Session %s not found.' % session) + raise ValueError("Session %s not found." % session) class KeywordLocals: @@ -242,6 +242,7 @@ class KeywordLocals: any keyword, then the name lookup returns True. Otherwise, the name lookup returns False. """ + def __init__(self, keywords): self._keywords = keywords @@ -260,4 +261,4 @@ def keyword_match(expression, keywords): def _null_session_func(session): """A no-op session for patemetrized sessions with no available params.""" - session.skip('This session had no parameters available.') + session.skip("This session had no parameters available.") diff --git a/nox/popen.py b/nox/popen.py index c975ff3b..82a07765 100644 --- a/nox/popen.py +++ b/nox/popen.py @@ -22,8 +22,7 @@ def popen(args, env=None, silent=False): if silent: stdout = subprocess.PIPE - proc = subprocess.Popen( - args, env=env, stdout=stdout, stderr=subprocess.STDOUT) + proc = subprocess.Popen(args, env=env, stdout=stdout, stderr=subprocess.STDOUT) try: out, err = proc.communicate() @@ -36,4 +35,4 @@ def popen(args, env=None, silent=False): return_code = proc.wait() - return return_code, out.decode('utf-8') if out else '' + return return_code, out.decode("utf-8") if out else "" diff --git a/nox/registry.py b/nox/registry.py index 7695587e..153d286d 100644 --- a/nox/registry.py +++ b/nox/registry.py @@ -19,8 +19,7 @@ _REGISTRY = collections.OrderedDict() -def session_decorator( - func=None, python=None, py=None, reuse_venv=None): +def session_decorator(func=None, python=None, py=None, reuse_venv=None): """Designate the decorated function as a session.""" # If `func` is provided, then this is the decorator call with the function # being sent as part of the Python syntax (`@nox.session`). @@ -31,12 +30,14 @@ def session_decorator( # This is what makes the syntax with and without parentheses both work. if func is None: return functools.partial( - session_decorator, python=python, py=py, reuse_venv=reuse_venv) + session_decorator, python=python, py=py, reuse_venv=reuse_venv + ) if py is not None and python is not None: raise ValueError( "The py argument to nox.session is an alias for the python " - "argument, please only specify one.") + "argument, please only specify one." + ) if python is None: python = py diff --git a/nox/sessions.py b/nox/sessions.py index 481b5bce..504dd82a 100644 --- a/nox/sessions.py +++ b/nox/sessions.py @@ -28,26 +28,26 @@ def _normalize_path(envdir, path): """Normalizes a string to be a "safe" filesystem path for a virtualenv.""" if isinstance(path, bytes): - path = path.decode('utf-8') + path = path.decode("utf-8") - path = unicodedata.normalize('NFKD', path).encode('ascii', 'ignore') - path = path.decode('ascii') - path = re.sub('[^\w\s-]', '-', path).strip().lower() - path = re.sub('[-\s]+', '-', path) - path = path.strip('-') + path = unicodedata.normalize("NFKD", path).encode("ascii", "ignore") + path = path.decode("ascii") + path = re.sub("[^\w\s-]", "-", path).strip().lower() + path = re.sub("[-\s]+", "-", path) + path = path.strip("-") full_path = os.path.join(envdir, path) - if len(full_path) > 100 - len('bin/pythonX.Y'): + if len(full_path) > 100 - len("bin/pythonX.Y"): if len(envdir) < 100 - 9: - path = hashlib.sha1(path.encode('ascii')).hexdigest()[:8] + path = hashlib.sha1(path.encode("ascii")).hexdigest()[:8] full_path = os.path.join(envdir, path) - logger.warning( - 'The virtualenv name was hashed to avoid being too long.') + logger.warning("The virtualenv name was hashed to avoid being too long.") else: logger.error( - 'The virtualenv path {} is too long and will cause issues on ' - 'some environments. Use the --envdir path to modify where ' - 'nox stores virtualenvs.'.format(full_path)) + "The virtualenv path {} is too long and will cause issues on " + "some environments. Use the --envdir path to modify where " + "nox stores virtualenvs.".format(full_path) + ) return full_path @@ -73,6 +73,7 @@ class Session: This is your primary means for installing package and running commands in your Nox session. """ + def __init__(self, runner): self._runner = runner @@ -99,7 +100,7 @@ def bin(self): def chdir(self, dir): """Change the current working directory.""" - self.log('cd {}'.format(dir)) + self.log("cd {}".format(dir)) os.chdir(dir) cd = chdir @@ -107,13 +108,11 @@ def chdir(self, dir): def _run_func(self, func, args, kwargs): """Legacy support for running a function through :func`run`.""" - self.log('{}(args={!r}, kwargs={!r})'.format( - func, args, kwargs)) + self.log("{}(args={!r}, kwargs={!r})".format(func, args, kwargs)) try: return func(*args, **kwargs) except Exception as e: - logger.exception('Function {!r} raised {!r}.'.format( - func, e)) + logger.exception("Function {!r} raised {!r}.".format(func, e)) raise nox.command.CommandFailed() def run(self, *args, env=None, **kwargs): @@ -153,7 +152,7 @@ def run(self, *args, env=None, **kwargs): :type success_codes: list, tuple, or None """ if not args: - raise ValueError('At least one argument required to run().') + raise ValueError("At least one argument required to run().") # Legacy support - run a function given. if callable(args[0]): @@ -168,12 +167,7 @@ def run(self, *args, env=None, **kwargs): env = self.env # Run a shell command. - return nox.command.run( - args, - env=env, - path=self.bin, - **kwargs - ) + return nox.command.run(args, env=env, path=self.bin, **kwargs) def install(self, *args, **kwargs): """Install invokes `pip`_ to install packages inside of the session's @@ -202,13 +196,12 @@ def install(self, *args, **kwargs): """ if not isinstance(self.virtualenv, VirtualEnv): raise ValueError( - 'A session without a virtualenv can not install dependencies.') + "A session without a virtualenv can not install dependencies." + ) if not args: - raise ValueError('At least one argument required to install().') + raise ValueError("At least one argument required to install().") - self.run( - 'pip', 'install', '--upgrade', *args, - silent=True, **kwargs) + self.run("pip", "install", "--upgrade", *args, silent=True, **kwargs) def notify(self, target): """Place the given session at the end of the queue. @@ -260,24 +253,23 @@ def _create_venv(self): 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.func.reuse_venv or self.global_config.reuse_existing_virtualenvs + ) self.venv = VirtualEnv( - path, - interpreter=self.func.python, - reuse_existing=reuse_existing) + 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)) + 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() + os.path.realpath(os.path.dirname(self.global_config.noxfile)) + ).as_cwd() with cwd: self._create_venv() @@ -297,12 +289,11 @@ def execute(self): return Result(self, Status.FAILED) except KeyboardInterrupt: - logger.error('Session {} interrupted.'.format(self)) + logger.error("Session {} interrupted.".format(self)) raise except Exception as exc: - logger.exception( - 'Session {} raised exception {!r}'.format(self, exc)) + logger.exception("Session {} raised exception {!r}".format(self, exc)) return Result(self, Status.FAILED) @@ -334,7 +325,7 @@ def imperfect(self): str: A word or phrase representing the status. """ if self.status == Status.SUCCESS: - return 'was successful' + return "was successful" return self.status.name.lower() def log(self, message): @@ -359,9 +350,9 @@ def serialize(self): dict: The serialized result. """ return { - 'args': getattr(self.session.func, 'call_spec', {}), - 'name': self.session.name, - 'result': self.status.name.lower(), - 'result_code': self.status.value, - 'signature': self.session.signature, + "args": getattr(self.session.func, "call_spec", {}), + "name": self.session.name, + "result": self.status.name.lower(), + "result_code": self.status.value, + "signature": self.session.signature, } diff --git a/nox/tasks.py b/nox/tasks.py index 5f9f3cfa..d8348f17 100644 --- a/nox/tasks.py +++ b/nox/tasks.py @@ -47,9 +47,9 @@ def load_nox_module(global_config): # import-time path resolutions work the way the Noxfile author would # guess. os.chdir(os.path.realpath(os.path.dirname(global_config.noxfile))) - return imp.load_source('user_nox_module', global_config.noxfile) + return imp.load_source("user_nox_module", global_config.noxfile) except (IOError, OSError): - logger.error('Noxfile {} not found.'.format(global_config.noxfile)) + logger.error("Noxfile {} not found.".format(global_config.noxfile)) return 2 @@ -118,9 +118,9 @@ def honor_list_request(manifest, global_config): # If the user just asked for a list of sessions, print that # and be done. if global_config.list_sessions: - print('Available sessions:') + print("Available sessions:") for session in manifest: - print('*', session.signature or session.name) + print("*", session.signature or session.name) return 0 return manifest @@ -160,10 +160,11 @@ def run_manifest(manifest, global_config): # iteration. for session in manifest: result = session.execute() - result.log('Session {name} {status}.'.format( - name=str(session), - status=result.imperfect, - )) + result.log( + "Session {name} {status}.".format( + name=str(session), status=result.imperfect + ) + ) results.append(result) # Sanity check: If we are supposed to stop on the first error case, @@ -192,12 +193,13 @@ def print_summary(results, global_config): # Iterate over the results and print the result for each in a # human-readable way. - logger.warning('Ran multiple sessions:') + logger.warning("Ran multiple sessions:") for result in results: - result.log('* {name}: {status}'.format( - name=str(result.session), - status=result.status.name.lower(), - )) + result.log( + "* {name}: {status}".format( + name=str(result.session), status=result.status.name.lower() + ) + ) # Return the results that were sent to this function. return results @@ -219,11 +221,15 @@ def create_report(results, global_config): return results # Write the JSON report. - with io.open(global_config.report, 'w') as report_file: - json.dump({ - 'result': int(all(results)), - 'sessions': [result.serialize() for result in results], - }, report_file, indent=2) + with io.open(global_config.report, "w") as report_file: + json.dump( + { + "result": int(all(results)), + "sessions": [result.serialize() for result in results], + }, + report_file, + indent=2, + ) # Return back the results passed to this task. return results diff --git a/nox/tox_to_nox.py b/nox/tox_to_nox.py index cf97b8ff..4eebca64 100644 --- a/nox/tox_to_nox.py +++ b/nox/tox_to_nox.py @@ -22,23 +22,23 @@ import tox.config _TEMPLATE = jinja2.Template( - pkgutil.get_data(__name__, 'tox_to_nox.jinja2').decode('utf-8'), - extensions=['jinja2.ext.do']) + pkgutil.get_data(__name__, "tox_to_nox.jinja2").decode("utf-8"), + extensions=["jinja2.ext.do"], +) def wrapjoin(seq): - return ', '.join(["'{}'".format(item) for item in seq]) + return ", ".join(["'{}'".format(item) for item in seq]) def main(): - parser = argparse.ArgumentParser( - description='Converts toxfiles to noxfiles.') - parser.add_argument('--output', default='nox.py') + parser = argparse.ArgumentParser(description="Converts toxfiles to noxfiles.") + parser.add_argument("--output", default="nox.py") args = parser.parse_args() config = tox.config.parseconfig([]) output = _TEMPLATE.render(config=config, wrapjoin=wrapjoin) - with io.open(args.output, 'w') as outfile: + with io.open(args.output, "w") as outfile: outfile.write(output) diff --git a/nox/virtualenv.py b/nox/virtualenv.py index 0f22445b..89422908 100644 --- a/nox/virtualenv.py +++ b/nox/virtualenv.py @@ -25,11 +25,9 @@ # Problematic environment variables that are stripped from all commands inside # of a virtualenv. See https://github.com/theacodes/nox/issues/44 -_BLACKLISTED_ENV_VARS = frozenset([ - 'PIP_RESPECT_VIRTUALENV', - 'PIP_REQUIRE_VIRTUALENV', - '__PYVENV_LAUNCHER__', -]) +_BLACKLISTED_ENV_VARS = frozenset( + ["PIP_RESPECT_VIRTUALENV", "PIP_REQUIRE_VIRTUALENV", "__PYVENV_LAUNCHER__"] +) class ProcessEnv: @@ -46,8 +44,7 @@ def __init__(self, bin=None, env=None): self.env.pop(key, None) if self.bin: - self.env['PATH'] = os.pathsep.join( - [self.bin, self.env.get('PATH', '')]) + self.env["PATH"] = os.pathsep.join([self.bin, self.env.get("PATH", "")]) @property def bin(self): @@ -70,11 +67,11 @@ def locate_via_py(version): Optional[str]: The full executable path for the Python ``version``, if it is found. """ - script = 'import sys; print(sys.executable)' - py_exe = py.path.local.sysfind('py') + script = "import sys; print(sys.executable)" + py_exe = py.path.local.sysfind("py") if py_exe is not None: try: - return py_exe.sysexec('-' + version, '-c', script).strip() + return py_exe.sysexec("-" + version, "-c", script).strip() except py.process.cmdexec.Error: return None @@ -111,16 +108,16 @@ def _resolved_interpreter(self): # If this is just a X, X.Y, or X.Y.Z string, extract just the X / X.Y # part and add Python to the front of it. - match = re.match(r'^([\d\.]+?)$', self.interpreter) + match = re.match(r"^([\d\.]+?)$", self.interpreter) if match: - parts = match.group(1).split('.') + parts = match.group(1).split(".") if len(parts) > 2: parts = parts[:2] - self.interpreter = 'python{}'.format('.'.join(parts)) + self.interpreter = "python{}".format(".".join(parts)) # Sanity check: We only need the rest of this behavior on Windows. - if platform.system() != 'Windows': + if platform.system() != "Windows": return self.interpreter # We may have gotten a fully-qualified interpreter path (for someone @@ -131,9 +128,9 @@ def _resolved_interpreter(self): # If this is a standard Unix "pythonX.Y" name, it should be found # in a standard location in Windows, and if not, the py.exe launcher # should be able to find it from the information in the registry. - match = re.match(r'^python(?P\d\.?\d?)$', self.interpreter) + match = re.match(r"^python(?P\d\.?\d?)$", self.interpreter) if match: - version = match.group('ver') + version = match.group("ver") # Ask the Python launcher to find the interpreter. path_from_launcher = locate_via_py(version) if path_from_launcher: @@ -141,33 +138,34 @@ def _resolved_interpreter(self): # If we got this far, then we were unable to resolve the interpreter # to an actual executable; raise an exception. - raise RuntimeError('Unable to locate Python interpreter "{}".'.format( - self.interpreter, - )) + raise RuntimeError( + 'Unable to locate Python interpreter "{}".'.format(self.interpreter) + ) @property def bin(self): """Returns the location of the virtualenv's bin folder.""" - if platform.system() == 'Windows': - return os.path.join(self.location, 'Scripts') + if platform.system() == "Windows": + return os.path.join(self.location, "Scripts") else: - return os.path.join(self.location, 'bin') + return os.path.join(self.location, "bin") def create(self): """Create the virtualenv.""" if not self._clean_location(): - logger.debug( - 'Re-using existing virtualenv at {}.'.format(self.location)) + logger.debug("Re-using existing virtualenv at {}.".format(self.location)) return False - cmd = [sys.executable, '-m', 'virtualenv', self.location] + cmd = [sys.executable, "-m", "virtualenv", self.location] if self.interpreter: - cmd.extend(['-p', self._resolved_interpreter]) + cmd.extend(["-p", self._resolved_interpreter]) logger.info( - 'Creating virtualenv using {} in {}'.format( - os.path.basename(self._resolved_interpreter), self.location)) + "Creating virtualenv using {} in {}".format( + os.path.basename(self._resolved_interpreter), self.location + ) + ) nox.command.run(cmd, silent=True, log=False) return True diff --git a/setup.py b/setup.py index 6789dcbc..4eca73f0 100644 --- a/setup.py +++ b/setup.py @@ -17,71 +17,52 @@ from setuptools import setup -long_description = open('README.rst', 'r', encoding='utf-8').read() +long_description = open("README.rst", "r", encoding="utf-8").read() setup( - name='nox', - - version='2018.7.31dev1', - - description='Flexible test automation.', + name="nox", + version="2018.7.31dev1", + description="Flexible test automation.", long_description=long_description, - - url='https://nox.readthedocs.org', - - author='Alethea Katherine Flowers', - author_email='me@thea.codes', - - license='Apache Software License', - + url="https://nox.readthedocs.org", + author="Alethea Katherine Flowers", + author_email="me@thea.codes", + license="Apache Software License", classifiers=[ - 'Development Status :: 4 - Beta', - - 'Intended Audience :: Developers', - - 'License :: OSI Approved :: Apache Software License', - - 'Topic :: Software Development :: Testing', - 'Environment :: Console', - - 'Programming Language :: Python', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - - 'Operating System :: POSIX', - 'Operating System :: MacOS', - 'Operating System :: Unix', - 'Operating System :: Microsoft :: Windows' + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Topic :: Software Development :: Testing", + "Environment :: Console", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Operating System :: POSIX", + "Operating System :: MacOS", + "Operating System :: Unix", + "Operating System :: Microsoft :: Windows", ], - - keywords='testing automation tox', - - packages=['nox'], - + keywords="testing automation tox", + packages=["nox"], include_package_data=True, - install_requires=[ - 'colorlog>=2.6.1,<4.0.0', - 'py>=1.4.0,<2.0.0', - 'virtualenv>=14.0.0'], - - extras_require={ - 'tox_to_nox': ['jinja2', 'tox'] - }, - + "colorlog>=2.6.1,<4.0.0", + "py>=1.4.0,<2.0.0", + "virtualenv>=14.0.0", + ], + extras_require={"tox_to_nox": ["jinja2", "tox"]}, entry_points={ - 'console_scripts': [ - 'nox=nox.main:main', - 'tox-to-nox=nox.tox_to_nox:main [tox_to_nox]' - ], + "console_scripts": [ + "nox=nox.main:main", + "tox-to-nox=nox.tox_to_nox:main [tox_to_nox]", + ] }, - project_urls={ - 'Documentation': 'https://nox.readthedocs.io/', - 'Source Code': 'https://github.com/theacodes/nox', - 'Bug Tracker': 'https://github.com/theacodes/nox/issues', + "Documentation": "https://nox.readthedocs.io/", + "Source Code": "https://github.com/theacodes/nox", + "Bug Tracker": "https://github.com/theacodes/nox/issues", }, ) diff --git a/tests/conftest.py b/tests/conftest.py index 5ba0446a..4d7b9b88 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -25,5 +25,6 @@ if six.PY2: import mock # pylint: disable=import-error + unittest.mock = mock - sys.modules['unittest.mock'] = unittest.mock + sys.modules["unittest.mock"] = unittest.mock diff --git a/tests/resources/noxfile.py b/tests/resources/noxfile.py index 81380226..af183c1a 100644 --- a/tests/resources/noxfile.py +++ b/tests/resources/noxfile.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -SIGIL = '123' +SIGIL = "123" diff --git a/tests/test__parametrize.py b/tests/test__parametrize.py index 37dc1826..d76ca158 100644 --- a/tests/test__parametrize.py +++ b/tests/test__parametrize.py @@ -18,107 +18,97 @@ def test_parametrize_decorator_one(): - def f(): pass - _parametrize.parametrize_decorator('abc', 1)(f) + _parametrize.parametrize_decorator("abc", 1)(f) - assert f.parametrize == [{'abc': 1}] + assert f.parametrize == [{"abc": 1}] def test_parametrize_decorator_one_with_args(): - def f(): pass - _parametrize.parametrize_decorator('abc', [1, 2, 3])(f) + _parametrize.parametrize_decorator("abc", [1, 2, 3])(f) - assert f.parametrize == [ - {'abc': 1}, - {'abc': 2}, - {'abc': 3}] + assert f.parametrize == [{"abc": 1}, {"abc": 2}, {"abc": 3}] def test_parametrize_decorator_multiple_args_as_list(): - def f(): pass - _parametrize.parametrize_decorator( - ['abc', 'def'], [('a', 1), ('b', 2), ('c', 3)])(f) + _parametrize.parametrize_decorator(["abc", "def"], [("a", 1), ("b", 2), ("c", 3)])( + f + ) assert f.parametrize == [ - {'abc': 'a', 'def': 1}, - {'abc': 'b', 'def': 2}, - {'abc': 'c', 'def': 3}] + {"abc": "a", "def": 1}, + {"abc": "b", "def": 2}, + {"abc": "c", "def": 3}, + ] def test_parametrize_decorator_multiple_args_as_string(): - def f(): pass - _parametrize.parametrize_decorator( - 'abc, def', [('a', 1), ('b', 2), ('c', 3)])(f) + _parametrize.parametrize_decorator("abc, def", [("a", 1), ("b", 2), ("c", 3)])(f) assert f.parametrize == [ - {'abc': 'a', 'def': 1}, - {'abc': 'b', 'def': 2}, - {'abc': 'c', 'def': 3}] + {"abc": "a", "def": 1}, + {"abc": "b", "def": 2}, + {"abc": "c", "def": 3}, + ] def test_parametrize_decorator_stack(): - def f(): pass - _parametrize.parametrize_decorator('abc', [1, 2, 3])(f) - _parametrize.parametrize_decorator('def', ['a', 'b'])(f) + _parametrize.parametrize_decorator("abc", [1, 2, 3])(f) + _parametrize.parametrize_decorator("def", ["a", "b"])(f) assert f.parametrize == [ - {'abc': 1, 'def': 'a'}, - {'abc': 2, 'def': 'a'}, - {'abc': 3, 'def': 'a'}, - {'abc': 1, 'def': 'b'}, - {'abc': 2, 'def': 'b'}, - {'abc': 3, 'def': 'b'}] + {"abc": 1, "def": "a"}, + {"abc": 2, "def": "a"}, + {"abc": 3, "def": "a"}, + {"abc": 1, "def": "b"}, + {"abc": 2, "def": "b"}, + {"abc": 3, "def": "b"}, + ] def test_parametrize_decorator_multiple_and_stack(): - def f(): pass - _parametrize.parametrize_decorator( - 'abc, def', [(1, 'a'), (2, 'b')])(f) - _parametrize.parametrize_decorator('foo', ['bar', 'baz'])(f) + _parametrize.parametrize_decorator("abc, def", [(1, "a"), (2, "b")])(f) + _parametrize.parametrize_decorator("foo", ["bar", "baz"])(f) assert f.parametrize == [ - {'abc': 1, 'def': 'a', 'foo': 'bar'}, - {'abc': 2, 'def': 'b', 'foo': 'bar'}, - {'abc': 1, 'def': 'a', 'foo': 'baz'}, - {'abc': 2, 'def': 'b', 'foo': 'baz'}] + {"abc": 1, "def": "a", "foo": "bar"}, + {"abc": 2, "def": "b", "foo": "bar"}, + {"abc": 1, "def": "a", "foo": "baz"}, + {"abc": 2, "def": "b", "foo": "baz"}, + ] def test_generate_calls_simple(): f = mock.Mock() - f.__name__ = 'f' + f.__name__ = "f" f.some_prop = 42 - call_specs = [ - {'abc': 1}, - {'abc': 2}, - {'abc': 3} - ] + call_specs = [{"abc": 1}, {"abc": 2}, {"abc": 3}] calls = _parametrize.generate_calls(f, call_specs) assert len(calls) == 3 - assert calls[0].session_signature == '(abc=1)' - assert calls[1].session_signature == '(abc=2)' - assert calls[2].session_signature == '(abc=3)' + assert calls[0].session_signature == "(abc=1)" + assert calls[1].session_signature == "(abc=2)" + assert calls[2].session_signature == "(abc=3)" calls[0]() f.assert_called_with(abc=1) @@ -130,30 +120,30 @@ def test_generate_calls_simple(): # Make sure wrapping was done correctly. for call in calls: assert call.some_prop == 42 - assert call.__name__ == 'f' + assert call.__name__ == "f" def test_generate_calls_multiple_args(): f = mock.Mock() - f.__name__ = 'f' + f.__name__ = "f" call_specs = [ - {'abc': 1, 'foo': 'a'}, - {'abc': 2, 'foo': 'b'}, - {'abc': 3, 'foo': 'c'} + {"abc": 1, "foo": "a"}, + {"abc": 2, "foo": "b"}, + {"abc": 3, "foo": "c"}, ] calls = _parametrize.generate_calls(f, call_specs) assert len(calls) == 3 - assert calls[0].session_signature == '(abc=1, foo=\'a\')' - assert calls[1].session_signature == '(abc=2, foo=\'b\')' - assert calls[2].session_signature == '(abc=3, foo=\'c\')' + assert calls[0].session_signature == "(abc=1, foo='a')" + assert calls[1].session_signature == "(abc=2, foo='b')" + assert calls[2].session_signature == "(abc=3, foo='c')" calls[0]() - f.assert_called_with(abc=1, foo='a') + f.assert_called_with(abc=1, foo="a") calls[1]() - f.assert_called_with(abc=2, foo='b') + f.assert_called_with(abc=2, foo="b") calls[2]() - f.assert_called_with(abc=3, foo='c') + f.assert_called_with(abc=3, foo="c") diff --git a/tests/test_command.py b/tests/test_command.py index 35bc08b1..802b46c0 100644 --- a/tests/test_command.py +++ b/tests/test_command.py @@ -24,104 +24,107 @@ def test_run_defaults(capsys): - result = nox.command.run([PYTHON, '-c', 'print(123)']) + result = nox.command.run([PYTHON, "-c", "print(123)"]) assert result is True def test_run_silent(capsys): - result = nox.command.run([PYTHON, '-c', 'print(123)'], silent=True) + result = nox.command.run([PYTHON, "-c", "print(123)"], silent=True) out, _ = capsys.readouterr() - assert '123' in result - assert out == '' + assert "123" in result + assert out == "" def test_run_env_binary(): result = nox.command.run( - [PYTHON, '-c', 'import os; print(os.environ.get("SIGIL"))'], - silent=True, env={ - b'SIGIL': b'123'}) + [PYTHON, "-c", 'import os; print(os.environ.get("SIGIL"))'], + silent=True, + env={b"SIGIL": b"123"}, + ) - assert '123' in result + assert "123" in result def test_run_env_unicode(): result = nox.command.run( - [PYTHON, '-c', 'import os; print(os.environ["SIGIL"])'], - silent=True, env={ - u'SIGIL': u'123'}) + [PYTHON, "-c", 'import os; print(os.environ["SIGIL"])'], + silent=True, + env={u"SIGIL": u"123"}, + ) - assert '123' in result + assert "123" in result def test_run_env_systemroot(): - systemroot = os.environ.setdefault('SYSTEMROOT', str('sigil')) + systemroot = os.environ.setdefault("SYSTEMROOT", str("sigil")) result = nox.command.run( - [PYTHON, '-c', 'import os; print(os.environ["SYSTEMROOT"])'], - silent=True) + [PYTHON, "-c", 'import os; print(os.environ["SYSTEMROOT"])'], silent=True + ) assert systemroot in result def test_run_not_found(): with pytest.raises(nox.command.CommandFailed): - nox.command.run(['nonexistentcmd']) + nox.command.run(["nonexistentcmd"]) def test_run_path_nonexistent(): result = nox.command.run( - [PYTHON, '-c', 'import sys; print(sys.executable)'], + [PYTHON, "-c", "import sys; print(sys.executable)"], silent=True, - path='/non/existent') + path="/non/existent", + ) - assert '/non/existent' not in result + assert "/non/existent" not in result def test_run_path_existent(tmpdir, monkeypatch): - executable = tmpdir.join('testexc') - executable.ensure('') + executable = tmpdir.join("testexc") + executable.ensure("") executable.chmod(0o700) - with mock.patch('nox.command.popen') as mock_command: - mock_command.return_value = (0, '') - nox.command.run( - ['testexc'], - silent=True, - path=tmpdir.strpath) - mock_command.assert_called_with( - [executable.strpath], env=None, silent=True) + with mock.patch("nox.command.popen") as mock_command: + mock_command.return_value = (0, "") + nox.command.run(["testexc"], silent=True, path=tmpdir.strpath) + mock_command.assert_called_with([executable.strpath], env=None, silent=True) def test_exit_codes(): - assert nox.command.run([PYTHON, '-c', 'import sys; sys.exit(0)']) + assert nox.command.run([PYTHON, "-c", "import sys; sys.exit(0)"]) with pytest.raises(nox.command.CommandFailed): - nox.command.run([PYTHON, '-c', 'import sys; sys.exit(1)']) + nox.command.run([PYTHON, "-c", "import sys; sys.exit(1)"]) assert nox.command.run( - [PYTHON, '-c', 'import sys; sys.exit(1)'], - success_codes=[1, 2]) + [PYTHON, "-c", "import sys; sys.exit(1)"], success_codes=[1, 2] + ) def test_fail_with_silent(capsys): with pytest.raises(nox.command.CommandFailed): nox.command.run( - [PYTHON, '-c', - 'import sys; sys.stdout.write("out");' - 'sys.stderr.write("err"); sys.exit(1)'], - silent=True) + [ + PYTHON, + "-c", + 'import sys; sys.stdout.write("out");' + 'sys.stderr.write("err"); sys.exit(1)', + ], + silent=True, + ) out, err = capsys.readouterr() - assert 'out' in err - assert 'err' in err + assert "out" in err + assert "err" in err def test_interrupt(): mock_proc = mock.Mock() mock_proc.communicate.side_effect = KeyboardInterrupt() - with mock.patch('subprocess.Popen', return_value=mock_proc): + with mock.patch("subprocess.Popen", return_value=mock_proc): with pytest.raises(KeyboardInterrupt): - nox.command.run([PYTHON, '-c' '123']) + nox.command.run([PYTHON, "-c" "123"]) diff --git a/tests/test_logger.py b/tests/test_logger.py index acd05a05..48935279 100644 --- a/tests/test_logger.py +++ b/tests/test_logger.py @@ -18,6 +18,6 @@ def test_success(): - with mock.patch.object(logger.LoggerWithSuccess, '_log') as _log: - logger.LoggerWithSuccess('foo').success('bar') - _log.assert_called_once_with(logger.SUCCESS, 'bar', ()) + with mock.patch.object(logger.LoggerWithSuccess, "_log") as _log: + logger.LoggerWithSuccess("foo").success("bar") + _log.assert_called_once_with(logger.SUCCESS, "bar", ()) diff --git a/tests/test_main.py b/tests/test_main.py index 4cd49ffb..f3311783 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -26,53 +26,54 @@ import nox.sessions -RESOURCES = os.path.join(os.path.dirname(__file__), 'resources') -VERSION = pkg_resources.get_distribution('nox').version +RESOURCES = os.path.join(os.path.dirname(__file__), "resources") +VERSION = pkg_resources.get_distribution("nox").version def test_global_config_constructor(): args = argparse.Namespace( - noxfile='noxfile', - envdir='dir', - sessions=['1', '2'], - keywords='red and blue', + noxfile="noxfile", + envdir="dir", + sessions=["1", "2"], + keywords="red and blue", list_sessions=False, reuse_existing_virtualenvs=True, stop_on_first_error=False, - posargs=['a', 'b', 'c'], - report=None) + posargs=["a", "b", "c"], + report=None, + ) config = nox.main.GlobalConfig(args) - assert config.noxfile == 'noxfile' - assert config.envdir == os.path.abspath('dir') - assert config.sessions == ['1', '2'] - assert config.keywords == 'red and blue' + assert config.noxfile == "noxfile" + assert config.envdir == os.path.abspath("dir") + assert config.sessions == ["1", "2"] + assert config.keywords == "red and blue" assert config.list_sessions is False assert config.reuse_existing_virtualenvs is True assert config.stop_on_first_error is False - assert config.posargs == ['a', 'b', 'c'] + assert config.posargs == ["a", "b", "c"] - args.posargs = ['--', 'a', 'b', 'c'] + args.posargs = ["--", "a", "b", "c"] config = nox.main.GlobalConfig(args) - assert config.posargs == ['a', 'b', 'c'] + assert config.posargs == ["a", "b", "c"] def test_main_no_args(): sys.argv = [sys.executable] - with mock.patch('nox.workflow.execute') as execute: + with mock.patch("nox.workflow.execute") as execute: execute.return_value = 0 # Call the function. - with mock.patch.object(sys, 'exit') as exit: + with mock.patch.object(sys, "exit") as exit: nox.main.main() exit.assert_called_once_with(0) assert execute.called # Verify that the config looks correct. - config = execute.call_args[1]['global_config'] - assert config.noxfile == 'nox.py' - assert config.envdir.endswith('.nox') + config = execute.call_args[1]["global_config"] + assert config.noxfile == "nox.py" + assert config.envdir.endswith(".nox") assert config.sessions is None assert config.reuse_existing_virtualenvs is False assert config.stop_on_first_error is False @@ -82,136 +83,123 @@ def test_main_no_args(): def test_main_long_form_args(): sys.argv = [ sys.executable, - '--noxfile', 'noxfile.py', - '--envdir', '.other', - '--sessions', '1', '2', - '--reuse-existing-virtualenvs', - '--stop-on-first-error', + "--noxfile", + "noxfile.py", + "--envdir", + ".other", + "--sessions", + "1", + "2", + "--reuse-existing-virtualenvs", + "--stop-on-first-error", ] - with mock.patch('nox.workflow.execute') as execute: + with mock.patch("nox.workflow.execute") as execute: execute.return_value = 0 # Call the main function. - with mock.patch.object(sys, 'exit') as exit: + with mock.patch.object(sys, "exit") as exit: nox.main.main() exit.assert_called_once_with(0) assert execute.called # Verify that the config looks correct. - config = execute.call_args[1]['global_config'] - assert config.noxfile == 'noxfile.py' - assert config.envdir.endswith('.other') - assert config.sessions == ['1', '2'] + config = execute.call_args[1]["global_config"] + assert config.noxfile == "noxfile.py" + assert config.envdir.endswith(".other") + assert config.sessions == ["1", "2"] assert config.reuse_existing_virtualenvs is True assert config.stop_on_first_error is True assert config.posargs == [] def test_main_short_form_args(): - sys.argv = [ - sys.executable, - '-f', 'noxfile.py', - '-s', '1', '2', - '-r', - ] - with mock.patch('nox.workflow.execute') as execute: + sys.argv = [sys.executable, "-f", "noxfile.py", "-s", "1", "2", "-r"] + with mock.patch("nox.workflow.execute") as execute: execute.return_value = 0 # Call the main function. - with mock.patch.object(sys, 'exit') as exit: + with mock.patch.object(sys, "exit") as exit: nox.main.main() exit.assert_called_once_with(0) assert execute.called # Verify that the config looks correct. - config = execute.call_args[1]['global_config'] - assert config.noxfile == 'noxfile.py' - assert config.sessions == ['1', '2'] + config = execute.call_args[1]["global_config"] + assert config.noxfile == "noxfile.py" + assert config.sessions == ["1", "2"] assert config.reuse_existing_virtualenvs is True def test_main_explicit_sessions(): - sys.argv = [ - sys.executable, - '-e', '1', '2', - ] - with mock.patch('nox.workflow.execute') as execute: + sys.argv = [sys.executable, "-e", "1", "2"] + with mock.patch("nox.workflow.execute") as execute: execute.return_value = 0 # Call the main function. - with mock.patch.object(sys, 'exit') as exit: + with mock.patch.object(sys, "exit") as exit: nox.main.main() exit.assert_called_once_with(0) assert execute.called # Verify that the explicit sessions are listed in the config. - config = execute.call_args[1]['global_config'] - assert config.sessions == ['1', '2'] + config = execute.call_args[1]["global_config"] + assert config.sessions == ["1", "2"] def test_main_positional_args(): - sys.argv = [ - sys.executable, - '1', '2', '3', - ] - with mock.patch('nox.workflow.execute') as execute: + sys.argv = [sys.executable, "1", "2", "3"] + with mock.patch("nox.workflow.execute") as execute: execute.return_value = 0 # Call the main function. - with mock.patch.object(sys, 'exit') as exit: + with mock.patch.object(sys, "exit") as exit: nox.main.main() exit.assert_called_once_with(0) assert execute.called # Verify that the positional args are listed in the config. - config = execute.call_args[1]['global_config'] - assert config.posargs == ['1', '2', '3'] + config = execute.call_args[1]["global_config"] + assert config.posargs == ["1", "2", "3"] def test_main_positional_with_double_hyphen(): - sys.argv = [ - sys.executable, - '--', '1', '2', '3', - ] - with mock.patch('nox.workflow.execute') as execute: + sys.argv = [sys.executable, "--", "1", "2", "3"] + with mock.patch("nox.workflow.execute") as execute: execute.return_value = 0 # Call the main function. - with mock.patch.object(sys, 'exit') as exit: + with mock.patch.object(sys, "exit") as exit: nox.main.main() exit.assert_called_once_with(0) assert execute.called # Verify that the positional args are listed in the config. - config = execute.call_args[1]['global_config'] - assert config.posargs == ['1', '2', '3'] + config = execute.call_args[1]["global_config"] + assert config.posargs == ["1", "2", "3"] def test_main_positional_flag_like_with_double_hyphen(): - sys.argv = [ - sys.executable, - '--', '1', '2', '3', '-f', '--baz', - ] - with mock.patch('nox.workflow.execute') as execute: + sys.argv = [sys.executable, "--", "1", "2", "3", "-f", "--baz"] + with mock.patch("nox.workflow.execute") as execute: execute.return_value = 0 # Call the main function. - with mock.patch.object(sys, 'exit') as exit: + with mock.patch.object(sys, "exit") as exit: nox.main.main() exit.assert_called_once_with(0) assert execute.called # Verify that the positional args are listed in the config. - config = execute.call_args[1]['global_config'] - assert config.posargs == ['1', '2', '3', '-f', '--baz'] + config = execute.call_args[1]["global_config"] + assert config.posargs == ["1", "2", "3", "-f", "--baz"] def test_main_version(capsys): - sys.argv = [sys.executable, '--version'] + sys.argv = [sys.executable, "--version"] with contexter.ExitStack() as stack: - execute = stack.enter_context(mock.patch('nox.workflow.execute')) - exit_mock = stack.enter_context(mock.patch('sys.exit')) + execute = stack.enter_context(mock.patch("nox.workflow.execute")) + exit_mock = stack.enter_context(mock.patch("sys.exit")) nox.main.main() _, err = capsys.readouterr() assert VERSION in err @@ -221,23 +209,23 @@ def test_main_version(capsys): def test_main_failure(): sys.argv = [sys.executable] - with mock.patch('nox.workflow.execute') as execute: + with mock.patch("nox.workflow.execute") as execute: execute.return_value = 1 - with mock.patch.object(sys, 'exit') as exit: + with mock.patch.object(sys, "exit") as exit: nox.main.main() exit.assert_called_once_with(1) def test_main_nested_config(capsys): sys.argv = [ - 'nox', - '--noxfile', - os.path.join(RESOURCES, 'noxfile_nested.py'), - '-s', + "nox", + "--noxfile", + os.path.join(RESOURCES, "noxfile_nested.py"), + "-s", "snack(cheese='cheddar')", ] - with mock.patch('sys.exit') as sys_exit: + with mock.patch("sys.exit") as sys_exit: nox.main.main() stdout, stderr = capsys.readouterr() assert stdout == "Noms, cheddar so good!\n" diff --git a/tests/test_manifest.py b/tests/test_manifest.py index 870a15b4..91689cff 100644 --- a/tests/test_manifest.py +++ b/tests/test_manifest.py @@ -24,10 +24,8 @@ def create_mock_sessions(): sessions = collections.OrderedDict() - sessions['foo'] = mock.Mock( - spec=(), python=None) - sessions['bar'] = mock.Mock( - spec=(), python=None) + sessions["foo"] = mock.Mock(spec=(), python=None) + sessions["bar"] = mock.Mock(spec=(), python=None) return sessions @@ -37,8 +35,8 @@ def test_init(): # Assert that basic properties look correctly. assert len(manifest) == 2 - assert manifest['foo'].func is sessions['foo'] - assert manifest['bar'].func is sessions['bar'] + assert manifest["foo"].func is sessions["foo"] + assert manifest["bar"].func is sessions["bar"] def test_contains(): @@ -46,19 +44,19 @@ def test_contains(): manifest = Manifest(sessions, mock.sentinel.CONFIG) # Establish that contains works pre-iteration. - assert 'foo' in manifest - assert 'bar' in manifest - assert 'baz' not in manifest + assert "foo" in manifest + assert "bar" in manifest + assert "baz" not in manifest # Establish that __contains__ works post-iteration. for session in manifest: pass - assert 'foo' in manifest - assert 'bar' in manifest - assert 'baz' not in manifest + assert "foo" in manifest + assert "bar" in manifest + assert "baz" not in manifest # Establish that sessions themselves work. - assert manifest['foo'] in manifest + assert manifest["foo"] in manifest def test_getitem(): @@ -67,17 +65,17 @@ def test_getitem(): # Establish that each session is present, and a made-up session # is not. - assert manifest['foo'].func is sessions['foo'] - assert manifest['bar'].func is sessions['bar'] + assert manifest["foo"].func is sessions["foo"] + assert manifest["bar"].func is sessions["bar"] with pytest.raises(KeyError): - manifest['baz'] + manifest["baz"] # Establish that the sessions are still present even after being # consumed by iteration. for session in manifest: pass - assert manifest['foo'].func is sessions['foo'] - assert manifest['bar'].func is sessions['bar'] + assert manifest["foo"].func is sessions["foo"] + assert manifest["bar"].func is sessions["bar"] def test_iteration(): @@ -90,7 +88,7 @@ def test_iteration(): # The first item should be our "foo" session. foo = next(manifest) - assert foo.func == sessions['foo'] + assert foo.func == sessions["foo"] assert foo in manifest._consumed assert foo not in manifest._queue assert len(manifest._consumed) == 1 @@ -99,7 +97,7 @@ def test_iteration(): # The .next() or .__next__() methods can be called directly according # to Python's data model. bar = manifest.next() - assert bar.func == sessions['bar'] + assert bar.func == sessions["bar"] assert bar in manifest._consumed assert bar not in manifest._queue assert len(manifest._consumed) == 2 @@ -121,33 +119,32 @@ def test_len(): def test_filter_by_name(): sessions = create_mock_sessions() manifest = Manifest(sessions, mock.sentinel.CONFIG) - manifest.filter_by_name(('foo',)) - assert 'foo' in manifest - assert 'bar' not in manifest + manifest.filter_by_name(("foo",)) + assert "foo" in manifest + assert "bar" not in manifest def test_filter_by_name_not_found(): sessions = create_mock_sessions() manifest = Manifest(sessions, mock.sentinel.CONFIG) with pytest.raises(KeyError): - manifest.filter_by_name(('baz',)) + manifest.filter_by_name(("baz",)) def test_filter_by_keyword(): sessions = create_mock_sessions() manifest = Manifest(sessions, mock.sentinel.CONFIG) assert len(manifest) == 2 - manifest.filter_by_keywords('foo or bar') + manifest.filter_by_keywords("foo or bar") assert len(manifest) == 2 - manifest.filter_by_keywords('foo') + manifest.filter_by_keywords("foo") assert len(manifest) == 1 def test_add_session_plain(): manifest = Manifest({}, mock.sentinel.CONFIG) - session_func = mock.Mock( - spec=(), python=None) - for session in manifest.make_session('my_session', session_func): + session_func = mock.Mock(spec=(), python=None) + for session in manifest.make_session("my_session", session_func): manifest.add_session(session) assert len(manifest) == 1 @@ -158,9 +155,9 @@ def test_add_session_multiple_pythons(): def session_func(): pass - session_func.python = ['3.5', '3.6'] + session_func.python = ["3.5", "3.6"] - for session in manifest.make_session('my_session', session_func): + for session in manifest.make_session("my_session", session_func): manifest.add_session(session) assert len(manifest) == 2 @@ -170,14 +167,14 @@ def test_add_session_parametrized(): manifest = Manifest({}, mock.sentinel.CONFIG) # Define a session with parameters. - @nox.parametrize('param', ('a', 'b', 'c')) + @nox.parametrize("param", ("a", "b", "c")) def my_session(session, param): pass my_session.python = None # Add the session to the manifest. - for session in manifest.make_session('my_session', my_session): + for session in manifest.make_session("my_session", my_session): manifest.add_session(session) assert len(manifest) == 3 @@ -186,14 +183,14 @@ def test_add_session_parametrized_multiple_pythons(): manifest = Manifest({}, mock.sentinel.CONFIG) # Define a session with parameters. - @nox.parametrize('param', ('a', 'b')) + @nox.parametrize("param", ("a", "b")) def my_session(session, param): pass - my_session.python = ['2.7', '3.6'] + my_session.python = ["2.7", "3.6"] # Add the session to the manifest. - for session in manifest.make_session('my_session', my_session): + for session in manifest.make_session("my_session", my_session): manifest.add_session(session) assert len(manifest) == 4 @@ -202,14 +199,14 @@ def test_add_session_parametrized_noop(): manifest = Manifest({}, mock.sentinel.CONFIG) # Define a session without any parameters. - @nox.parametrize('param', ()) + @nox.parametrize("param", ()) def my_session(session, param): pass my_session.python = None # Add the session to the manifest. - for session in manifest.make_session('my_session', my_session): + for session in manifest.make_session("my_session", my_session): manifest.add_session(session) assert len(manifest) == 1 @@ -229,18 +226,18 @@ def notified(session): notified.python = None # Add the sessions to the manifest. - for session in manifest.make_session('my_session', my_session): + for session in manifest.make_session("my_session", my_session): manifest.add_session(session) - for session in manifest.make_session('notified', notified): + for session in manifest.make_session("notified", notified): manifest.add_session(session) assert len(manifest) == 2 # Filter so only the first session is included in the queue. - manifest.filter_by_name(('my_session',)) + manifest.filter_by_name(("my_session",)) assert len(manifest) == 1 # Notify the notified session. - manifest.notify('notified') + manifest.notify("notified") assert len(manifest) == 2 @@ -253,33 +250,32 @@ def my_session(session): my_session.python = None - for session in manifest.make_session('my_session', my_session): + for session in manifest.make_session("my_session", my_session): manifest.add_session(session) assert len(manifest) == 1 # Establish idempotency; notifying a session already in the queue no-ops. - manifest.notify('my_session') + manifest.notify("my_session") assert len(manifest) == 1 def test_notify_error(): manifest = Manifest({}, mock.sentinel.CONFIG) with pytest.raises(ValueError): - manifest.notify('does_not_exist') + manifest.notify("does_not_exist") def test_add_session_idempotent(): manifest = Manifest({}, mock.sentinel.CONFIG) - session_func = mock.Mock( - spec=(), python=None) - for session in manifest.make_session('my_session', session_func): + session_func = mock.Mock(spec=(), python=None) + for session in manifest.make_session("my_session", session_func): manifest.add_session(session) manifest.add_session(session) assert len(manifest) == 1 def test_null_session_function(): - session = mock.Mock(spec=('skip',)) + session = mock.Mock(spec=("skip",)) _null_session_func(session) assert session.skip.called diff --git a/tests/test_nox_to_tox.py b/tests/test_nox_to_tox.py index 06dd71f9..40b3fdd0 100644 --- a/tests/test_nox_to_tox.py +++ b/tests/test_nox_to_tox.py @@ -23,24 +23,32 @@ @pytest.fixture def makeconfig(tmpdir): def makeconfig(toxini_content): - tmpdir.join('tox.ini').write(toxini_content) + tmpdir.join("tox.ini").write(toxini_content) old = tmpdir.chdir() try: sys.argv = [sys.executable] tox_to_nox.main() - return tmpdir.join('nox.py').read() + return tmpdir.join("nox.py").read() finally: old.chdir() + return makeconfig def test_trivial(makeconfig): - result = makeconfig(textwrap.dedent(""" + result = makeconfig( + textwrap.dedent( + """ [tox] envlist = py27 - """)) - - assert result == textwrap.dedent(""" + """ + ) + ) + + assert ( + result + == textwrap.dedent( + """ import nox @@ -48,38 +56,56 @@ def test_trivial(makeconfig): def py27(session): session.interpreter = 'python2.7' session.install('.') - """).lstrip() + """ + ).lstrip() + ) def test_skipinstall(makeconfig): - result = makeconfig(textwrap.dedent(""" + result = makeconfig( + textwrap.dedent( + """ [tox] envlist = py27 [testenv] skip_install = True - """)) - - assert result == textwrap.dedent(""" + """ + ) + ) + + assert ( + result + == textwrap.dedent( + """ import nox @nox.session def py27(session): session.interpreter = 'python2.7' - """).lstrip() + """ + ).lstrip() + ) def test_usedevelop(makeconfig): - result = makeconfig(textwrap.dedent(""" + result = makeconfig( + textwrap.dedent( + """ [tox] envlist = py27 [testenv] usedevelop = True - """)) - - assert result == textwrap.dedent(""" + """ + ) + ) + + assert ( + result + == textwrap.dedent( + """ import nox @@ -87,11 +113,15 @@ def test_usedevelop(makeconfig): def py27(session): session.interpreter = 'python2.7' session.install('-e', '.') - """).lstrip() + """ + ).lstrip() + ) def test_commands(makeconfig): - result = makeconfig(textwrap.dedent(""" + result = makeconfig( + textwrap.dedent( + """ [tox] envlist = lint @@ -102,9 +132,14 @@ def test_commands(makeconfig): flake8 \\ --import-order-style=google \\ google tests - """)) - - assert result == textwrap.dedent(""" + """ + ) + ) + + assert ( + result + == textwrap.dedent( + """ import nox @@ -115,11 +150,15 @@ def lint(session): session.run('python', 'setup.py', 'check', '--metadata', \ '--restructuredtext', '--strict') session.run('flake8', '--import-order-style=google', 'google', 'tests') - """).lstrip() + """ + ).lstrip() + ) def test_deps(makeconfig): - result = makeconfig(textwrap.dedent(""" + result = makeconfig( + textwrap.dedent( + """ [tox] envlist = lint @@ -128,9 +167,14 @@ def test_deps(makeconfig): deps = flake8 gcp-devrel-py-tools>=0.0.3 - """)) - - assert result == textwrap.dedent(""" + """ + ) + ) + + assert ( + result + == textwrap.dedent( + """ import nox @@ -139,11 +183,15 @@ def lint(session): session.interpreter = 'python2.7' session.install('flake8', 'gcp-devrel-py-tools>=0.0.3') session.install('.') - """).lstrip() + """ + ).lstrip() + ) def test_env(makeconfig): - result = makeconfig(textwrap.dedent(""" + result = makeconfig( + textwrap.dedent( + """ [tox] envlist = lint @@ -152,9 +200,14 @@ def test_env(makeconfig): setenv = SPHINX_APIDOC_OPTIONS=members,inherited-members,show-inheritance TEST=meep - """)) - - assert result == textwrap.dedent(""" + """ + ) + ) + + assert ( + result + == textwrap.dedent( + """ import nox @@ -165,20 +218,29 @@ def lint(session): 'members,inherited-members,show-inheritance' session.env['TEST'] = 'meep' session.install('.') - """).lstrip() + """ + ).lstrip() + ) def test_chdir(makeconfig): - result = makeconfig(textwrap.dedent(""" + result = makeconfig( + textwrap.dedent( + """ [tox] envlist = lint [testenv:lint] basepython = python2.7 changedir = docs - """)) - - assert result == textwrap.dedent(""" + """ + ) + ) + + assert ( + result + == textwrap.dedent( + """ import nox @@ -187,4 +249,6 @@ def lint(session): session.interpreter = 'python2.7' session.install('.') session.chdir('docs') - """).lstrip() + """ + ).lstrip() + ) diff --git a/tests/test_registry.py b/tests/test_registry.py index 4de1e122..4549a9e6 100644 --- a/tests/test_registry.py +++ b/tests/test_registry.py @@ -37,38 +37,39 @@ def unit_tests(session): pass answer = registry.get() - assert 'unit_tests' in answer - assert answer['unit_tests'] is unit_tests + assert "unit_tests" in answer + assert answer["unit_tests"] is unit_tests assert unit_tests.python is None def test_session_decorator_single_python(cleanup_registry): - @registry.session_decorator(python='3.6') + @registry.session_decorator(python="3.6") def unit_tests(session): pass - assert unit_tests.python == '3.6' + assert unit_tests.python == "3.6" def test_session_decorator_list_of_pythons(cleanup_registry): - @registry.session_decorator(python=['3.5', '3.6']) + @registry.session_decorator(python=["3.5", "3.6"]) def unit_tests(session): pass - assert unit_tests.python == ['3.5', '3.6'] + assert unit_tests.python == ["3.5", "3.6"] def test_session_decorator_py_alias(cleanup_registry): - @registry.session_decorator(py=['3.5', '3.6']) + @registry.session_decorator(py=["3.5", "3.6"]) def unit_tests(session): pass - assert unit_tests.python == ['3.5', '3.6'] + assert unit_tests.python == ["3.5", "3.6"] def test_session_decorator_py_alias_error(cleanup_registry): - with pytest.raises(ValueError, match='argument'): - @registry.session_decorator(python=['3.5', '3.6'], py='2.7') + with pytest.raises(ValueError, match="argument"): + + @registry.session_decorator(python=["3.5", "3.6"], py="2.7") def unit_tests(session): pass @@ -102,5 +103,5 @@ def system_tests(session): assert len(full) == 2 assert full == registry._REGISTRY assert full is not registry._REGISTRY - assert full['unit_tests'] is unit_tests - assert full['system_tests'] is system_tests + assert full["unit_tests"] is unit_tests + assert full["system_tests"] is system_tests diff --git a/tests/test_sessions.py b/tests/test_sessions.py index 7058017e..f585753a 100644 --- a/tests/test_sessions.py +++ b/tests/test_sessions.py @@ -29,42 +29,41 @@ def test__normalize_path(): - envdir = 'envdir' + envdir = "envdir" normalize = nox.sessions._normalize_path - assert normalize(envdir, u'hello') == os.path.join('envdir', 'hello') - assert normalize(envdir, b'hello') == os.path.join('envdir', 'hello') - assert normalize(envdir, 'hello(world)') == os.path.join( - 'envdir', 'hello-world') - assert normalize(envdir, 'hello(world, meep)') == os.path.join( - 'envdir', 'hello-world-meep') - assert normalize( - envdir, 'tests(interpreter="python2.7", django="1.10")') == ( - os.path.join('envdir', 'tests-interpreter-python2-7-django-1-10')) + assert normalize(envdir, u"hello") == os.path.join("envdir", "hello") + assert normalize(envdir, b"hello") == os.path.join("envdir", "hello") + assert normalize(envdir, "hello(world)") == os.path.join("envdir", "hello-world") + assert normalize(envdir, "hello(world, meep)") == os.path.join( + "envdir", "hello-world-meep" + ) + assert normalize(envdir, 'tests(interpreter="python2.7", django="1.10")') == ( + os.path.join("envdir", "tests-interpreter-python2-7-django-1-10") + ) def test__normalize_path_hash(): - envdir = 'd' * (100 - len('bin/pythonX.Y') - 10) - norm_path = nox.sessions._normalize_path( - envdir, 'a-really-long-virtualenv-path') - assert 'a-really-long-virtualenv-path' not in norm_path + envdir = "d" * (100 - len("bin/pythonX.Y") - 10) + norm_path = nox.sessions._normalize_path(envdir, "a-really-long-virtualenv-path") + assert "a-really-long-virtualenv-path" not in norm_path assert len(norm_path) < 100 def test__normalize_path_give_up(): - envdir = 'd' * 100 - norm_path = nox.sessions._normalize_path( - envdir, 'any-path') - assert 'any-path' in norm_path + envdir = "d" * 100 + norm_path = nox.sessions._normalize_path(envdir, "any-path") + assert "any-path" in norm_path class TestSession: def make_session_and_runner(self): runner = nox.sessions.SessionRunner( - name='test', - signature='test', + name="test", + signature="test", func=mock.sentinel.func, global_config=argparse.Namespace(posargs=mock.sentinel.posargs), - manifest=mock.create_autospec(nox.manifest.Manifest)) + manifest=mock.create_autospec(nox.manifest.Manifest), + ) runner.venv = mock.create_autospec(nox.virtualenv.VirtualEnv) runner.venv.env = {} return nox.sessions.Session(runner=runner), runner @@ -78,7 +77,7 @@ def test_properties(self): assert session.bin is runner.venv.bin def test_chdir(self, tmpdir): - cdto = str(tmpdir.join('cdbby').ensure(dir=True)) + cdto = str(tmpdir.join("cdbby").ensure(dir=True)) current_cwd = os.getcwd() session, _ = self.make_session_and_runner() @@ -91,49 +90,51 @@ def test_chdir(self, tmpdir): def test_run_bad_args(self): session, _ = self.make_session_and_runner() - with pytest.raises(ValueError, match='arg'): + with pytest.raises(ValueError, match="arg"): session.run() def test_run_with_func(self): session, _ = self.make_session_and_runner() - assert session.run(lambda a, b: a+b, 1, 2) == 3 + assert session.run(lambda a, b: a + b, 1, 2) == 3 def test_run_with_func_error(self): session, _ = self.make_session_and_runner() def raise_value_error(): - raise ValueError('meep') + raise ValueError("meep") with pytest.raises(nox.command.CommandFailed): assert session.run(raise_value_error) def test_run_success(self): session, _ = self.make_session_and_runner() - result = session.run(sys.executable, '-c', 'print(123)') + result = session.run(sys.executable, "-c", "print(123)") assert result def test_run_error(self): session, _ = self.make_session_and_runner() with pytest.raises(nox.command.CommandFailed): - session.run(sys.executable, '-c', 'import sys; sys.exit(1)') + session.run(sys.executable, "-c", "import sys; sys.exit(1)") def test_run_overly_env(self): session, runner = self.make_session_and_runner() - runner.venv.env['A'] = '1' - runner.venv.env['B'] = '2' + runner.venv.env["A"] = "1" + runner.venv.env["B"] = "2" result = session.run( sys.executable, - '-c', 'import os; print(os.environ["A"], os.environ["B"])', - env={'B': '3'}, - silent=True) - assert result.strip() == '1 3' + "-c", + 'import os; print(os.environ["A"], os.environ["B"])', + env={"B": "3"}, + silent=True, + ) + assert result.strip() == "1 3" def test_install_bad_args(self): session, _ = self.make_session_and_runner() - with pytest.raises(ValueError, match='arg'): + with pytest.raises(ValueError, match="arg"): session.install() def test_install_not_a_virtualenv(self): @@ -141,41 +142,41 @@ def test_install_not_a_virtualenv(self): runner.venv = None - with pytest.raises(ValueError, match='virtualenv'): + with pytest.raises(ValueError, match="virtualenv"): session.install() def test_install(self): session, runner = self.make_session_and_runner() - with mock.patch.object(session, 'run', autospec=True) as run: - session.install('requests', 'urllib3') + with mock.patch.object(session, "run", autospec=True) as run: + session.install("requests", "urllib3") run.assert_called_once_with( - 'pip', 'install', '--upgrade', 'requests', 'urllib3', - silent=True) + "pip", "install", "--upgrade", "requests", "urllib3", silent=True + ) def test_notify(self): session, runner = self.make_session_and_runner() - session.notify('other') + session.notify("other") - runner.manifest.notify.assert_called_once_with('other') + runner.manifest.notify.assert_called_once_with("other") def test_log(self, caplog): caplog.set_level(logging.INFO) session, _ = self.make_session_and_runner() - session.log('meep') + session.log("meep") - assert 'meep' in caplog.text + assert "meep" in caplog.text def test_error(self, caplog): caplog.set_level(logging.ERROR) session, _ = self.make_session_and_runner() with pytest.raises(nox.sessions._SessionQuit): - session.error('meep') + session.error("meep") - assert 'meep' in caplog.text + assert "meep" in caplog.text def test_error_no_log(self): session, _ = self.make_session_and_runner() @@ -196,22 +197,24 @@ def make_runner(self): func.python = None func.reuse_venv = False runner = nox.sessions.SessionRunner( - name='test', - signature='test(1, 2)', + name="test", + signature="test(1, 2)", func=func, global_config=argparse.Namespace( - noxfile=os.path.join(os.getcwd(), 'nox.py'), - envdir='envdir', + noxfile=os.path.join(os.getcwd(), "nox.py"), + envdir="envdir", posargs=mock.sentinel.posargs, - reuse_existing_virtualenvs=False), - manifest=mock.create_autospec(nox.manifest.Manifest)) + reuse_existing_virtualenvs=False, + ), + manifest=mock.create_autospec(nox.manifest.Manifest), + ) return runner def test_properties(self): runner = self.make_runner() - assert runner.name == 'test' - assert runner.signature == 'test(1, 2)' + assert runner.name == "test" + assert runner.signature == "test(1, 2)" assert runner.func is not None assert runner.global_config.posargs == mock.sentinel.posargs assert isinstance(runner.manifest, nox.manifest.Manifest) @@ -224,7 +227,7 @@ def test__create_venv_process_env(self): assert isinstance(runner.venv, nox.virtualenv.ProcessEnv) - @mock.patch('nox.virtualenv.VirtualEnv.create', autospec=True) + @mock.patch("nox.virtualenv.VirtualEnv.create", autospec=True) def test__create_venv(self, create): runner = self.make_runner() @@ -232,22 +235,21 @@ def test__create_venv(self, create): create.assert_called_once_with(runner.venv) assert isinstance(runner.venv, nox.virtualenv.VirtualEnv) - assert runner.venv.location.endswith( - os.path.join('envdir', 'test-1-2')) + assert runner.venv.location.endswith(os.path.join("envdir", "test-1-2")) assert runner.venv.interpreter is None assert runner.venv.reuse_existing is False - @mock.patch('nox.virtualenv.VirtualEnv.create', autospec=True) + @mock.patch("nox.virtualenv.VirtualEnv.create", autospec=True) def test__create_venv_options(self, create): runner = self.make_runner() - runner.func.python = 'coolpython' + runner.func.python = "coolpython" runner.func.reuse_venv = True runner._create_venv() create.assert_called_once_with(runner.venv) assert isinstance(runner.venv, nox.virtualenv.VirtualEnv) - assert runner.venv.interpreter is 'coolpython' + assert runner.venv.interpreter is "coolpython" assert runner.venv.reuse_existing is True def make_runner_with_mock_venv(self): @@ -264,13 +266,13 @@ def test_execute_noop_success(self, caplog): assert result runner.func.assert_called_once_with(mock.ANY) - assert 'Running session test(1, 2)' in caplog.text + assert "Running session test(1, 2)" in caplog.text def test_execute_quit(self): runner = self.make_runner_with_mock_venv() def func(session): - session.error('meep') + session.error("meep") runner.func = func @@ -282,7 +284,7 @@ def test_execute_skip(self): runner = self.make_runner_with_mock_venv() def func(session): - session.skip('meep') + session.skip("meep") runner.func = func @@ -317,7 +319,7 @@ def test_execute_exception(self): runner = self.make_runner_with_mock_venv() def func(session): - raise ValueError('meep') + raise ValueError("meep") runner.func = func @@ -329,23 +331,20 @@ def func(session): class TestResult: def test_init(self): result = nox.sessions.Result( - session=mock.sentinel.SESSION, - status=mock.sentinel.STATUS, + session=mock.sentinel.SESSION, status=mock.sentinel.STATUS ) assert result.session == mock.sentinel.SESSION assert result.status == mock.sentinel.STATUS def test__bool_true(self): - for status in ( - nox.sessions.Status.SUCCESS, nox.sessions.Status.SKIPPED): + for status in (nox.sessions.Status.SUCCESS, nox.sessions.Status.SKIPPED): result = nox.sessions.Result(session=object(), status=status) assert bool(result) assert result.__bool__() assert result.__nonzero__() def test__bool_false(self): - for status in ( - nox.sessions.Status.FAILED, nox.sessions.Status.ABORTED): + for status in (nox.sessions.Status.FAILED, nox.sessions.Status.ABORTED): result = nox.sessions.Result(session=object(), status=status) assert not bool(result) assert not result.__bool__() @@ -353,36 +352,37 @@ def test__bool_false(self): def test__imperfect(self): result = nox.sessions.Result(object(), nox.sessions.Status.SUCCESS) - assert result.imperfect == 'was successful' + assert result.imperfect == "was successful" result = nox.sessions.Result(object(), nox.sessions.Status.FAILED) - assert result.imperfect == 'failed' + assert result.imperfect == "failed" def test__log_success(self): result = nox.sessions.Result(object(), nox.sessions.Status.SUCCESS) - with mock.patch.object(logger, 'success') as success: - result.log('foo') - success.assert_called_once_with('foo') + with mock.patch.object(logger, "success") as success: + result.log("foo") + success.assert_called_once_with("foo") def test__log_warning(self): result = nox.sessions.Result(object(), nox.sessions.Status.SKIPPED) - with mock.patch.object(logger, 'warning') as warning: - result.log('foo') - warning.assert_called_once_with('foo') + with mock.patch.object(logger, "warning") as warning: + result.log("foo") + warning.assert_called_once_with("foo") def test__log_error(self): result = nox.sessions.Result(object(), nox.sessions.Status.FAILED) - with mock.patch.object(logger, 'error') as error: - result.log('foo') - error.assert_called_once_with('foo') + with mock.patch.object(logger, "error") as error: + result.log("foo") + error.assert_called_once_with("foo") def test__serialize(self): result = nox.sessions.Result( session=argparse.Namespace( - signature='siggy', name='namey', func=mock.Mock()), + signature="siggy", name="namey", func=mock.Mock() + ), status=nox.sessions.Status.SUCCESS, ) answer = result.serialize() - assert answer['name'] == 'namey' - assert answer['result'] == 'success' - assert answer['result_code'] == 1 - assert answer['signature'] == 'siggy' + assert answer["name"] == "namey" + assert answer["result"] == "success" + assert answer["result_code"] == 1 + assert answer["signature"] == "siggy" diff --git a/tests/test_tasks.py b/tests/test_tasks.py index 3c8e8502..d4143474 100644 --- a/tests/test_tasks.py +++ b/tests/test_tasks.py @@ -25,7 +25,7 @@ from nox.manifest import Manifest -RESOURCES = os.path.join(os.path.dirname(__file__), 'resources') +RESOURCES = os.path.join(os.path.dirname(__file__), "resources") def session_func(): @@ -36,13 +36,13 @@ def session_func(): def test_load_nox_module(): - config = argparse.Namespace(noxfile=os.path.join(RESOURCES, 'noxfile.py')) + config = argparse.Namespace(noxfile=os.path.join(RESOURCES, "noxfile.py")) noxfile_module = tasks.load_nox_module(config) - assert noxfile_module.SIGIL == '123' + assert noxfile_module.SIGIL == "123" def test_load_nox_module_not_found(): - config = argparse.Namespace(noxfile='bogus.py') + config = argparse.Namespace(noxfile="bogus.py") assert tasks.load_nox_module(config) == 2 @@ -61,10 +61,7 @@ def notasession(): # Mock up a nox.py module and configuration. mock_module = argparse.Namespace( - __name__=foo.__module__, - foo=foo, - bar=bar, - notasession=notasession, + __name__=foo.__module__, foo=foo, bar=bar, notasession=notasession ) config = argparse.Namespace(sessions=(), keywords=()) @@ -72,37 +69,29 @@ def notasession(): manifest = tasks.discover_manifest(mock_module, config) sessions = list(manifest) assert [s.func for s in sessions] == [foo, bar] - assert [str(i) for i in sessions] == ['foo', 'bar'] + assert [str(i) for i in sessions] == ["foo", "bar"] def test_filter_manifest(): config = argparse.Namespace(sessions=(), keywords=()) - manifest = Manifest({ - 'foo': session_func, - 'bar': session_func, - }, config) + manifest = Manifest({"foo": session_func, "bar": session_func}, config) return_value = tasks.filter_manifest(manifest, config) assert return_value is manifest assert len(manifest) == 2 def test_filter_manifest_not_found(): - config = argparse.Namespace(sessions=('baz',), keywords=()) - manifest = Manifest({ - 'foo': session_func, - 'bar': session_func, - }, config) + config = argparse.Namespace(sessions=("baz",), keywords=()) + manifest = Manifest({"foo": session_func, "bar": session_func}, config) return_value = tasks.filter_manifest(manifest, config) assert return_value == 3 def test_filter_manifest_keywords(): - config = argparse.Namespace(sessions=(), keywords='foo or bar') - manifest = Manifest({ - 'foo': session_func, - 'bar': session_func, - 'baz': session_func, - }, config) + config = argparse.Namespace(sessions=(), keywords="foo or bar") + manifest = Manifest( + {"foo": session_func, "bar": session_func, "baz": session_func}, config + ) return_value = tasks.filter_manifest(manifest, config) assert return_value is manifest assert len(manifest) == 2 @@ -110,14 +99,14 @@ def test_filter_manifest_keywords(): def test_honor_list_request_noop(): config = argparse.Namespace(list_sessions=False) - manifest = {'thing': mock.sentinel.THING} + manifest = {"thing": mock.sentinel.THING} return_value = tasks.honor_list_request(manifest, global_config=config) assert return_value is manifest def test_honor_list_request(): config = argparse.Namespace(list_sessions=True) - manifest = [argparse.Namespace(signature='foo')] + manifest = [argparse.Namespace(signature="foo")] return_value = tasks.honor_list_request(manifest, global_config=config) assert return_value == 0 @@ -125,20 +114,14 @@ def test_honor_list_request(): def test_verify_manifest_empty(): config = argparse.Namespace(sessions=(), keywords=()) manifest = Manifest({}, config) - return_value = tasks.verify_manifest_nonempty( - manifest, - global_config=config, - ) + return_value = tasks.verify_manifest_nonempty(manifest, global_config=config) assert return_value == 3 def test_verify_manifest_nonempty(): config = argparse.Namespace(sessions=(), keywords=()) - manifest = Manifest({'session': session_func}, config) - return_value = tasks.verify_manifest_nonempty( - manifest, - global_config=config, - ) + manifest = Manifest({"session": session_func}, config) + return_value = tasks.verify_manifest_nonempty(manifest, global_config=config) assert return_value == manifest @@ -155,8 +138,7 @@ def test_run_manifest(): # Ensure each of the mocks returns a successful result for mock_session in sessions_: mock_session.execute.return_value = sessions.Result( - session=mock_session, - status=sessions.Status.SUCCESS, + session=mock_session, status=sessions.Status.SUCCESS ) # Run the manifest. @@ -184,8 +166,7 @@ def test_run_manifest_abort_on_first_failure(): # Ensure each of the mocks returns a successful result. for mock_session in sessions_: mock_session.execute.return_value = sessions.Result( - session=mock_session, - status=sessions.Status.FAILED, + session=mock_session, status=sessions.Status.FAILED ) # Run the manifest. @@ -204,7 +185,7 @@ def test_run_manifest_abort_on_first_failure(): def test_print_summary_one_result(): results = [mock.sentinel.RESULT] - with mock.patch('nox.tasks.logger', autospec=True) as logger: + with mock.patch("nox.tasks.logger", autospec=True) as logger: answer = tasks.print_summary(results, object()) assert not logger.warning.called assert not logger.success.called @@ -214,10 +195,10 @@ def test_print_summary_one_result(): def test_print_summary(): results = [ - sessions.Result(session='foo', status=sessions.Status.SUCCESS), - sessions.Result(session='bar', status=sessions.Status.FAILED), + sessions.Result(session="foo", status=sessions.Status.SUCCESS), + sessions.Result(session="bar", status=sessions.Status.FAILED), ] - with mock.patch.object(sessions.Result, 'log', autospec=True) as log: + with mock.patch.object(sessions.Result, "log", autospec=True) as log: answer = tasks.print_summary(results, object()) assert log.call_count == 2 assert answer is results @@ -225,35 +206,41 @@ def test_print_summary(): def test_create_report_noop(): config = argparse.Namespace(report=None) - with mock.patch.object(io, 'open', autospec=True) as open_: + with mock.patch.object(io, "open", autospec=True) as open_: results = tasks.create_report(mock.sentinel.RESULTS, config) assert not open_.called assert results is mock.sentinel.RESULTS def test_create_report(): - config = argparse.Namespace(report='/path/to/report') - results = [sessions.Result( - session=argparse.Namespace( - signature='foosig', name='foo', func=object() - ), - status=sessions.Status.SUCCESS, - )] - with mock.patch.object(io, 'open', autospec=True) as open_: - with mock.patch.object(json, 'dump', autospec=True) as dump: + config = argparse.Namespace(report="/path/to/report") + results = [ + sessions.Result( + session=argparse.Namespace(signature="foosig", name="foo", func=object()), + status=sessions.Status.SUCCESS, + ) + ] + with mock.patch.object(io, "open", autospec=True) as open_: + with mock.patch.object(json, "dump", autospec=True) as dump: answer = tasks.create_report(results, config) assert answer is results - dump.assert_called_once_with({ - 'result': 1, - 'sessions': [{ - 'name': 'foo', - 'signature': 'foosig', - 'result': 'success', - 'result_code': 1, - 'args': {}, - }], - }, mock.ANY, indent=2) - open_.assert_called_once_with('/path/to/report', 'w') + dump.assert_called_once_with( + { + "result": 1, + "sessions": [ + { + "name": "foo", + "signature": "foosig", + "result": "success", + "result_code": 1, + "args": {}, + } + ], + }, + mock.ANY, + indent=2, + ) + open_.assert_called_once_with("/path/to/report", "w") def test_final_reduce(): diff --git a/tests/test_virtualenv.py b/tests/test_virtualenv.py index b6d1a4e6..78b41f20 100644 --- a/tests/test_virtualenv.py +++ b/tests/test_virtualenv.py @@ -24,15 +24,16 @@ SYSTEM = platform.system() -IS_WINDOWS = platform.system() == 'Windows' +IS_WINDOWS = platform.system() == "Windows" @pytest.fixture def make_one(tmpdir): def factory(*args, **kwargs): - location = tmpdir.join('venv') + location = tmpdir.join("venv") venv = nox.virtualenv.VirtualEnv(location.strpath, *args, **kwargs) return (venv, location) + return factory @@ -40,8 +41,8 @@ def test_process_env_constructor(): penv = nox.virtualenv.ProcessEnv() assert not penv.bin - penv = nox.virtualenv.ProcessEnv(env={'SIGIL': '123'}) - assert penv.env['SIGIL'] == '123' + penv = nox.virtualenv.ProcessEnv(env={"SIGIL": "123"}) + assert penv.env["SIGIL"] == "123" def test_constructor_defaults(make_one): @@ -51,29 +52,26 @@ def test_constructor_defaults(make_one): assert venv.reuse_existing is False -@pytest.mark.skipif( - IS_WINDOWS, reason='Not testing multiple interpreters on Windows.') +@pytest.mark.skipif(IS_WINDOWS, reason="Not testing multiple interpreters on Windows.") def test_constructor_explicit(make_one): - venv, _ = make_one( - interpreter='python3.5', - reuse_existing=True) + venv, _ = make_one(interpreter="python3.5", reuse_existing=True) assert venv.location - assert venv.interpreter is 'python3.5' + assert venv.interpreter is "python3.5" assert venv.reuse_existing is True def test_env(monkeypatch, make_one): - monkeypatch.setenv('SIGIL', '123') + monkeypatch.setenv("SIGIL", "123") venv, _ = make_one() - assert venv.env['SIGIL'] == '123' - assert venv.bin in venv.env['PATH'] - assert venv.bin not in os.environ['PATH'] + assert venv.env["SIGIL"] == "123" + assert venv.bin in venv.env["PATH"] + assert venv.bin not in os.environ["PATH"] def test_blacklisted_env(monkeypatch, make_one): - monkeypatch.setenv('__PYVENV_LAUNCHER__', 'meep') + monkeypatch.setenv("__PYVENV_LAUNCHER__", "meep") venv, _ = make_one() - assert '__PYVENV_LAUNCHER__' not in venv.bin + assert "__PYVENV_LAUNCHER__" not in venv.bin def test__clean_location(monkeypatch, make_one): @@ -81,7 +79,7 @@ def test__clean_location(monkeypatch, make_one): # Don't re-use existing, but doesn't currently exist. # Should return True indicating that the venv needs to be created. - monkeypatch.delattr(nox.virtualenv.shutil, 'rmtree') + monkeypatch.delattr(nox.virtualenv.shutil, "rmtree") assert not dir.check() assert venv._clean_location() @@ -110,16 +108,16 @@ def test_bin(make_one): venv, dir = make_one() if IS_WINDOWS: - assert dir.join('Scripts').strpath == venv.bin + assert dir.join("Scripts").strpath == venv.bin else: - assert dir.join('bin').strpath == venv.bin + assert dir.join("bin").strpath == venv.bin def test_bin_windows(make_one): venv, dir = make_one() - with mock.patch('platform.system', return_value='Windows'): - assert dir.join('Scripts').strpath == venv.bin + with mock.patch("platform.system", return_value="Windows"): + assert dir.join("Scripts").strpath == venv.bin def test_create(make_one): @@ -127,35 +125,34 @@ def test_create(make_one): venv.create() if IS_WINDOWS: - assert dir.join('Scripts', 'python.exe').check() - assert dir.join('Scripts', 'pip.exe').check() - assert dir.join('Lib').check() + assert dir.join("Scripts", "python.exe").check() + assert dir.join("Scripts", "pip.exe").check() + assert dir.join("Lib").check() else: - assert dir.join('bin', 'python').check() - assert dir.join('bin', 'pip').check() - assert dir.join('lib').check() + assert dir.join("bin", "python").check() + assert dir.join("bin", "pip").check() + assert dir.join("lib").check() # Test running create on an existing environment. It should be deleted. - dir.ensure('test.txt') + dir.ensure("test.txt") venv.create() - assert not dir.join('test.txt').check() + assert not dir.join("test.txt").check() # Test running create on an existing environment with reuse_exising # enabled, it should not be deleted. - dir.ensure('test.txt') - assert dir.join('test.txt').check() + dir.ensure("test.txt") + assert dir.join("test.txt").check() venv.reuse_existing = True venv.create() - assert dir.join('test.txt').check() + assert dir.join("test.txt").check() -@pytest.mark.skipif( - IS_WINDOWS, reason='Not testing multiple interpreters on Windows.') +@pytest.mark.skipif(IS_WINDOWS, reason="Not testing multiple interpreters on Windows.") def test_create_interpreter(make_one): - venv, dir = make_one(interpreter='python3') + venv, dir = make_one(interpreter="python3") venv.create() - assert dir.join('bin', 'python').check() - assert dir.join('bin', 'python3').check() + assert dir.join("bin", "python").check() + assert dir.join("bin", "python3").check() def test__resolved_interpreter_none(make_one): @@ -165,16 +162,14 @@ def test__resolved_interpreter_none(make_one): assert venv._resolved_interpreter == sys.executable -@pytest.mark.parametrize(['input', 'expected'], [ - ('3', 'python3'), - ('3.6', 'python3.6'), - ('3.6.2', 'python3.6'), -]) -def test__resolved_interpreter_numerical_non_windows( - make_one, input, expected): +@pytest.mark.parametrize( + ["input", "expected"], + [("3", "python3"), ("3.6", "python3.6"), ("3.6.2", "python3.6")], +) +def test__resolved_interpreter_numerical_non_windows(make_one, input, expected): venv, _ = make_one(interpreter=input) - with mock.patch.object(platform, 'system') as system: - system.return_value = 'Linux' + with mock.patch.object(platform, "system") as system: + system.return_value = "Linux" assert venv._resolved_interpreter == expected system.assert_called_once_with() @@ -182,87 +177,87 @@ def test__resolved_interpreter_numerical_non_windows( def test__resolved_interpreter_non_windows(make_one): # Establish that the interpreter is simply passed through resolution # on non-Windows. - venv, _ = make_one(interpreter='python3.6') - with mock.patch.object(platform, 'system') as system: - system.return_value = 'Linux' - assert venv._resolved_interpreter == 'python3.6' + venv, _ = make_one(interpreter="python3.6") + with mock.patch.object(platform, "system") as system: + system.return_value = "Linux" + assert venv._resolved_interpreter == "python3.6" system.assert_called_once_with() def test__resolved_interpreter_windows_full_path(make_one): # Establish that if we get a fully-qualified system path on Windows # and the path exists, that we accept it. - venv, _ = make_one(interpreter=r'c:\Python36\python.exe') - with mock.patch.object(platform, 'system') as system: - system.return_value = 'Windows' - with mock.patch.object(py.path.local, 'sysfind') as sysfind: + venv, _ = make_one(interpreter=r"c:\Python36\python.exe") + with mock.patch.object(platform, "system") as system: + system.return_value = "Windows" + with mock.patch.object(py.path.local, "sysfind") as sysfind: sysfind.return_value = py.path.local(venv.interpreter) - assert venv._resolved_interpreter == r'c:\Python36\python.exe' + assert venv._resolved_interpreter == r"c:\Python36\python.exe" system.assert_called_once_with() - sysfind.assert_called_once_with(r'c:\Python36\python.exe') + sysfind.assert_called_once_with(r"c:\Python36\python.exe") -@mock.patch.object(platform, 'system') -@mock.patch.object(py.path.local, 'sysfind') +@mock.patch.object(platform, "system") +@mock.patch.object(py.path.local, "sysfind") def test__resolved_interpreter_windows_pyexe(sysfind, system, make_one): # Establish that if we get a standard pythonX.Y path, we look it # up via the py launcher on Windows. - venv, _ = make_one(interpreter='python3.6') + venv, _ = make_one(interpreter="python3.6") # Trick the system into thinking we are on Windows. - system.return_value = 'Windows' + system.return_value = "Windows" # Trick the system into thinking that it cannot find python3.6 # (it likely will on Unix). Also, when the system looks for the # py launcher, give it a dummy that returns our test value when # run. - attrs = {'sysexec.return_value': r'c:\python36\python.exe'} + attrs = {"sysexec.return_value": r"c:\python36\python.exe"} mock_py = mock.Mock() mock_py.configure_mock(**attrs) - sysfind.side_effect = lambda arg: mock_py if arg == 'py' else False + sysfind.side_effect = lambda arg: mock_py if arg == "py" else False # Okay now run the test. - assert venv._resolved_interpreter == r'c:\python36\python.exe' - sysfind.assert_any_call('python3.6') - sysfind.assert_any_call('py') + assert venv._resolved_interpreter == r"c:\python36\python.exe" + sysfind.assert_any_call("python3.6") + sysfind.assert_any_call("py") system.assert_called_with() -@mock.patch.object(platform, 'system') -@mock.patch.object(py.path.local, 'sysfind') +@mock.patch.object(platform, "system") +@mock.patch.object(py.path.local, "sysfind") def test__resolved_interpreter_windows_pyexe_fails(sysfind, system, make_one): # Establish that if the py launcher fails, we give the right error. - venv, _ = make_one(interpreter='python3.6') + venv, _ = make_one(interpreter="python3.6") # Trick the system into thinking we are on Windows. - system.return_value = 'Windows' + system.return_value = "Windows" # Trick the system into thinking that it cannot find python3.6 # (it likely will on Unix). Also, when the system looks for the # py launcher, give it a dummy that fails. - attrs = {'sysexec.side_effect': py.process.cmdexec.Error(1, 1, '', '', '')} + attrs = {"sysexec.side_effect": py.process.cmdexec.Error(1, 1, "", "", "")} mock_py = mock.Mock() mock_py.configure_mock(**attrs) - sysfind.side_effect = lambda arg: mock_py if arg == 'py' else False + sysfind.side_effect = lambda arg: mock_py if arg == "py" else False # Okay now run the test. with pytest.raises(RuntimeError): venv._resolved_interpreter - sysfind.assert_any_call('python3.6') - sysfind.assert_any_call('py') + sysfind.assert_any_call("python3.6") + sysfind.assert_any_call("py") system.assert_called_with() -@mock.patch.object(platform, 'system') -@mock.patch.object(py._path.local.LocalPath, 'check') -@mock.patch.object(py.path.local, 'sysfind') +@mock.patch.object(platform, "system") +@mock.patch.object(py._path.local.LocalPath, "check") +@mock.patch.object(py.path.local, "sysfind") def test__resolved_interpreter_not_found(sysfind, check, system, make_one): # Establish that if an interpreter cannot be found at a standard # location on Windows, we raise a useful error. - venv, _ = make_one(interpreter='python3.6') + venv, _ = make_one(interpreter="python3.6") # We are on Windows, and nothing can be found. - system.return_value = 'Windows' + system.return_value = "Windows" sysfind.return_value = None check.return_value = False @@ -274,10 +269,10 @@ def test__resolved_interpreter_not_found(sysfind, check, system, make_one): def test__resolved_interpreter_nonstandard(make_one): # Establish that we do not try to resolve non-standard locations # on Windows. - venv, _ = make_one(interpreter='goofy') + venv, _ = make_one(interpreter="goofy") - with mock.patch.object(platform, 'system') as system: - system.return_value = 'Windows' + with mock.patch.object(platform, "system") as system: + system.return_value = "Windows" with pytest.raises(RuntimeError): venv._resolved_interpreter system.assert_called_once_with() diff --git a/tests/test_workflow.py b/tests/test_workflow.py index cf1d35a0..2e8eb661 100644 --- a/tests/test_workflow.py +++ b/tests/test_workflow.py @@ -36,12 +36,10 @@ def test_simple_workflow(): # return value. function_a.assert_called_once_with(global_config=mock.sentinel.CONFIG) function_b.assert_called_once_with( - function_a.return_value, - global_config=mock.sentinel.CONFIG, + function_a.return_value, global_config=mock.sentinel.CONFIG ) function_c.assert_called_once_with( - function_b.return_value, - global_config=mock.sentinel.CONFIG, + function_b.return_value, global_config=mock.sentinel.CONFIG ) @@ -68,8 +66,7 @@ def test_workflow_int_cutoff(): # return value. function_a.assert_called_once_with(global_config=mock.sentinel.CONFIG) function_b.assert_called_once_with( - function_a.return_value, - global_config=mock.sentinel.CONFIG, + function_a.return_value, global_config=mock.sentinel.CONFIG ) assert not function_c.called @@ -97,7 +94,6 @@ def test_workflow_interrupted(): # return value. function_a.assert_called_once_with(global_config=mock.sentinel.CONFIG) function_b.assert_called_once_with( - function_a.return_value, - global_config=mock.sentinel.CONFIG, + function_a.return_value, global_config=mock.sentinel.CONFIG ) assert not function_c.called