Skip to content

Commit

Permalink
Merge pull request #1484 from lukebfox/migrate-nose-pytest
Browse files Browse the repository at this point in the history
Migrate to Python 3.9 and swap nose for pytest
  • Loading branch information
roberth authored Jul 7, 2022
2 parents fc78a64 + 00be25d commit e258b73
Show file tree
Hide file tree
Showing 63 changed files with 1,214 additions and 2,367 deletions.
10 changes: 8 additions & 2 deletions .readthedocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,14 @@ sphinx:
# Optionally build your docs in additional formats such as PDF and ePub
formats: all

# Optionally set the version of Python and requirements required to build your docs
build:
os: ubuntu-22.04
tools:
python: "3.10"

python:
version: 3
install:
- requirements: doc/requirements.txt

# This shouldn't be necessary but might unbreak the build?
# system_packages: true
2 changes: 1 addition & 1 deletion ci/check-flake8.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env nix-shell
#!nix-shell ../shell.nix -i bash

exec flake8 nixops tests/unit
exec flake8 nixops tests
2 changes: 1 addition & 1 deletion ci/check-mypy.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env nix-shell
#!nix-shell ../shell.nix -i bash

mypy nixops
mypy nixops tests
2 changes: 1 addition & 1 deletion ci/check-tests.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env nix-shell
#!nix-shell ../shell.nix -i bash

./coverage-tests.py -a '!libvirtd,!gce,!ec2,!azure' -v
pytest
4 changes: 1 addition & 3 deletions ci/ratchet.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@
import re
from typing import Dict, Tuple, Optional, List, TextIO

from pprint import pprint

report: Dict[str, List[Optional[float]]] = {}

extract_line = re.compile(
"^\|\s+(?P<module>[^\s]*)\s+\|\s+(?P<percent>\d\d?\.\d\d)% imprecise \|"
r"^\|\s+(?P<module>[^\s]*)\s+\|\s+(?P<percent>\d\d?\.\d\d)% imprecise \|"
)


Expand Down
22 changes: 0 additions & 22 deletions coverage-tests.py

This file was deleted.

4 changes: 2 additions & 2 deletions doc/manual/hacking.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ be found:

$ nix-shell
$ echo $PYTHONPATH
/nix/store/5dbidajmgrvskv7kj6bwrkza8szxkgar-python3-3.7.5/lib/python3.7/site-packages:...
/nix/store/34l1p57bn9jqdq2qvz269m9vkp1rsyq8-python3-3.9.6-env/lib/python3.9/site-packages:...

You can then run NixOps in your source tree as follows:

Expand All @@ -39,7 +39,7 @@ To run the tests, do

::

$ python3 tests.py
$ pytest

Note that some of the tests involve the creation of EC2 resources and
thus cost money. You must set the environment variable EC2_ACCESS_KEY
Expand Down
668 changes: 338 additions & 330 deletions doc/requirements.txt

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@
};

