diff --git a/.gitignore b/.gitignore index c07b7032..d58d70db 100644 --- a/.gitignore +++ b/.gitignore @@ -29,7 +29,7 @@ dist/ downloads/ eggs/ .eggs/ -lib/ +./lib/ lib64/ parts/ sdist/ diff --git a/.travis.yml b/.travis.yml index 692e7893..4eb766a6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,11 @@ language: python python: - "3.6" -sudo: required +sudo: false +env: + - MYPYPATH="$TRAVIS_BUILD_DIR/.travis/mypy-stubs" install: - - pip3 install flake8 + - pip3 install flake8 mypy script: - ".travis/flake8.sh" + - mypy libiocage diff --git a/.travis/flake8.sh b/.travis/flake8.sh index d67c89db..5fd1f826 100755 --- a/.travis/flake8.sh +++ b/.travis/flake8.sh @@ -21,6 +21,9 @@ find ./libiocage/ -name \*.py -exec flake8 --ignore=E203,W391 {} + | grep -v "./ num_errors_before=`cat ${tmpbefore} | wc -l` echo "${last_release}'s Error Count: ${num_errors_before}" +# restore whichever branch we were on previously +git checkout - + # The number may be lower then the last release, but that doesn't tell them that they're not higher than they should be. num_errors_adjusted=$((num_errors_before-num_errors_after)) diff --git a/.travis/mypy-stubs/libzfs.pyi b/.travis/mypy-stubs/libzfs.pyi new file mode 100644 index 00000000..97493fd2 --- /dev/null +++ b/.travis/mypy-stubs/libzfs.pyi @@ -0,0 +1,383 @@ +# Stubs for libzfs (Python 3.6) +# +# NOTE: This dynamically typed stub was automatically generated by stubgen. + +from datetime import date +from typing import Any + +DatasetType = ... # type: Any +DiffFileType = ... # type: Any +DiffRecordType = ... # type: Any +Error = ... # type: Any +FeatureState = ... # type: Any +PoolState = ... # type: Any +PoolStatus = ... # type: Any +PropertySource = ... # type: Any +ScanFunction = ... # type: Any +ScanState = ... # type: Any +SendFlag = ... # type: Any +SendFlags = ... # type: Any +VDevAuxState = ... # type: Any +VDevState = ... # type: Any +ZFS_PROPERTY_CONVERTERS = ... # type: Any +ZIOType = ... # type: Any +ZPOOL_PROPERTY_CONVERTERS = ... # type: Any +collections = ... # type: Any +enum = ... # type: Any +errno = ... # type: Any +numbers = ... # type: Any +os = ... # type: Any +stat = ... # type: Any +threading = ... # type: Any + +def __pyx_unpickle_ZFSProperty(*args, **kwargs): ... +def __pyx_unpickle_ZFSPropertyDict(*args, **kwargs): ... +def __pyx_unpickle_ZFSUserProperty(*args, **kwargs): ... +def __pyx_unpickle_ZFSVdev(*args, **kwargs): ... +def __pyx_unpickle_ZFSVdevStats(*args, **kwargs): ... +def __pyx_unpickle_ZPoolProperty(*args, **kwargs): ... +def __pyx_unpickle_ZPoolScrub(*args, **kwargs): ... +def clear_label(*args, **kwargs): ... +def nicestrtonum(*args, **kwargs): ... +def parse_zfs_prop(*args, **kwargs): ... +def parse_zpool_prop(*args, **kwargs): ... +def read_label(*args, **kwargs): ... +def serialize_zfs_prop(*args, **kwargs): ... +def serialize_zpool_prop(*args, **kwargs): ... +def vdev_label_offset(*args, **kwargs): ... + +class DiffRecord: + __init__ = ... # type: Any + __getstate__ = ... # type: Any + +class ZFS: + datasets = ... # type: Any + errno = ... # type: Any + errstr = ... # type: Any + pools = ... # type: Any + snapshots = ... # type: Any + __pyx_vtable__ = ... # type: Any + def __init__(self, *args, **kwargs): ... + def create(self, *args, **kwargs): ... + def describe_resume_token(self, *args, **kwargs): ... + def destroy(self, *args, **kwargs): ... + def export_pool(self, *args, **kwargs): ... + def find_import(self, *args, **kwargs): ... + def generate_history_opts(self, *args, **kwargs): ... + def get(self, *args, **kwargs): ... + def get_dataset(self, *args, **kwargs): ... + def get_dataset_by_path(self, *args, **kwargs): ... + def get_object(self, *args, **kwargs): ... + def get_snapshot(self, *args, **kwargs): ... + def history_vdevs_list(self, *args, **kwargs): ... + def import_pool(self, *args, **kwargs): ... + def receive(self, *args, **kwargs): ... + def send_resume(self, *args, **kwargs): ... + def write_history(self, *args, **kwargs): ... + def __getstate__(self): ... + def __reduce_cython__(self, *args, **kwargs): ... + def __setstate_cython__(self, *args, **kwargs): ... + +class ZFSBookmark(ZFSObject): + bookmark_name = ... # type: Any + parent = ... # type: Any + def __init__(self, *args, **kwargs): ... + def __getstate__(self): ... + def __reduce_cython__(self, *args, **kwargs): ... + def __setstate_cython__(self, *args, **kwargs): ... + +class ZFSDataset(ZFSObject): + bookmarks = ... # type: Any + children = ... # type: Any + children_recursive = ... # type: Any + dependents = ... # type: Any + mountpoint = ... # type: Any + snapshots = ... # type: Any + snapshots_recursive = ... # type: Any + __pyx_vtable__ = ... # type: Any + def __init__(self, *args, **kwargs): ... + def destroy_snapshot(self, *args, **kwargs): ... + def diff(self, *args, **kwargs): ... + def get_send_progress(self, *args, **kwargs): ... + def mount(self, *args, **kwargs): ... + def mount_recursive(self, *args, **kwargs): ... + def promote(self, *args, **kwargs): ... + def receive(self, *args, **kwargs): ... + def send(self, *args, **kwargs): ... + def snapshot(self, *args, **kwargs): ... + def umount(self, *args, **kwargs): ... + def umount_recursive(self, *args, **kwargs): ... + def __getstate__(self): ... + def __reduce_cython__(self, *args, **kwargs): ... + def __setstate_cython__(self, *args, **kwargs): ... + +class ZFSException(RuntimeError): + __init__ = ... # type: Any + +class ZFSImportablePool(ZFSPool): + config = ... # type: Any + error_count = ... # type: Any + features = ... # type: Any + name = ... # type: Any + properties = ... # type: Any + root_dataset = ... # type: Any + __pyx_vtable__ = ... # type: Any + def __init__(self, *args, **kwargs): ... + def attach_vdev(self, *args, **kwargs): ... + def create(self, *args, **kwargs): ... + def destroy(self, *args, **kwargs): ... + def __reduce_cython__(self, *args, **kwargs): ... + def __setstate_cython__(self, *args, **kwargs): ... + +class ZFSObject: + name = ... # type: Any + pool = ... # type: Any + properties = ... # type: Any + root = ... # type: Any + type = ... # type: Any + def __init__(self, *args, **kwargs): ... + def delete(self, *args, **kwargs): ... + def get_send_space(self, *args, **kwargs): ... + def rename(self, *args, **kwargs): ... + def __getstate__(self): ... + def __reduce_cython__(self, *args, **kwargs): ... + def __setstate_cython__(self, *args, **kwargs): ... + +class ZFSPool: + cache_vdevs = ... # type: Any + config = ... # type: Any + data_vdevs = ... # type: Any + disks = ... # type: Any + error_count = ... # type: Any + features = ... # type: Any + groups = ... # type: Any + guid = ... # type: Any + hostname = ... # type: Any + log_vdevs = ... # type: Any + name = ... # type: Any + properties = ... # type: Any + root = ... # type: Any + root_dataset = ... # type: Any + root_vdev = ... # type: Any + scrub = ... # type: Any + spare_vdevs = ... # type: Any + state = ... # type: Any + status = ... # type: Any + __pyx_vtable__ = ... # type: Any + def __init__(self, *args, **kwargs): ... + def attach_vdevs(self, *args, **kwargs): ... + def clear(self, *args, **kwargs): ... + def create(self, *args, **kwargs): ... + def delete(self, *args, **kwargs): ... + def start_scrub(self, *args, **kwargs): ... + def stop_scrub(self, *args, **kwargs): ... + def upgrade(self, *args, **kwargs): ... + def vdev_by_guid(self, *args, **kwargs): ... + def __getstate__(self): ... + def __reduce_cython__(self, *args, **kwargs): ... + def __setstate_cython__(self, *args, **kwargs): ... + +class ZFSProperty: + allowed_values = ... # type: Any + dataset = ... # type: Any + name = ... # type: Any + parsed = ... # type: Any + rawvalue = ... # type: Any + source = ... # type: Any + value = ... # type: Any + def __init__(self, *args, **kwargs): ... + def inherit(self, *args, **kwargs): ... + def refresh(self, *args, **kwargs): ... + def __getstate__(self): ... + def __reduce_cython__(self, *args, **kwargs): ... + def __setstate_cython__(self, *args, **kwargs): ... + +class ZFSPropertyDict(dict): + def __init__(self, *args, **kwargs): ... + def get(self, *args, **kwargs): ... + def has_key(self, *args, **kwargs): ... + def items(self, *args, **kwargs): ... + def iterkeys(self, *args, **kwargs): ... + def itervalues(self, *args, **kwargs): ... + def keys(self, *args, **kwargs): ... + def refresh(self, *args, **kwargs): ... + def setdefault(self, *args, **kwargs): ... + def update(self, *args, **kwargs): ... + def values(self, *args, **kwargs): ... + def __contains__(self, *args, **kwargs): ... + def __delitem__(self, *args, **kwargs): ... + def __getitem__(self, index): ... + def __iter__(self): ... + def __reduce__(self): ... + def __setitem__(self, index, object): ... + def __setstate__(self, state): ... + +class ZFSSnapshot(ZFSObject): + holds = ... # type: Any + mountpoint = ... # type: Any + parent = ... # type: Any + snapshot_name = ... # type: Any + def __init__(self, *args, **kwargs): ... + def bookmark(self, *args, **kwargs): ... + def clone(self, *args, **kwargs): ... + def delete(self, *args, **kwargs): ... + def hold(self, *args, **kwargs): ... + def release(self, *args, **kwargs): ... + def rollback(self, *args, **kwargs): ... + def send(self, *args, **kwargs): ... + def __getstate__(self): ... + def __reduce_cython__(self, *args, **kwargs): ... + def __setstate_cython__(self, *args, **kwargs): ... + +class ZFSUserProperty(ZFSProperty): + name = ... # type: Any + rawvalue = ... # type: Any + source = ... # type: Any + value = ... # type: Any + def __init__(self, *args, **kwargs): ... + def __reduce_cython__(self, *args, **kwargs): ... + def __setstate_cython__(self, *args, **kwargs): ... + +class ZFSVdev: + children = ... # type: Any + disks = ... # type: Any + group = ... # type: Any + guid = ... # type: Any + parent = ... # type: Any + path = ... # type: Any + root = ... # type: Any + size = ... # type: Any + stats = ... # type: Any + status = ... # type: Any + type = ... # type: Any + zpool = ... # type: Any + def __init__(self, *args, **kwargs): ... + def add_child_vdev(self, *args, **kwargs): ... + def attach(self, *args, **kwargs): ... + def degrade(self, *args, **kwargs): ... + def detach(self, *args, **kwargs): ... + def fault(self, *args, **kwargs): ... + def offline(self, *args, **kwargs): ... + def online(self, *args, **kwargs): ... + def remove(self, *args, **kwargs): ... + def replace(self, *args, **kwargs): ... + def __getstate__(self): ... + def __reduce_cython__(self, *args, **kwargs): ... + def __setstate_cython__(self, *args, **kwargs): ... + +class ZFSVdevStats: + allocated = ... # type: Any + bytes = ... # type: Any + checksum_errors = ... # type: Any + configured_ashift = ... # type: Any + fragmentation = ... # type: Any + logical_ashift = ... # type: Any + ops = ... # type: Any + physical_ashift = ... # type: Any + read_errors = ... # type: Any + size = ... # type: Any + timestamp = ... # type: Any + vdev = ... # type: Any + write_errors = ... # type: Any + def __init__(self, *args, **kwargs): ... + def __getstate__(self): ... + def __reduce_cython__(self, *args, **kwargs): ... + def __setstate_cython__(self, *args, **kwargs): ... + +class ZPoolFeature: + description = ... # type: Any + guid = ... # type: Any + name = ... # type: Any + pool = ... # type: Any + state = ... # type: Any + def __init__(self, *args, **kwargs): ... + def enable(self, *args, **kwargs): ... + def __getstate__(self): ... + def __reduce_cython__(self, *args, **kwargs): ... + def __setstate_cython__(self, *args, **kwargs): ... + +class ZPoolProperty: + allowed_values = ... # type: Any + name = ... # type: Any + parsed = ... # type: Any + pool = ... # type: Any + rawvalue = ... # type: Any + source = ... # type: Any + value = ... # type: Any + def __init__(self, *args, **kwargs): ... + def reset(self, *args, **kwargs): ... + def __getstate__(self): ... + def __reduce_cython__(self, *args, **kwargs): ... + def __setstate_cython__(self, *args, **kwargs): ... + +class ZPoolScrub: + bytes_scanned = ... # type: Any + bytes_to_scan = ... # type: Any + end_time = ... # type: Any + errors = ... # type: Any + function = ... # type: Any + percentage = ... # type: Any + pool = ... # type: Any + root = ... # type: Any + start_time = ... # type: Any + stat = ... # type: Any + state = ... # type: Any + def __init__(self, *args, **kwargs): ... + def __getstate__(self): ... + def __reduce_cython__(self, *args, **kwargs): ... + def __setstate_cython__(self, *args, **kwargs): ... + +class ZfsConverter: + __init__ = ... # type: Any + to_native = ... # type: Any + to_property = ... # type: Any + +class datetime(date): + fold = ... # type: Any + hour = ... # type: Any + max = ... # type: Any + microsecond = ... # type: Any + min = ... # type: Any + minute = ... # type: Any + resolution = ... # type: Any + second = ... # type: Any + tzinfo = ... # type: Any + def __init__(self, *args, **kwargs): ... + def astimezone(self, *args, **kwargs): ... + @classmethod + def combine(cls, *args, **kwargs): ... + def ctime(self, *args, **kwargs): ... + def date(self, *args, **kwargs): ... + def dst(self, *args, **kwargs): ... + @classmethod + def fromtimestamp(cls, *args, **kwargs): ... + def isoformat(self, *args, **kwargs): ... + @classmethod + def now(cls, *args, **kwargs): ... + def replace(self, *args, **kwargs): ... + @classmethod + def strptime(cls, *args, **kwargs): ... + def time(self, *args, **kwargs): ... + def timestamp(self, *args, **kwargs): ... + def timetuple(self, *args, **kwargs): ... + def timetz(self, *args, **kwargs): ... + def tzname(self, *args, **kwargs): ... + @classmethod + def utcfromtimestamp(cls, *args, **kwargs): ... + @classmethod + def utcnow(cls, *args, **kwargs): ... + def utcoffset(self, *args, **kwargs): ... + def utctimetuple(self, *args, **kwargs): ... + def __add__(self, other): ... + def __eq__(self, other): ... + def __ge__(self, other): ... + def __gt__(self, other): ... + def __hash__(self): ... + def __le__(self, other): ... + def __lt__(self, other): ... + def __ne__(self, other): ... + def __radd__(self, other): ... + def __reduce__(self): ... + def __reduce_ex__(self, proto): ... + def __rsub__(self, other): ... + def __sub__(self, other): ... diff --git a/.travis/mypy-stubs/pytest.pyi b/.travis/mypy-stubs/pytest.pyi new file mode 100644 index 00000000..9a98fbc8 --- /dev/null +++ b/.travis/mypy-stubs/pytest.pyi @@ -0,0 +1,25 @@ +# Stubs for pytest (Python 3.6) +# +# NOTE: This dynamically typed stub was automatically generated by stubgen. + +from typing import Any +from _pytest.config import main as main, UsageError as UsageError, cmdline as cmdline, hookspec as hookspec, hookimpl as hookimpl +from _pytest.fixtures import fixture as fixture, yield_fixture as yield_fixture +from _pytest.assertion import register_assert_rewrite as register_assert_rewrite +from _pytest.freeze_support import freeze_includes as freeze_includes +from _pytest import __version__ as __version__ +from _pytest.debugging import pytestPDB as __pytestPDB +from _pytest.recwarn import warns as warns, deprecated_call as deprecated_call +from _pytest.runner import fail as fail, skip as skip, importorskip as importorskip, exit as exit +from _pytest.mark import param as param +from _pytest.mark import MARK_GEN as mark +from _pytest.skipping import xfail as xfail +from _pytest.main import Item as Item, Collector as Collector, File as File, Session as Session +from _pytest.fixtures import fillfixtures as _fillfuncargs +from _pytest.python import raises as raises, approx as approx, Module as Module, Class as Class, Instance as Instance, Function as Function, Generator as Generator + +set_trace = ... # type: Any + +# Names in __all__ with no definition: +# _fillfuncargs +# mark diff --git a/.travis/mypy-stubs/texttable.pyi b/.travis/mypy-stubs/texttable.pyi new file mode 100644 index 00000000..ea6417e8 --- /dev/null +++ b/.travis/mypy-stubs/texttable.pyi @@ -0,0 +1,28 @@ +# Stubs for texttable (Python 3.6) +# +# NOTE: This dynamically typed stub was automatically generated by stubgen. + +from typing import Any + +class ArraySizeError(Exception): + msg = ... # type: Any + def __init__(self, msg) -> None: ... + +class Texttable: + BORDER = ... # type: int + HEADER = ... # type: Any + HLINES = ... # type: Any + VLINES = ... # type: Any + def __init__(self, max_width: int = ...) -> None: ... + def reset(self): ... + def set_chars(self, array): ... + def set_deco(self, deco): ... + def set_cols_align(self, array): ... + def set_cols_valign(self, array): ... + def set_cols_dtype(self, array): ... + def set_cols_width(self, array): ... + def set_precision(self, width): ... + def header(self, array): ... + def add_row(self, array): ... + def add_rows(self, rows, header: bool = ...): ... + def draw(self): ... diff --git a/.travis/mypy-stubs/ucl.pyi b/.travis/mypy-stubs/ucl.pyi new file mode 100644 index 00000000..ff60ac57 --- /dev/null +++ b/.travis/mypy-stubs/ucl.pyi @@ -0,0 +1,13 @@ +# Stubs for ucl (Python 3.6) +# +# NOTE: This dynamically typed stub was automatically generated by stubgen. + +UCL_EMIT_CONFIG = ... # type: int +UCL_EMIT_JSON = ... # type: int +UCL_EMIT_JSON_COMPACT = ... # type: int +UCL_EMIT_MSGPACK = ... # type: int +UCL_EMIT_YAML = ... # type: int + +def dump(*args, **kwargs): ... +def load(*args, **kwargs): ... +def validate(*args, **kwargs): ... diff --git a/libiocage/__init__.py b/libiocage/__init__.py index f7520f0e..c4115b62 100644 --- a/libiocage/__init__.py +++ b/libiocage/__init__.py @@ -21,10 +21,10 @@ # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +from libiocage.lib import errors, events +from libiocage.lib.Host import Host from libiocage.lib.Jail import Jail from libiocage.lib.Jails import Jails +from libiocage.lib.Logger import Logger from libiocage.lib.Release import Release from libiocage.lib.Releases import Releases -from libiocage.lib.Host import Host -from libiocage.lib.Logger import Logger -from libiocage.lib import errors diff --git a/libiocage/cli/__init__.py b/libiocage/cli/__init__.py index ebc8e702..fee43d66 100644 --- a/libiocage/cli/__init__.py +++ b/libiocage/cli/__init__.py @@ -35,7 +35,7 @@ logger = Logger() -click.core._verify_python3_env = lambda: None +click.core._verify_python3_env = lambda: None # type: ignore user_locale = os.environ.get("LANG", "en_US.UTF-8") locale.setlocale(locale.LC_ALL, user_locale) @@ -148,8 +148,7 @@ def get_command(self, ctx, name): @click.option("--log-level", "-d", default=None) @click.command(cls=IOCageCLI) -@click.version_option(version="0.2.11 08/29/2017", prog_name="ioc", - message="%(version)s") +@click.version_option(version="0.2.11 08/29/2017", prog_name="ioc") @click.pass_context def cli(ctx, log_level): """A jail manager.""" diff --git a/libiocage/lib/Datasets.py b/libiocage/lib/Datasets.py index e480e47a..a5ddaaa7 100644 --- a/libiocage/lib/Datasets.py +++ b/libiocage/lib/Datasets.py @@ -31,9 +31,8 @@ class Datasets: ZFS_POOL_ACTIVE_PROPERTY = "org.freebsd.ioc:active" def __init__(self, root=None, pool=None, zfs=None, logger=None): - libiocage.lib.helpers.init_logger(self, logger) - libiocage.lib.helpers.init_zfs(self, zfs) - + self.logger = libiocage.lib.helpers.init_logger(self, logger) + self.zfs = libiocage.lib.helpers.init_zfs(self, zfs) self._datasets = {} if isinstance(root, libzfs.ZFSDataset): diff --git a/libiocage/lib/Distribution.py b/libiocage/lib/Distribution.py index ce3b8047..9fe06850 100644 --- a/libiocage/lib/Distribution.py +++ b/libiocage/lib/Distribution.py @@ -48,12 +48,11 @@ class DistributionGenerator: mirror_link_pattern = r"a href=\"([A-z0-9\-_\.]+)/\"" def __init__(self, host, zfs=None, logger=None): - libiocage.lib.helpers.init_logger(self, logger) - libiocage.lib.helpers.init_zfs(self, zfs) - libiocage.lib.helpers.init_host(self, host) + self.logger = libiocage.lib.helpers.init_logger(self, logger) + self.zfs = libiocage.lib.helpers.init_zfs(self, zfs) + self.host = libiocage.lib.helpers.init_host(self, host) + self.available_releases = None - self.zfs = zfs - self.logger = logger @property def name(self): @@ -133,18 +132,18 @@ def _get_eol_list(self) -> List[str]: _eol = "https://www.freebsd.org/security/unsupported.html" req = requests.get(_eol) status = req.status_code == requests.codes.ok - eol_releases = [] + eol_releases: List[str] = [] if not status: req.raise_for_status() for eol in req.content.decode("iso-8859-1").split(): - eol = eol.strip("href=").strip("/").split(">") + eol_lines = eol.strip("href=").strip("/").split(">") # We want a dynamic EOL try: - if "-RELEASE" in eol[1]: - eol = eol[1].strip(') """ - _class_host = libiocage.lib.Host.HostGenerator - _class_storage = libiocage.lib.Storage.Storage - def __init__(self, data={}, zfs=None, host=None, logger=None, new=False): """ Initializes a Jail @@ -107,9 +104,9 @@ def __init__(self, data={}, zfs=None, host=None, logger=None, new=False): """ - libiocage.lib.helpers.init_logger(self, logger) - libiocage.lib.helpers.init_zfs(self, zfs) - libiocage.lib.helpers.init_host(self, host) + self.logger = libiocage.lib.helpers.init_logger(self, logger) + self.zfs = libiocage.lib.helpers.init_zfs(self, zfs) + self.host = libiocage.lib.helpers.init_host(self, host) if isinstance(data, str): data = { @@ -124,7 +121,7 @@ def __init__(self, data={}, zfs=None, host=None, logger=None, new=False): self.networks = [] - self.storage = self._class_storage( + self.storage = libiocage.lib.Storage.Storage( auto_create=True, safe_mode=False, jail=self, @@ -944,8 +941,6 @@ def __dir__(self): class Jail(JailGenerator): - _class_host = libiocage.lib.Host.HostGenerator - def start(self, *args, **kwargs): return list(JailGenerator.start(self, *args, **kwargs)) diff --git a/libiocage/lib/JailConfig.py b/libiocage/lib/JailConfig.py index 8b9f0d19..d607d58d 100644 --- a/libiocage/lib/JailConfig.py +++ b/libiocage/lib/JailConfig.py @@ -79,8 +79,7 @@ def __init__(self, dict.__init__(self) - libiocage.lib.helpers.init_logger(self, logger) - + self.logger = libiocage.lib.helpers.init_logger(self, logger) self.data = {} self.special_properties = {} diff --git a/libiocage/lib/JailConfigFstab.py b/libiocage/lib/JailConfigFstab.py index 9485223f..882cdc5a 100644 --- a/libiocage/lib/JailConfigFstab.py +++ b/libiocage/lib/JailConfigFstab.py @@ -45,7 +45,7 @@ class JailConfigFstab(set): def __init__(self, jail, logger=None): set.__init__(self) - libiocage.lib.helpers.init_logger(self, logger) + self.logger = libiocage.lib.helpers.init_logger(self, logger) self.jail = jail @property diff --git a/libiocage/lib/JailConfigResolver.py b/libiocage/lib/JailConfigResolver.py index 0e1e5a5f..f581a86b 100644 --- a/libiocage/lib/JailConfigResolver.py +++ b/libiocage/lib/JailConfigResolver.py @@ -29,7 +29,7 @@ class JailConfigResolver(list): def __init__(self, jail_config, logger=None): list.__init__(self, []) - libiocage.lib.helpers.init_logger(self, logger) + self.logger = libiocage.lib.helpers.init_logger(self, logger) self.jail_config = jail_config self.jail_config.attach_special_property( name="resolver", diff --git a/libiocage/lib/JailFilter.py b/libiocage/lib/JailFilter.py index c9cf6f93..6be3b07b 100644 --- a/libiocage/lib/JailFilter.py +++ b/libiocage/lib/JailFilter.py @@ -21,10 +21,11 @@ # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -from typing import List, Union, Iterable import re -import libiocage.lib.Jail +from typing import Iterable, List, Union + import libiocage.lib.errors +import libiocage.lib.Jail def match_filter(value: str, filter_string: str): @@ -54,7 +55,7 @@ def __init__(self, key, values=list()): list.__init__(self, data) - def matches_jail(self, jail: libiocage.lib.Jail.JailGenerator) -> bool: + def matches_jail(self, jail: 'libiocage.lib.Jail.JailGenerator') -> bool: return self.matches(jail.getstring(self.key)) def matches(self, value: str) -> bool: @@ -83,7 +84,7 @@ def _filter_string_has_globs(self, filter_string: str) -> bool: return False def _split_filter_values(self, user_input: str) -> List[str]: - values = [] + values: List[str] = [] escaped_comma_blocks = map( lambda block: block.split(","), user_input.split("\\,") @@ -124,9 +125,9 @@ class Terms(list): This can be interpreted as logical AND """ - def __init__(self, terms: Iterable[Union[Term, str]]=None): + def __init__(self, terms: Iterable[Union[Term, str]]=None) -> None: - data = [] + data: List[Union[Term, str]] = [] if terms is not None: @@ -138,7 +139,7 @@ def __init__(self, terms: Iterable[Union[Term, str]]=None): list.__init__(self, data) - def match_jail(self, jail: libiocage.lib.Jail.JailGenerator) -> bool: + def match_jail(self, jail: 'libiocage.lib.Jail.JailGenerator') -> bool: """ Returns True if all Terms match the jail """ diff --git a/libiocage/lib/Jails.py b/libiocage/lib/Jails.py index c490c949..aaf5a1b8 100644 --- a/libiocage/lib/Jails.py +++ b/libiocage/lib/Jails.py @@ -46,9 +46,10 @@ def __init__(self, logger=None, zfs=None): - libiocage.lib.helpers.init_logger(self, logger) - libiocage.lib.helpers.init_zfs(self, zfs) - libiocage.lib.helpers.init_host(self, host) + self.logger = libiocage.lib.helpers.init_logger(self, logger) + self.host = libiocage.lib.helpers.init_host(self, host) + + self.zfs = libiocage.lib.helpers.init_zfs(self, zfs) self.zfs = libzfs.ZFS(history=True, history_prefix="") self._filters = None @@ -98,7 +99,7 @@ def jail_datasets(self) -> list: def _load_jail_from_dataset( self, dataset: libzfs.ZFSDataset - ) -> Generator[libiocage.lib.Jail.JailGenerator, None, None]: + ) -> Generator['libiocage.lib.Jail.JailGenerator', None, None]: return self._create_jail({ "name": self._get_name_from_jail_dataset(dataset) diff --git a/libiocage/lib/Logger.py b/libiocage/lib/Logger.py index 26a8be41..9b66a1be 100644 --- a/libiocage/lib/Logger.py +++ b/libiocage/lib/Logger.py @@ -26,6 +26,8 @@ import libiocage.lib.errors +from typing import List + class LogEntry: @@ -100,7 +102,7 @@ class Logger: INDENT_PREFIX = " " - PRINT_HISTORY = [] + PRINT_HISTORY: List[str] = [] def __init__(self, print_level=None, log_directory="/var/log/iocage"): self._print_level = print_level diff --git a/libiocage/lib/Network.py b/libiocage/lib/Network.py index 7c46b855..84ca6043 100644 --- a/libiocage/lib/Network.py +++ b/libiocage/lib/Network.py @@ -38,7 +38,7 @@ def __init__(self, jail, bridges=None, logger=None): - libiocage.lib.helpers.init_logger(self, logger) + self.logger = libiocage.lib.helpers.init_logger(self, logger) if bridges is not None: if not isinstance(bridges, list): diff --git a/libiocage/lib/Prompts.py b/libiocage/lib/Prompts.py index 19ba2408..dd0475de 100644 --- a/libiocage/lib/Prompts.py +++ b/libiocage/lib/Prompts.py @@ -27,8 +27,8 @@ class Prompts: def __init__(self, host=None, logger=None): - self.logger = logger - libiocage.lib.helpers.init_host(self, host) + self.logger = libiocage.lib.helpers.init_logger(self, logger) + self.host = libiocage.lib.helpers.init_host(self, host) def release(self): default = None diff --git a/libiocage/lib/RCConf.py b/libiocage/lib/RCConf.py index a2ecc117..0ee2dc12 100644 --- a/libiocage/lib/RCConf.py +++ b/libiocage/lib/RCConf.py @@ -32,7 +32,7 @@ class RCConf(dict): def __init__(self, path, data={}, logger=None, jail=None): dict.__init__(self, {}) - libiocage.lib.helpers.init_logger(self, logger=logger) + self.logger = libiocage.lib.helpers.init_logger(self, logger) self.jail = jail # No file was loaded yet, so we can't know the delta yet diff --git a/libiocage/lib/Release.py b/libiocage/lib/Release.py index d1c4c2fe..908dcb54 100644 --- a/libiocage/lib/Release.py +++ b/libiocage/lib/Release.py @@ -56,9 +56,9 @@ def __init__(self, name=None, check_hashes=True, eol=False): - libiocage.lib.helpers.init_logger(self, logger) - libiocage.lib.helpers.init_zfs(self, zfs) - libiocage.lib.helpers.init_host(self, host) + self.logger = libiocage.lib.helpers.init_logger(self, logger) + self.zfs = libiocage.lib.helpers.init_zfs(self, zfs) + self.host = libiocage.lib.helpers.init_host(self, host) if not libiocage.lib.helpers.validate_name(name): raise NameError(f"Invalid 'name' for Release: '{name}'") diff --git a/libiocage/lib/Releases.py b/libiocage/lib/Releases.py index 8009cc9d..0717d99e 100644 --- a/libiocage/lib/Releases.py +++ b/libiocage/lib/Releases.py @@ -27,9 +27,9 @@ class Releases: def __init__(self, host=None, zfs=None, logger=None): - libiocage.lib.helpers.init_host(self, host) - self.logger = logger - self.zfs = zfs + self.logger = libiocage.lib.helpers.init_logger(self, logger) + self.zfs = libiocage.lib.helpers.init_zfs(self, zfs) + self.host = libiocage.lib.helpers.init_host(self, host) @property def dataset(self): diff --git a/libiocage/lib/Storage.py b/libiocage/lib/Storage.py index c453d02d..f3852d97 100644 --- a/libiocage/lib/Storage.py +++ b/libiocage/lib/Storage.py @@ -35,9 +35,8 @@ def __init__(self, jail, safe_mode=True, logger=None): - libiocage.lib.helpers.init_logger(self, logger) - libiocage.lib.helpers.init_zfs(self, zfs) - + self.logger = libiocage.lib.helpers.init_logger(self, logger) + self.zfs = libiocage.lib.helpers.init_zfs(self, zfs) self.jail = jail # when auto_create is enabled, non-existing zfs volumes will be diff --git a/libiocage/lib/errors.py b/libiocage/lib/errors.py index 1990441d..cdea82f3 100644 --- a/libiocage/lib/errors.py +++ b/libiocage/lib/errors.py @@ -412,7 +412,13 @@ def __init__(self, *args, **kwargs): class MissingFeature(IocageException, NotImplementedError): - def __init__(self, feature_name: str, plural: bool=False, *args, **kwargs): + def __init__( + self, + feature_name: str, + plural: bool=False, + *args, + **kwargs + ) -> None: message = ( f"Missing Feature: '{feature_name}' " "are" if plural is True else "is" diff --git a/libiocage/lib/events.py b/libiocage/lib/events.py index f1772243..730ac733 100644 --- a/libiocage/lib/events.py +++ b/libiocage/lib/events.py @@ -22,6 +22,8 @@ # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. from timeit import default_timer as timer +from typing import List + import libiocage.lib.errors EVENT_STATUS = ( @@ -38,7 +40,7 @@ class IocageEvent: Base class for all other iocage events """ - HISTORY = [] + HISTORY: List['IocageEvent'] = [] PENDING_COUNT = 0 diff --git a/libiocage/lib/helpers.py b/libiocage/lib/helpers.py index 7a76ebb1..9bcaba2d 100644 --- a/libiocage/lib/helpers.py +++ b/libiocage/lib/helpers.py @@ -25,37 +25,34 @@ import subprocess import uuid -import libzfs - import libiocage.lib.Datasets import libiocage.lib.Host import libiocage.lib.Logger +import libzfs -def init_zfs(self, zfs): +def init_zfs( + self, + zfs: libzfs.ZFS=None +) -> libzfs.ZFS: if isinstance(zfs, libzfs.ZFS): - self.zfs = zfs + return zfs else: - self.zfs = get_zfs() + return get_zfs() def get_zfs(): return libzfs.ZFS(history=True, history_prefix="") -def init_host(self, host=None): +def init_host( + self, + host: 'libiocage.lib.Host.Host'=None, +) -> 'libiocage.lib.Host.HostGenerator': if host: - self.host = host - else: - try: - logger = self.logger - except: - logger = None + return host - try: - self.host = self._class_host(logger=logger) - except: - self.host = libiocage.lib.Host.HostGenerator(logger=logger) + return libiocage.lib.Host.HostGenerator(self.logger) def init_datasets(self, datasets=None): @@ -65,12 +62,14 @@ def init_datasets(self, datasets=None): self.datasets = libiocage.lib.Datasets.Datasets() -def init_logger(self, logger=None): +def init_logger( + self, + logger: 'libiocage.lib.Logger.Logger'=None +) -> 'libiocage.lib.Logger.Logger': if logger is not None: - object.__setattr__(self, 'logger', logger) + return logger else: - new_logger = libiocage.lib.Logger.Logger() - object.__setattr__(self, 'logger', new_logger) + return libiocage.lib.Logger.Logger() def exec(command, logger=None, ignore_error=False): diff --git a/setup.cfg b/setup.cfg index 0fa743fd..defb2320 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,9 @@ [metadata] description-file = README.md +[mypy] +python_version = 3.6 + [tool:pytest] addopts = -v -x -rs --ignore=setup.py --pep8 --cov-report term-missing --cov=libiocage/lib libiocage/lib libiocage/tests pep8maxlinelength = 80