diff --git a/setup.cfg b/setup.cfg index d0b23d7..2cbca99 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [flake8] -ignore = E501,E402 +ignore = E402 max-line-length = 119 exclude = .git,.tox,build,_build,env,venv,__pycache__ diff --git a/src/simplezfs/types.py b/src/simplezfs/types.py index 3aa77a4..cdc5b38 100644 --- a/src/simplezfs/types.py +++ b/src/simplezfs/types.py @@ -107,7 +107,7 @@ class PropertySource(str, Enum): INHERITED = 'inherited' #: Property is temporary TEMPORARY = 'temporary' - #: Property is set to the value that it had due to the sender of a "zfs send/receive" operation having it set this way. + #: Property value is set due to a "zfs send/receive" operation. RECEIVED = 'received' #: Property is set on the dataset in question NONE = 'none' diff --git a/src/simplezfs/validation.py b/src/simplezfs/validation.py index 67de088..236ef07 100644 --- a/src/simplezfs/validation.py +++ b/src/simplezfs/validation.py @@ -17,7 +17,7 @@ METADATA_PROPERTY_NAME_LEN_MAX: int = MAXNAMELEN #: Maximum length of a metadata property value in bytes METADATA_PROPERTY_VALUE_LEN_MAX: int = 8192 -#: Regular expression for validating dataset names, handling both the name itself as well as snapshot or bookmark names. +#: Regular expression for validating dataset names, handling both the name itself as well as snapshot or bookmark names DATASET_NAME_RE = re.compile(r'^(?P[a-zA-Z0-9_\-.:]+)(?P(@|#)[a-zA-Z0-9_\-.:]+)?$') #: Regular expression for validating a native property name NATIVE_PROPERTY_NAME_RE = re.compile(r'^[a-z]([a-z0-9]+)?$') diff --git a/src/simplezfs/zfs.py b/src/simplezfs/zfs.py index 20671ab..dcd699a 100644 --- a/src/simplezfs/zfs.py +++ b/src/simplezfs/zfs.py @@ -45,8 +45,8 @@ class ZFS: The functions :func:`set_property`, :func:`get_property` and :func:`get_properties` wrap the ZFS get/set functionality. To support so-called `user properties`, which are called `metadata` in this API, a default namespace - can be stored using `metadata_namespace` when instantiating the interface or by calling :func:`set_metadata_namespace` - at any time. + can be stored using `metadata_namespace` when instantiating the interface or by calling + :func:`set_metadata_namespace` at any time. :note: Not setting a metadata namespace means that one can't set or get metadata properties, unless the overwrite parameter for the get/set functions is used. @@ -155,8 +155,8 @@ class ZFS: def list_datasets(self, *, parent: Union[str, Dataset] = None) -> List[Dataset]: ''' - Lists all datasets known to the system. If ``parent`` is set to a pool or dataset name (or a :class:`~zfs.types.Dataset`), - lists all the children of that dataset. + Lists all datasets known to the system. If ``parent`` is set to a pool or dataset name (or a + :class:`~zfs.types.Dataset`), lists all the children of that dataset. :param parent: If set, list all child datasets. :return: The list of datasets. @@ -177,7 +177,8 @@ class ZFS: # real_use_pe_helper = use_pe_helper if use_pe_helper is not None else self.use_pe_helper raise NotImplementedError(f'not implemented yet') - def set_property(self, dataset: str, key: str, value: str, *, metadata: bool = False, overwrite_metadata_namespace: Optional[str] = None) -> None: + def set_property(self, dataset: str, key: str, value: str, *, metadata: bool = False, + overwrite_metadata_namespace: Optional[str] = None) -> None: ''' Sets the ``value`` of the native property ``key``. By default, only native properties can be set. If ``metadata`` is set to **True**, the default metadata namespace is prepended or the one in @@ -237,12 +238,13 @@ class ZFS: ''' raise NotImplementedError(f'{self} has not implemented this function') - def get_property(self, dataset: str, key: str, *, metadata: bool = False, overwrite_metadata_namespace: Optional[str] = None) -> Property: + def get_property(self, dataset: str, key: str, *, metadata: bool = False, + overwrite_metadata_namespace: Optional[str] = None) -> Property: ''' Gets a specific property named ``key`` from the ``dataset``. By default, only native properties are returned. - This behaviour can be changed by setting ``metadata`` to **True**, which uses the default `metadata_namespace` to - select the namespace. The namespace can be overwritten using ``overwrite_metadata_namespace`` for the duration of the - method invocaton. + This behaviour can be changed by setting ``metadata`` to **True**, which uses the default `metadata_namespace` + to select the namespace. The namespace can be overwritten using ``overwrite_metadata_namespace`` for the + duration of the method invocaton. :param dataset: Name of the dataset to get the property. Expects the full path beginning with the pool name. :param key: Name of the property to set. For non-native properties, set ``metadata`` to **True** and overwrite @@ -461,8 +463,8 @@ class ZFS: .. warning:: - On Linux, only root is allowed to manipulate the namespace (aka `mount`). Refer to :ref:`the_mount_problem` in - the documentation. + On Linux, only root is allowed to manipulate the namespace (aka `mount`). Refer to :ref:`the_mount_problem` + in the documentation. :param name: The name of the new dataset. This includes the full path, e.g. ``tank/data/newdataset``. :param dataset_type: Indicates the type of the dataset to be created. @@ -572,7 +574,9 @@ class ZFS: # TODO - return self._create_dataset(name, dataset_type=dataset_type, properties=properties, metadata_properties=_metadata_properties, sparse=sparse, size=size, recursive=recursive) + return self._create_dataset(name, dataset_type=dataset_type, properties=properties, + metadata_properties=_metadata_properties, sparse=sparse, size=size, + recursive=recursive) def _create_dataset( self, diff --git a/src/simplezfs/zfs_cli.py b/src/simplezfs/zfs_cli.py index 7245263..758e535 100644 --- a/src/simplezfs/zfs_cli.py +++ b/src/simplezfs/zfs_cli.py @@ -204,7 +204,8 @@ class ZFSCli(ZFS): if include_metadata: namespace = prop_name.split(':')[0] prop_name = prop_name.lstrip(f'{namespace}:') - res.append(Property(key=prop_name, value=prop_value, source=property_source, namespace=namespace)) + res.append(Property(key=prop_name, value=prop_value, source=property_source, + namespace=namespace)) else: res.append(Property(key=prop_name, value=prop_value, source=property_source, namespace=None)) return res diff --git a/src/simplezfs/zfs_native.py b/src/simplezfs/zfs_native.py index 7c9f546..703af2a 100644 --- a/src/simplezfs/zfs_native.py +++ b/src/simplezfs/zfs_native.py @@ -25,10 +25,12 @@ class ZFSNative(ZFS): def __repr__(self) -> str: return f'' - def set_property(self, dataset: str, key: str, value: str, *, metadata: bool = False, overwrite_metadata_namespace: Optional[str] = None) -> None: + def set_property(self, dataset: str, key: str, value: str, *, metadata: bool = False, + overwrite_metadata_namespace: Optional[str] = None) -> None: raise NotImplementedError - def get_property(self, dataset: str, key: str, *, metadata: bool = False, overwrite_metadata_namespace: Optional[str] = None) -> Property: + def get_property(self, dataset: str, key: str, *, metadata: bool = False, + overwrite_metadata_namespace: Optional[str] = None) -> Property: raise NotImplementedError def get_properties(self, dataset: str, *, include_metadata: bool = False) -> List[Property]: diff --git a/tests/test_enums.py b/tests/test_enums.py index 42e62c8..2f06be5 100644 --- a/tests/test_enums.py +++ b/tests/test_enums.py @@ -6,7 +6,10 @@ from simplezfs.types import DatasetType, PropertySource class TestDatasetType: - @pytest.mark.parametrize('string,value', [('FiLeSet', DatasetType.FILESET), ('fileset', DatasetType.FILESET), ('vOlUMe', DatasetType.VOLUME), ('volume', DatasetType.VOLUME), ('SnapSHOT', DatasetType.SNAPSHOT), ('snapshot', DatasetType.SNAPSHOT), ('BOOKmark', DatasetType.BOOKMARK), ('bookmark', DatasetType.BOOKMARK)]) + @pytest.mark.parametrize('string,value', [('FiLeSet', DatasetType.FILESET), ('fileset', DatasetType.FILESET), + ('vOlUMe', DatasetType.VOLUME), ('volume', DatasetType.VOLUME), + ('SnapSHOT', DatasetType.SNAPSHOT), ('snapshot', DatasetType.SNAPSHOT), + ('BOOKmark', DatasetType.BOOKMARK), ('bookmark', DatasetType.BOOKMARK)]) def test_from_string_valid(self, string, value): ''' Tests that the from_string helper works. @@ -35,7 +38,12 @@ class TestDatasetType: class TestPropertySource: - @pytest.mark.parametrize('string,value', [('default', PropertySource.DEFAULT), ('DeFAULT', PropertySource.DEFAULT), ('inheriteD', PropertySource.INHERITED), ('inherited', PropertySource.INHERITED), ('TEMPORARY', PropertySource.TEMPORARY), ('temporary', PropertySource.TEMPORARY), ('rEcEiVeD', PropertySource.RECEIVED), ('received', PropertySource.RECEIVED), ('None', PropertySource.NONE), ('none', PropertySource.NONE)]) + @pytest.mark.parametrize('string,value', [ + ('default', PropertySource.DEFAULT), ('DeFAULT', PropertySource.DEFAULT), + ('inheriteD', PropertySource.INHERITED), ('inherited', PropertySource.INHERITED), + ('TEMPORARY', PropertySource.TEMPORARY), ('temporary', PropertySource.TEMPORARY), + ('rEcEiVeD', PropertySource.RECEIVED), ('received', PropertySource.RECEIVED), + ('None', PropertySource.NONE), ('none', PropertySource.NONE)]) def test_from_string_valid(self, string, value): ''' Test that the from_string helper works. diff --git a/tests/test_validation.py b/tests/test_validation.py index 7dae5a8..56b54b5 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -84,14 +84,18 @@ class TestDatasetName: Tests the function ``validate_dataset_name``. ''' - @pytest.mark.parametrize('name', ['a', 'aa', '0', '0a', 'A', 'A0', 'qwertzuiop', 'a-', '-a', 'a.a', '.', 'a:', ':a', 'a:a', 'a::a', '842bf5a29bd55c12c20a8d1e73bdb5790e8ab804d857885e35e55be025acb6b2', '842bf5a29bd55c12c20a8d1e73bdb5790e8ab804d857885e35e55be025acb6b2-init', 'towel@20190525', 'page#42']) + @pytest.mark.parametrize('name', [ + 'a', 'aa', '0', '0a', 'A', 'A0', 'qwertzuiop', 'a-', '-a', 'a.a', '.', 'a:', ':a', 'a:a', 'a::a', + '842bf5a29bd55c12c20a8d1e73bdb5790e8ab804d857885e35e55be025acb6b2', + '842bf5a29bd55c12c20a8d1e73bdb5790e8ab804d857885e35e55be025acb6b2-init', 'towel@20190525', 'page#42']) def test_valid_name(self, name): ''' Tests a set of known good combinations. ''' validate_dataset_name(name) - @pytest.mark.parametrize('name', ['/a', '/', 'a/a', 'a/', 'a+', 'ä', '→', '\0', '\n', 'towel@@20190525', 'towel@#42', 'page##42', 'page#@20190525']) + @pytest.mark.parametrize('name', ['/a', '/', 'a/a', 'a/', 'a+', 'ä', '→', '\0', '\n', 'towel@@20190525', + 'towel@#42', 'page##42', 'page#@20190525']) def test_invalid_name(self, name): ''' Tests a set of known invalid combinations. @@ -172,7 +176,8 @@ class TestNativePropertyName: ''' validate_native_property_name(name) - @pytest.mark.parametrize('name', ['0', '0a', 'A', 'AA', '-', 'a-', 'a-a', '-a', '_', 'a_', 'a_a', '_a', ':', 'a:', 'a:a', ':a', '\0']) + @pytest.mark.parametrize('name', ['0', '0a', 'A', 'AA', '-', 'a-', 'a-a', '-a', '_', 'a_', 'a_a', '_a', ':', 'a:', + 'a:a', ':a', '\0']) def test_invalid_name(self, name): ''' Tests a set of known invalid combinations. @@ -211,7 +216,8 @@ class TestMetadataPropertyName: ''' validate_metadata_property_name(name) - @pytest.mark.parametrize('name', ['0', '0a', 'A', 'AA', '-', 'a-', 'a-a', '-a', '_', 'a_', 'a_a', '_a', ':', 'a:', '\0', 'a+:a']) + @pytest.mark.parametrize('name', ['0', '0a', 'A', 'AA', '-', 'a-', 'a-a', '-a', '_', 'a_', 'a_a', '_a', ':', 'a:', + '\0', 'a+:a']) def test_invalid_name(self, name): ''' Tests a set of known invalid combinations. diff --git a/tests/test_zfs_cli.py b/tests/test_zfs_cli.py index 895f0f4..1367b80 100644 --- a/tests/test_zfs_cli.py +++ b/tests/test_zfs_cli.py @@ -97,7 +97,7 @@ class TestZFSCli: subproc.assert_called_once() assert ['/bin/true', 'list', '-H', '-t', 'all', 'rpool'] == subproc.call_args[0][0] assert data.pool == 'rpool' - assert data.parent == None + assert data.parent is None assert data.name == 'rpool' assert data.type == DatasetType.VOLUME assert data.full_path == 'rpool' @@ -158,7 +158,8 @@ tank/system/root 14.9G 13.3G 14.9G /''' subproc.return_value = subprocess.CompletedProcess(args=[], returncode=0, stdout=test_stdout, stderr='') zfs = ZFSCli(zfs_exe='/bin/true') - lst = zfs.list_datasets(parent=Dataset(pool='tank', name='system', full_path='tank', parent='tank', type=DatasetType.FILESET)) + lst = zfs.list_datasets(parent=Dataset(pool='tank', name='system', full_path='tank', parent='tank', + type=DatasetType.FILESET)) subproc.assert_called_once() assert ['/bin/true', 'list', '-H', '-r', '-t', 'all', 'tank'] == subproc.call_args[0][0] assert len(lst) == 4 @@ -202,7 +203,8 @@ tank/system/root 14.9G 13.3G 14.9G /''' subproc.return_value = subprocess.CompletedProcess(args=[], returncode=0, stdout=test_stdout, stderr='') zfs = ZFSCli(zfs_exe='/bin/true') - lst = zfs.list_datasets(parent=Dataset(pool='tank', full_path='tank/system', name='system', parent='tank', type=DatasetType.FILESET)) + lst = zfs.list_datasets(parent=Dataset(pool='tank', full_path='tank/system', name='system', parent='tank', + type=DatasetType.FILESET)) subproc.assert_called_once() assert ['/bin/true', 'list', '-H', '-r', '-t', 'all', 'tank/system'] == subproc.call_args[0][0] assert len(lst) == 3