checks.doc = pkgs.stdenv.mkDerivation {
name = "lint-docs";
name = "check-lint-docs";
# we use cleanPythonSources because the default gitignore
# implementation doesn't support the restricted evaluation
src = pkgs.poetry2nix.cleanPythonSources {
Expand Down
2 changes: 1 addition & 1 deletion live-docs.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env nix-shell
#!nix-shell ./shell.nix -i python3
# !nix-shell ./shell.nix -i python3

from livereload import Server, shell

Expand Down
6 changes: 3 additions & 3 deletions nixops/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@
# -*- coding: utf-8 -*-
import sys
import os
from typing import Optional


def setup_debugger() -> None:
"""
"""
""" """
import traceback
import pdb
from types import TracebackType
from typing import Type

def hook(
_type: Type[BaseException], value: BaseException, tb: TracebackType
_type: Type[BaseException], value: BaseException, tb: Optional[TracebackType]
) -> None:
if hasattr(sys, "ps1") or not sys.stderr.isatty():
sys.__excepthook__(_type, value, tb)
Expand Down
10 changes: 8 additions & 2 deletions nixops/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,10 @@
subparser.set_defaults(op=op_ssh)
subparser.add_argument("machine", metavar="MACHINE", help="identifier of the machine")
subparser.add_argument(
"args", metavar="SSH_ARGS", nargs=REMAINDER, help="SSH flags and/or command",
"args",
metavar="SSH_ARGS",
nargs=REMAINDER,
help="SSH flags and/or command",
)
subparser.add_argument(
"--now",
Expand Down Expand Up @@ -482,7 +485,10 @@
help="do not perform backup actions on the specified machines",
)
subparser.add_argument(
"--wait", dest="wait", action="store_true", help="wait until backup is finished",
"--wait",
dest="wait",
action="store_true",
help="wait until backup is finished",
)
subparser.add_argument(
"--latest",
Expand Down
8 changes: 6 additions & 2 deletions nixops/backends/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ class MachineState(

defn: Optional[MachineDefinition] = None

state: nixops.resources.State

def __init__(
self, depl: "nixops.deployment.Deployment", name: str, id: RecordId
) -> None:
Expand All @@ -149,7 +151,7 @@ def prefix_definition(self, attr):
@property
def started(self) -> bool:
state = self.state
return state == self.STARTING or state == self.UP
return state == self.STARTING or state == self.UP # type: ignore

def set_common_state(self, defn: MachineDefinitionType) -> None:
self.defn = defn
Expand Down Expand Up @@ -245,7 +247,9 @@ def _check(self, res):
# that. Hack: ignore special filesystems like
# /sys/kernel/config and /tmp. Systemd tries to mount these
# even when they don't exist.
match = re.match("^([^\.]+\.mount) .* inactive .*$", line) # noqa: W605
match = re.match(
r"^([^\.]+\.mount) .* inactive .*$", line
) # noqa: W605

if match:
unit = match.group(1)
Expand Down
41 changes: 26 additions & 15 deletions nixops/deployment.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from collections import defaultdict
import re
from datetime import datetime, timedelta
from nixops.resources import GenericResourceState
import nixops.statefile
import getpass
import traceback
Expand Down Expand Up @@ -80,8 +81,13 @@ class Deployment:

network_expr: nixops.evaluation.NetworkFile

_statefile: nixops.statefile.StateFile

def __init__(
self, statefile, uuid: str, log_file: TextIO = sys.stderr,
self,
statefile,
uuid: str,
log_file: TextIO = sys.stderr,
):
self._statefile = statefile
self._db: nixops.statefile.Connection = statefile._db
Expand Down Expand Up @@ -285,6 +291,8 @@ def _create_resource(
(self.uuid, name, type),
)
id = c.lastrowid
if id is None:
raise Exception("internal error: insert did not produce row id?")
r = _create_state(self, type, name, id)
self.resources[name] = r
return r
Expand Down Expand Up @@ -409,7 +417,7 @@ def evaluate_args(self) -> Any:

@lru_cache()
def evaluate_config(self, attr) -> Dict:
return self.eval(checkConfigurationOptions=False, attr=attr)
return self.eval(checkConfigurationOptions=False, attr=attr) # type: ignore

def evaluate_network(self, action: str = "") -> None:
if not self.network_attr_eval:
Expand Down Expand Up @@ -479,7 +487,10 @@ def eval(
)

def evaluate_option_value(
self, machine_name: str, option_name: str, include_physical: bool = False,
self,
machine_name: str,
option_name: str,
include_physical: bool = False,
) -> Any:
"""Evaluate a single option of a single machine in the deployment specification."""
return self.eval(
Expand Down Expand Up @@ -716,7 +727,7 @@ def build_configs(
if platform.system() != "Linux" and os.environ.get("NIX_REMOTE") != "daemon":
if os.environ.get("NIX_REMOTE_SYSTEMS") is None:
remote_machines = []
for m in sorted(selected, key=lambda m: m.index):
for m in sorted(selected, key=lambda m: m.get_index()):
key_file: Optional[str] = m.get_ssh_private_key_file()
if not key_file:
raise Exception(
Expand Down Expand Up @@ -771,7 +782,9 @@ def build_configs(
)

configs_path = subprocess.check_output(
argv, text=True, stderr=self.logger.log_file,
argv,
text=True,
stderr=self.logger.log_file,
).rstrip()

except subprocess.CalledProcessError:
Expand Down Expand Up @@ -1228,7 +1241,7 @@ def worker(r: nixops.resources.GenericResourceState):
)
)
match = re.search(
'VERSION_ID="([0-9]+\.[0-9]+).*"', # noqa: W605
r'VERSION_ID="([0-9]+\.[0-9]+).*"', # noqa: W605
os_release,
)
if match:
Expand Down Expand Up @@ -1578,7 +1591,7 @@ def worker(m: nixops.backends.GenericMachineState) -> None:
)

def is_valid_resource_name(self, name: str) -> bool:
p = re.compile("^[\w-]+$") # noqa: W605
p = re.compile(r"^[\w-]+$") # noqa: W605
return not p.match(name) is None

def rename(self, name: str, new_name: str) -> None:
Expand Down Expand Up @@ -1642,11 +1655,7 @@ def is_machine(
def _filter_machines(
resources: Dict[str, nixops.resources.GenericResourceState]
) -> Dict[str, nixops.backends.GenericMachineState]:
return {
n: r # type: ignore
for n, r in resources.items()
if is_machine(r)
}
return {n: r for n, r in resources.items() if is_machine(r)} # type: ignore


def is_machine_defn(r: nixops.resources.GenericResourceState) -> bool:
Expand All @@ -1665,20 +1674,22 @@ def _create_definition(

for cls in _subclasses(nixops.resources.ResourceDefinition):
if type_name == cls.get_resource_type():
return cls(name, nixops.resources.ResourceEval(config))
return cls(name, nixops.resources.ResourceEval(config)) # type: ignore

raise nixops.deployment.UnknownBackend(
"unknown resource type ‘{0}’".format(type_name)
)


def _create_state(depl: Deployment, type: str, name: str, id: int) -> Any:
def _create_state(
depl: Deployment, type: str, name: str, id: int
) -> GenericResourceState:
"""Create a resource state object of the desired type."""

for cls in _subclasses(nixops.resources.ResourceState):
try:
if type == cls.get_type():
return cls(depl, name, id)
return cls(depl, name, id) # type: ignore
except NotImplementedError:
pass

Expand Down
1 change: 0 additions & 1 deletion nixops/monkey.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,5 @@
def runtime_checkable(f):
return f


else:
from typing_extensions import Protocol, runtime_checkable
23 changes: 18 additions & 5 deletions nixops/nix_expr.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
from abc import abstractmethod
import functools
import string
from typing import Optional, Any, List, Union, Dict
from typing import Iterable, Optional, Any, List, Tuple, Union, Dict
from textwrap import dedent

__all__ = ["py2nix", "nix2py", "nixmerge", "expand_dict", "RawValue", "Function"]


class RawValue:
class ValueLike:
@abstractmethod
def indent(self, level: int, inline: bool, maxwidth: int) -> str:
pass


class RawValue(ValueLike):
def __init__(self, value: str) -> None:
self.value: str = value

Expand Down Expand Up @@ -71,7 +78,13 @@ def __eq__(self, other) -> bool:


class Container(object):
def __init__(self, prefix: str, children: List, suffix: str, inline_variant=None):
def __init__(
self,
prefix: str,
children: List,
suffix: str,
inline_variant: Optional[ValueLike] = None,
):
self.prefix: str = prefix
self.children: List = children
self.suffix: str = suffix
Expand Down Expand Up @@ -141,8 +154,8 @@ def enclose_node(
)


def _fold_string(value, rules) -> str:
def folder(val, rule) -> str:
def _fold_string(value: str, rules: Iterable[Tuple[str, str]]) -> str:
def folder(val: str, rule: Tuple[str, str]) -> str:
return val.replace(rule[0], rule[1])

return functools.reduce(folder, rules, value)
Expand Down
Loading

0 comments on commit e258b73

Please sign in to comment.