From 90ee9a08f44e7b28a295ded5bbaea53538e477db Mon Sep 17 00:00:00 2001 From: Joachim Metz Date: Sun, 28 Jan 2024 17:30:41 +0100 Subject: [PATCH] Changes to use docformatter (#760) --- config/dpkg/changelog | 4 +- dependencies.ini | 16 ++-- dfvfs/__init__.py | 8 +- dfvfs/analyzer/analyzer_helper.py | 14 ++- dfvfs/analyzer/specification.py | 6 +- dfvfs/credentials/keychain.py | 6 +- dfvfs/file_io/apfs_file_io.py | 2 +- dfvfs/file_io/compressed_stream_io.py | 6 +- dfvfs/file_io/data_range_io.py | 13 ++- dfvfs/file_io/encoded_stream_io.py | 6 +- dfvfs/file_io/encrypted_stream_io.py | 6 +- dfvfs/file_io/ext_file_io.py | 2 +- dfvfs/file_io/fat_file_io.py | 2 +- dfvfs/file_io/gzip_file_io.py | 30 +++++- dfvfs/file_io/hfs_file_io.py | 2 +- dfvfs/file_io/xfs_file_io.py | 2 +- dfvfs/helpers/source_scanner.py | 12 ++- dfvfs/lib/gzipfile.py | 6 +- dfvfs/vfs/apfs_container_file_entry.py | 18 +++- dfvfs/vfs/directory.py | 6 +- dfvfs/vfs/file_entry.py | 109 +++++++++++++++++----- dfvfs/volume/volume_system.py | 54 +++++++++-- docs/conf.py | 1 + pyproject.toml | 7 ++ setup.cfg | 2 +- tests/vfs/apfs_container_file_entry.py | 4 +- tests/vfs/apfs_file_entry.py | 4 +- tests/vfs/apm_file_entry.py | 2 +- tests/vfs/compressed_stream_file_entry.py | 2 +- tests/vfs/cpio_file_entry.py | 2 +- tests/vfs/cs_file_entry.py | 2 +- tests/vfs/data_range_file_entry.py | 2 +- tests/vfs/encoded_stream_file_entry.py | 2 +- tests/vfs/encrypted_stream_file_entry.py | 2 +- tests/vfs/ext_file_entry.py | 4 +- tests/vfs/fake_file_entry.py | 2 +- tests/vfs/fat_file_entry.py | 2 +- tests/vfs/gpt_file_entry.py | 2 +- tests/vfs/gzip_file_entry.py | 2 +- tests/vfs/hfs_file_entry.py | 2 +- tests/vfs/luksde_file_entry.py | 2 +- tests/vfs/lvm_file_entry.py | 2 +- tests/vfs/os_file_entry.py | 2 +- tests/vfs/os_file_system.py | 2 +- tests/vfs/sqlite_blob_file_entry.py | 2 +- tests/vfs/tar_file_entry.py | 2 +- tests/vfs/tsk_file_entry.py | 10 +- tests/vfs/tsk_partition_file_entry.py | 6 +- tests/vfs/vshadow_file_entry.py | 2 +- tests/vfs/xfs_file_entry.py | 2 +- tox.ini | 13 ++- utils/update_release.sh | 2 +- 52 files changed, 301 insertions(+), 122 deletions(-) diff --git a/config/dpkg/changelog b/config/dpkg/changelog index 871e682d..d2c8c749 100644 --- a/config/dpkg/changelog +++ b/config/dpkg/changelog @@ -1,5 +1,5 @@ -dfvfs (20240115-1) unstable; urgency=low +dfvfs (20240128-1) unstable; urgency=low * Auto-generated - -- Log2Timeline maintainers Mon, 15 Jan 2024 05:37:59 +0100 + -- Log2Timeline maintainers Sun, 28 Jan 2024 13:31:12 +0100 diff --git a/dependencies.ini b/dependencies.ini index 5d57584b..d29b0e01 100644 --- a/dependencies.ini +++ b/dependencies.ini @@ -25,14 +25,6 @@ minimum_version: 2.5 rpm_name: python3-idna version_property: __version__ -[pycaes] -dpkg_name: libcaes-python3 -l2tbinaries_name: libcaes -minimum_version: 20240114 -pypi_name: libcaes-python -rpm_name: libcaes-python3 -version_property: get_version() - [pybde] dpkg_name: libbde-python3 l2tbinaries_name: libbde @@ -41,6 +33,14 @@ pypi_name: libbde-python rpm_name: libbde-python3 version_property: get_version() +[pycaes] +dpkg_name: libcaes-python3 +l2tbinaries_name: libcaes +minimum_version: 20240114 +pypi_name: libcaes-python +rpm_name: libcaes-python3 +version_property: get_version() + [pyewf] dpkg_name: libewf-python3 l2tbinaries_name: libewf diff --git a/dfvfs/__init__.py b/dfvfs/__init__.py index dafcd350..b2f3dfb9 100644 --- a/dfvfs/__init__.py +++ b/dfvfs/__init__.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- """Digital Forensics Virtual File System (dfVFS). -dfVFS, or Digital Forensics Virtual File System, is a Python module -that provides read-only access to file-system objects from various -storage media types and file formats. +dfVFS, or Digital Forensics Virtual File System, is a Python module that +provides read-only access to file-system objects from various storage media +types and file formats. """ -__version__ = '20240115' +__version__ = '20240128' diff --git a/dfvfs/analyzer/analyzer_helper.py b/dfvfs/analyzer/analyzer_helper.py index 810af404..0e0b0c07 100644 --- a/dfvfs/analyzer/analyzer_helper.py +++ b/dfvfs/analyzer/analyzer_helper.py @@ -26,18 +26,24 @@ def __init__(self): @property def format_categories(self): - """set[str]: format categories, such as archive file or file system. + """Retrieves the format categories. The format categories are defined in definitions.FORMAT_CATEGORIES. + + Returns: + set[str]: format categories, such as archive file or file system. """ # pylint: disable=no-member return self.FORMAT_CATEGORIES @property def type_indicator(self): - """str: type indicator.""" - # pylint: disable=no-member - return self.TYPE_INDICATOR + """Retrieves the type indicator. + + Returns: + str: type indicator or None if not available. + """ + return getattr(self, 'TYPE_INDICATOR', None) def AnalyzeFileObject(self, file_object): # pylint: disable=useless-type-doc """Retrieves the format specification. diff --git a/dfvfs/analyzer/specification.py b/dfvfs/analyzer/specification.py index fcfdaaa9..ea4da0a5 100644 --- a/dfvfs/analyzer/specification.py +++ b/dfvfs/analyzer/specification.py @@ -81,7 +81,11 @@ def __init__(self): @property def specifications(self): - """generator[FormatSpecification]: format specifications.""" + """Retrieves the format specifications. + + Returns: + generator[FormatSpecification]: format specifications. + """ return iter(self._format_specifications.values()) def AddNewSpecification(self, identifier): diff --git a/dfvfs/credentials/keychain.py b/dfvfs/credentials/keychain.py index 130d84e4..c8212f9b 100644 --- a/dfvfs/credentials/keychain.py +++ b/dfvfs/credentials/keychain.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- """The path specification key chain. -The key chain is used to manage credentials for path specifications. -E.g. BitLocker Drive Encryption (BDE) encrypted volumes can require a -credential (e.g. password) to access the unencrypted data (unlock). +The key chain is used to manage credentials for path specifications. E.g. +BitLocker Drive Encryption (BDE) encrypted volumes can require a credential +(e.g. password) to access the unencrypted data (unlock). """ from dfvfs.credentials import manager diff --git a/dfvfs/file_io/apfs_file_io.py b/dfvfs/file_io/apfs_file_io.py index 072b58fe..7d0d7864 100644 --- a/dfvfs/file_io/apfs_file_io.py +++ b/dfvfs/file_io/apfs_file_io.py @@ -9,7 +9,7 @@ class APFSFile(file_io.FileIO): - """File input/output (IO) object using pyfsapfs.file_entry""" + """File input/output (IO) object using pyfsapfs.file_entry.""" def __init__(self, resolver_context, path_spec): """Initializes a file input/output (IO) object. diff --git a/dfvfs/file_io/compressed_stream_io.py b/dfvfs/file_io/compressed_stream_io.py index 7ada3282..15f909ae 100644 --- a/dfvfs/file_io/compressed_stream_io.py +++ b/dfvfs/file_io/compressed_stream_io.py @@ -37,9 +37,9 @@ def __init__(self, resolver_context, path_spec): def _Close(self): """Closes the file-like object. - If the file-like object was passed in the init function - the compressed stream file-like object does not control - the file-like object and should not actually close it. + If the file-like object was passed in the init function the compressed + stream file-like object does not control the file-like object and should not + actually close it. """ self._compressed_data = b'' self._file_object = None diff --git a/dfvfs/file_io/data_range_io.py b/dfvfs/file_io/data_range_io.py index 633677a2..40d12796 100644 --- a/dfvfs/file_io/data_range_io.py +++ b/dfvfs/file_io/data_range_io.py @@ -11,10 +11,9 @@ class DataRange(file_io.FileIO): """File input/output (IO) object that maps an in-file data range. - The data range object allows to expose a single partition within - a full disk image as a separate file-like object by mapping - the data range (offset and size) of the volume on top of the full disk - image. + The data range object allows to expose a single partition within a full disk + image as a separate file-like object by mapping the data range (offset and + size) of the volume on top of the full disk image. """ def __init__(self, resolver_context, path_spec): @@ -33,9 +32,9 @@ def __init__(self, resolver_context, path_spec): def _Close(self): """Closes the file-like object. - If the file-like object was passed in the init function - the data range file-like object does not control the file-like object - and should not actually close it. + If the file-like object was passed in the init function the data range file- + like object does not control the file-like object and should not actually + close it. """ self._file_object = None self._range_offset = -1 diff --git a/dfvfs/file_io/encoded_stream_io.py b/dfvfs/file_io/encoded_stream_io.py index c65ad1a3..187dc0f8 100644 --- a/dfvfs/file_io/encoded_stream_io.py +++ b/dfvfs/file_io/encoded_stream_io.py @@ -37,9 +37,9 @@ def __init__(self, resolver_context, path_spec): def _Close(self): """Closes the file-like object. - If the file-like object was passed in the init function - the encoded stream file-like object does not control - the file-like object and should not actually close it. + If the file-like object was passed in the init function the encoded stream + file-like object does not control the file-like object and should not + actually close it. """ self._decoder = None self._decoded_data = b'' diff --git a/dfvfs/file_io/encrypted_stream_io.py b/dfvfs/file_io/encrypted_stream_io.py index 865a4146..f265700f 100644 --- a/dfvfs/file_io/encrypted_stream_io.py +++ b/dfvfs/file_io/encrypted_stream_io.py @@ -37,9 +37,9 @@ def __init__(self, resolver_context, path_spec): def _Close(self): """Closes the file-like object. - If the file-like object was passed in the init function - the encrypted stream file-like object does not control - the file-like object and should not actually close it. + If the file-like object was passed in the init function the encrypted stream + file-like object does not control the file-like object and should not + actually close it. """ self._decrypter = None self._decrypted_data = b'' diff --git a/dfvfs/file_io/ext_file_io.py b/dfvfs/file_io/ext_file_io.py index 3e497d96..bd940f6a 100644 --- a/dfvfs/file_io/ext_file_io.py +++ b/dfvfs/file_io/ext_file_io.py @@ -9,7 +9,7 @@ class EXTFile(file_io.FileIO): - """File input/output (IO) object using pyfsext.file_entry""" + """File input/output (IO) object using pyfsext.file_entry.""" def __init__(self, resolver_context, path_spec): """Initializes a file input/output (IO) object. diff --git a/dfvfs/file_io/fat_file_io.py b/dfvfs/file_io/fat_file_io.py index e8f2ddcd..4d440d14 100644 --- a/dfvfs/file_io/fat_file_io.py +++ b/dfvfs/file_io/fat_file_io.py @@ -8,7 +8,7 @@ class FATFile(file_io.FileIO): - """File input/output (IO) object using pyfsfat.file_entry""" + """File input/output (IO) object using pyfsfat.file_entry.""" def __init__(self, resolver_context, path_spec): """Initializes a file input/output (IO) object. diff --git a/dfvfs/file_io/gzip_file_io.py b/dfvfs/file_io/gzip_file_io.py index fdf4db36..fe39e4d1 100644 --- a/dfvfs/file_io/gzip_file_io.py +++ b/dfvfs/file_io/gzip_file_io.py @@ -12,27 +12,47 @@ class GzipFile(file_object_io.FileObjectIO): @property def comments(self): - """list(str): comments in the gzip file.""" + """Retrieves the comments. + + Returns: + list[str]: comments of the members. + """ return [member.comment for member in self._file_object.members] @property def modification_times(self): - """list(int): modification times stored in the gzip file.""" + """Retrieves the modification times. + + Returns: + list[str]: modification times of the members. + """ return [member.modification_time for member in self._file_object.members] @property def original_filenames(self): - """list(str): original filenames stored in the gzip file.""" + """Retrieves the original filenames. + + Returns: + list[str]: original filenames of the members. + """ return [member.original_filename for member in self._file_object.members] @property def operating_systems(self): - """list(int): operating system values stored in the gzip file.""" + """Retrieves the operating system values. + + Returns: + list[str]: operating system values of the members. + """ return [member.operating_system for member in self._file_object.members] @property def uncompressed_data_size(self): - """int: uncompressed data size.""" + """Retrieves the uncompressed data size. + + Returns: + int: uncompressed data size. + """ return self._file_object.uncompressed_data_size def _OpenFileObject(self, path_spec): diff --git a/dfvfs/file_io/hfs_file_io.py b/dfvfs/file_io/hfs_file_io.py index a39d6330..947b07c2 100644 --- a/dfvfs/file_io/hfs_file_io.py +++ b/dfvfs/file_io/hfs_file_io.py @@ -8,7 +8,7 @@ class HFSFile(file_io.FileIO): - """File input/output (IO) object using pyfshfs.file_entry""" + """File input/output (IO) object using pyfshfs.file_entry.""" def __init__(self, resolver_context, path_spec): """Initializes a file input/output (IO) object. diff --git a/dfvfs/file_io/xfs_file_io.py b/dfvfs/file_io/xfs_file_io.py index 1120057a..63e10485 100644 --- a/dfvfs/file_io/xfs_file_io.py +++ b/dfvfs/file_io/xfs_file_io.py @@ -9,7 +9,7 @@ class XFSFile(file_io.FileIO): - """File input/output (IO) object using pyfsxfs.file_entry""" + """File input/output (IO) object using pyfsxfs.file_entry.""" def __init__(self, resolver_context, path_spec): """Initializes a file input/output (IO) object. diff --git a/dfvfs/helpers/source_scanner.py b/dfvfs/helpers/source_scanner.py index 3cbd43bb..366ead4b 100644 --- a/dfvfs/helpers/source_scanner.py +++ b/dfvfs/helpers/source_scanner.py @@ -55,7 +55,11 @@ def __init__(self, path_spec): @property def type_indicator(self): - """str: path specification type indicator.""" + """Retrieves the type indicator. + + Returns: + str: path specification type indicator. + """ return self.path_spec.type_indicator def GetSubNodeByLocation(self, location): @@ -165,7 +169,11 @@ def __init__(self): @property def locked_scan_nodes(self): - """list[SourceScanNode]: locked scan nodes.""" + """Retrieves the locked scan nodes. + + Returns: + list[SourceScanNode]: locked scan nodes. + """ return list(self._locked_scan_nodes.values()) def AddScanNode(self, path_spec, parent_scan_node): diff --git a/dfvfs/lib/gzipfile.py b/dfvfs/lib/gzipfile.py index eaa9a554..923fe89a 100644 --- a/dfvfs/lib/gzipfile.py +++ b/dfvfs/lib/gzipfile.py @@ -427,7 +427,11 @@ def __init__(self): @property def members(self): - """list(GzipMember): members in the gzip file.""" + """Retrieves the members in the file. + + Returns: + list[GzipMember]: members in the file. + """ return list(self._members_by_end_offset.values()) def _GetMemberForOffset(self, offset): diff --git a/dfvfs/vfs/apfs_container_file_entry.py b/dfvfs/vfs/apfs_container_file_entry.py index dcc8fbf8..72a1d70a 100644 --- a/dfvfs/vfs/apfs_container_file_entry.py +++ b/dfvfs/vfs/apfs_container_file_entry.py @@ -80,7 +80,11 @@ def _GetSubFileEntries(self): @property def name(self): - """str: name of the file entry, which does not include the full path.""" + """Retrieves the name. + + Return: + str: name of the file entry, which does not include the full path. + """ if self._name is None: self._name = '' @@ -98,7 +102,11 @@ def name(self): @property def size(self): - """int: size of the file entry in bytes or None if not available.""" + """Retrieves the size. + + Returns: + int: size of the file entry in bytes or None if not available. + """ if self._fsapfs_volume is None: return None @@ -107,7 +115,11 @@ def size(self): @property def sub_file_entries(self): - """generator[APFSContainerFileEntry]: sub file entries.""" + """Retrieves sub file entries. + + Returns: + generator[APFSContainerFileEntry]: sub file entries. + """ return self._GetSubFileEntries() def GetAPFSVolume(self): diff --git a/dfvfs/vfs/directory.py b/dfvfs/vfs/directory.py index ae8b36f0..8a67bad7 100644 --- a/dfvfs/vfs/directory.py +++ b/dfvfs/vfs/directory.py @@ -34,5 +34,9 @@ def _EntriesGenerator(self): @property def entries(self): - """generator[PathSpec]: path specifications of the directory entries.""" + """Retrieves directory entries. + + Returns: + generator[PathSpec]: path specifications of the directory entries. + """ return self._EntriesGenerator() diff --git a/dfvfs/vfs/file_entry.py b/dfvfs/vfs/file_entry.py index 89635949..0c222346 100644 --- a/dfvfs/vfs/file_entry.py +++ b/dfvfs/vfs/file_entry.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- """The Virtual File System (VFS) file entry interface. -The file entry can be various file system elements like a regular file, -a directory or file system metadata. +The file entry can be various file system elements like a regular file, a +directory or file system metadata. """ import abc @@ -122,47 +122,83 @@ def _GetSubFileEntries(self): @property def access_time(self): - """dfdatetime.DateTimeValues: access time or None if not available.""" + """Retrieves the access time. + + Returns: + dfdatetime.DateTimeValues: access time or None if not available. + """ return None @property def added_time(self): - """dfdatetime.DateTimeValues: added time or None if not available.""" + """Retrieves the added time. + + Returns: + dfdatetime.DateTimeValues: added time or None if not available. + """ return None @property def attributes(self): - """generator[Attribute]: attributes.""" + """Retrieves attributes. + + Returns: + generator[Attribute]: attributes. + """ return self._GetAttributes() @property def backup_time(self): - """dfdatetime.DateTimeValues: backup time or None if not available.""" + """Retrieves the backup time. + + Returns: + dfdatetime.DateTimeValues: backup time or None if not available. + """ return None @property def change_time(self): - """dfdatetime.DateTimeValues: change time or None if not available.""" + """Retrieves the change time. + + Returns: + dfdatetime.DateTimeValues: change time or None if not available. + """ return None @property def creation_time(self): - """dfdatetime.DateTimeValues: creation time or None if not available.""" + """Retrieves the creation time. + + Returns: + dfdatetime.DateTimeValues: creation time or None if not available. + """ return None @property def deletion_time(self): - """dfdatetime.DateTimeValues: deletion time or None if not available.""" + """Retrieves the deletion time. + + Returns: + dfdatetime.DateTimeValues: deletion time or None if not available. + """ return None @property def data_streams(self): - """generator[DataStream]: data streams.""" + """Retrieves data streams. + + Returns: + generator[DataStream]: data streams. + """ return self._GetDataStreams() @property def link(self): - """str: full path of the linked file entry or None if not available.""" + """Retrieves the path of a linked file entry. + + Returns: + str: full path of the linked file entry or None if not available. + """ if not self.IsLink(): return None @@ -170,29 +206,49 @@ def link(self): @property def modification_time(self): - """dfdatetime.DateTimeValues: modification time or None if not available.""" + """Retrieves the modification time. + + Returns: + dfdatetime.DateTimeValues: modification time or None if not available. + """ return None @property @abc.abstractmethod def name(self): - """str: name of the file entry, without the full path.""" + """Retrieves the name. + + Returns: + str: name of the file entry, without the full path. + """ @property def number_of_attributes(self): - """int: number of attributes.""" + """Retrieves the number of attributes. + + Returns: + int: number of attributes. + """ attributes = self._GetAttributes() return len(attributes) @property def number_of_data_streams(self): - """int: number of data streams.""" + """Retrieves the number of data streams. + + Returns: + int: number of data streams. + """ data_streams = self._GetDataStreams() return len(data_streams) @property def number_of_sub_file_entries(self): - """int: number of sub file entries.""" + """Retrieves the number of sub file entries. + + Returns: + int: number of sub file entries. + """ number_of_sub_file_entries = 0 if self.entry_type == definitions.FILE_ENTRY_TYPE_DIRECTORY: directory = self._GetDirectory() @@ -203,19 +259,30 @@ def number_of_sub_file_entries(self): @property def size(self): - """int: size of the file entry in bytes or None if not available.""" + """Retrieves the size. + + Returns: + int: size of the file entry in bytes or None if not available. + """ return None @property def sub_file_entries(self): - """generator[FileEntry]: sub file entries.""" + """Retrieves sub file entries. + + Returns: + generator[FileEntry]: sub file entries. + """ return self._GetSubFileEntries() @property def type_indicator(self): - """str: type indicator.""" - # pylint: disable=no-member - return self.TYPE_INDICATOR + """Retrieves the type indicator. + + Returns: + str: type indicator. + """ + return getattr(self, 'TYPE_INDICATOR', None) def GetDataStream(self, name, case_sensitive=True): """Retrieves a data stream by name. diff --git a/dfvfs/volume/volume_system.py b/dfvfs/volume/volume_system.py index 3fa22aaa..6d9b98ef 100644 --- a/dfvfs/volume/volume_system.py +++ b/dfvfs/volume/volume_system.py @@ -80,7 +80,11 @@ def _Parse(self): @property def attributes(self): - """generator[VolumeAttribute]: volume attributes generator.""" + """Retrieves attributes. + + Returns: + generator[VolumeAttribute]: volume attributes generator. + """ if not self._is_parsed: self._Parse() self._is_parsed = True @@ -89,7 +93,11 @@ def attributes(self): @property def extents(self): - """list[VolumeExtent]: volume extents.""" + """Retrieves extents. + + Returns: + list[VolumeExtent]: volume extents. + """ if not self._is_parsed: self._Parse() self._is_parsed = True @@ -98,7 +106,11 @@ def extents(self): @property def number_of_attributes(self): - """int: number of attributes.""" + """Retrieves the number of attributes. + + Returns: + int: number of attributes. + """ if not self._is_parsed: self._Parse() self._is_parsed = True @@ -107,7 +119,11 @@ def number_of_attributes(self): @property def number_of_extents(self): - """int: number of extents.""" + """Retrieves the number of extents. + + Returns: + int: number of extents. + """ if not self._is_parsed: self._Parse() self._is_parsed = True @@ -181,7 +197,11 @@ def _Parse(self): @property def number_of_sections(self): - """int: number of sections.""" + """Retrieves the number of sections. + + Returns: + int: number of sections. + """ if not self._is_parsed: self._Parse() self._is_parsed = True @@ -190,7 +210,11 @@ def number_of_sections(self): @property def number_of_volumes(self): - """int: number of volumes.""" + """Retrieves the number of volumes. + + Returns: + int: number of volumes. + """ if not self._is_parsed: self._Parse() self._is_parsed = True @@ -199,7 +223,11 @@ def number_of_volumes(self): @property def sections(self): - """list[VolumeExtent]: sections.""" + """Retrieves sections. + + Returns: + list[VolumeExtent]: sections. + """ if not self._is_parsed: self._Parse() self._is_parsed = True @@ -208,7 +236,11 @@ def sections(self): @property def volume_identifiers(self): - """list[str]: volume identifiers.""" + """Retrieves volume identifiers. + + Returns: + list[str]: volume identifiers. + """ if not self._is_parsed: self._Parse() self._is_parsed = True @@ -217,7 +249,11 @@ def volume_identifiers(self): @property def volumes(self): - """generator(Volume): volumes generator.""" + """Retrieves volumes. + + Returns: + generator(Volume): volumes generator. + """ if not self._is_parsed: self._Parse() self._is_parsed = True diff --git a/docs/conf.py b/docs/conf.py index 5089f2f5..278872e8 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -52,6 +52,7 @@ # docstrings. napoleon_google_docstring = True napoleon_numpy_docstring = False +napoleon_include_init_with_doc = True napoleon_include_private_with_doc = False napoleon_include_special_with_doc = True diff --git a/pyproject.toml b/pyproject.toml index 9787c3bd..5a5671e2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,10 @@ [build-system] requires = ["setuptools", "wheel"] build-backend = "setuptools.build_meta" + +[tool.docformatter] +black = false +non-cap = ["dfDateTime", "dfImageTools", "dfVFS", "dfWinReg", "dtFabric"] +non-strict = false +wrap-summaries = 80 +wrap-descriptions = 80 diff --git a/setup.cfg b/setup.cfg index 25cc902a..869793ce 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = dfvfs -version = 20240115 +version = 20240128 description = Digital Forensics Virtual File System (dfVFS). long_description = dfVFS, or Digital Forensics Virtual File System, provides read-only access to file-system objects from various storage media types and file formats. The goal of dfVFS is to provide a generic interface for accessing file-system objects, for which it uses several back-ends that provide the actual implementation of the various storage media types, volume systems and file systems. long_description_content_type = text/plain diff --git a/tests/vfs/apfs_container_file_entry.py b/tests/vfs/apfs_container_file_entry.py index 7b7d1dad..dbab99c5 100644 --- a/tests/vfs/apfs_container_file_entry.py +++ b/tests/vfs/apfs_container_file_entry.py @@ -178,7 +178,7 @@ def testGetParentFileEntry(self): self.assertIsNone(parent_file_entry) def testIsFunctions(self): - """Test the Is? functions.""" + """Test the Is* functions.""" path_spec = path_spec_factory.Factory.NewPathSpec( definitions.TYPE_INDICATOR_APFS_CONTAINER, parent=self._raw_path_spec, volume_index=0) @@ -394,7 +394,7 @@ def testGetParentFileEntry(self): self.assertIsNone(parent_file_entry) def testIsFunctions(self): - """Test the Is? functions.""" + """Test the Is* functions.""" path_spec = path_spec_factory.Factory.NewPathSpec( definitions.TYPE_INDICATOR_APFS_CONTAINER, parent=self._gpt_path_spec, volume_index=0) diff --git a/tests/vfs/apfs_file_entry.py b/tests/vfs/apfs_file_entry.py index 186f6bf4..5f0b38cd 100644 --- a/tests/vfs/apfs_file_entry.py +++ b/tests/vfs/apfs_file_entry.py @@ -272,7 +272,7 @@ def testGetParentFileEntry(self): self.assertEqual(parent_file_entry.name, 'a_directory') def testIsFunctions(self): - """Tests the Is? functions.""" + """Tests the Is* functions.""" path_spec = path_spec_factory.Factory.NewPathSpec( definitions.TYPE_INDICATOR_APFS, identifier=self._IDENTIFIER_ANOTHER_FILE, @@ -615,7 +615,7 @@ def testGetParentFileEntry(self): self.assertEqual(parent_file_entry.name, 'a_directory') def testIsFunctions(self): - """Tests the Is? functions.""" + """Tests the Is* functions.""" path_spec = path_spec_factory.Factory.NewPathSpec( definitions.TYPE_INDICATOR_APFS, identifier=self._IDENTIFIER_ANOTHER_FILE, diff --git a/tests/vfs/apm_file_entry.py b/tests/vfs/apm_file_entry.py index bf347531..054ac67f 100644 --- a/tests/vfs/apm_file_entry.py +++ b/tests/vfs/apm_file_entry.py @@ -116,7 +116,7 @@ def testGetParentFileEntry(self): self.assertIsNone(parent_file_entry) def testIsFunctions(self): - """Test the Is? functions.""" + """Test the Is* functions.""" path_spec = path_spec_factory.Factory.NewPathSpec( definitions.TYPE_INDICATOR_APM, entry_index=0, parent=self._raw_path_spec) diff --git a/tests/vfs/compressed_stream_file_entry.py b/tests/vfs/compressed_stream_file_entry.py index d4557085..0f6a3ec2 100644 --- a/tests/vfs/compressed_stream_file_entry.py +++ b/tests/vfs/compressed_stream_file_entry.py @@ -69,7 +69,7 @@ def testGetParentFileEntry(self): self.assertIsNone(parent_file_entry) def testIsFunctions(self): - """Test the Is? functions.""" + """Test the Is* functions.""" file_entry = self._file_system.GetFileEntryByPathSpec( self._compressed_stream_path_spec) self.assertIsNotNone(file_entry) diff --git a/tests/vfs/cpio_file_entry.py b/tests/vfs/cpio_file_entry.py index 5fdabf18..50076cd4 100644 --- a/tests/vfs/cpio_file_entry.py +++ b/tests/vfs/cpio_file_entry.py @@ -123,7 +123,7 @@ def testGetParentFileEntry(self): self.assertEqual(parent_file_entry.name, '') def testIsFunctions(self): - """Test the Is? functions.""" + """Test the Is* functions.""" path_spec = path_spec_factory.Factory.NewPathSpec( definitions.TYPE_INDICATOR_CPIO, location='/syslog', parent=self._os_path_spec) diff --git a/tests/vfs/cs_file_entry.py b/tests/vfs/cs_file_entry.py index 9c622929..0690cd58 100644 --- a/tests/vfs/cs_file_entry.py +++ b/tests/vfs/cs_file_entry.py @@ -187,7 +187,7 @@ def testGetParentFileEntry(self): self.assertIsNone(parent_file_entry) def testIsFunctions(self): - """Test the Is? functions.""" + """Test the Is* functions.""" path_spec = path_spec_factory.Factory.NewPathSpec( definitions.TYPE_INDICATOR_CS, parent=self._gpt_path_spec, volume_index=0) diff --git a/tests/vfs/data_range_file_entry.py b/tests/vfs/data_range_file_entry.py index 51f6d66b..77ca2ce7 100644 --- a/tests/vfs/data_range_file_entry.py +++ b/tests/vfs/data_range_file_entry.py @@ -68,7 +68,7 @@ def testGetParentFileEntry(self): self.assertIsNone(parent_file_entry) def testIsFunctions(self): - """Test the Is? functions.""" + """Test the Is* functions.""" file_entry = self._file_system.GetFileEntryByPathSpec( self._data_range_path_spec) self.assertIsNotNone(file_entry) diff --git a/tests/vfs/encoded_stream_file_entry.py b/tests/vfs/encoded_stream_file_entry.py index 3bcb0f7e..bdf61773 100644 --- a/tests/vfs/encoded_stream_file_entry.py +++ b/tests/vfs/encoded_stream_file_entry.py @@ -69,7 +69,7 @@ def testGetParentFileEntry(self): self.assertIsNone(parent_file_entry) def testIsFunctions(self): - """Test the Is? functions.""" + """Test the Is* functions.""" file_entry = self._file_system.GetFileEntryByPathSpec( self._encoded_stream_path_spec) self.assertIsNotNone(file_entry) diff --git a/tests/vfs/encrypted_stream_file_entry.py b/tests/vfs/encrypted_stream_file_entry.py index c7e97b9d..c7689fa9 100644 --- a/tests/vfs/encrypted_stream_file_entry.py +++ b/tests/vfs/encrypted_stream_file_entry.py @@ -79,7 +79,7 @@ def testGetParentFileEntry(self): self.assertIsNone(parent_file_entry) def testIsFunctions(self): - """Test the Is? functions.""" + """Test the Is* functions.""" file_entry = self._file_system.GetFileEntryByPathSpec( self._encrypted_stream_path_spec) self.assertIsNotNone(file_entry) diff --git a/tests/vfs/ext_file_entry.py b/tests/vfs/ext_file_entry.py index 421135f3..a88f7768 100644 --- a/tests/vfs/ext_file_entry.py +++ b/tests/vfs/ext_file_entry.py @@ -196,7 +196,7 @@ def testGetParentFileEntry(self): self.assertEqual(parent_file_entry.name, 'a_directory') def testIsFunctions(self): - """Tests the Is? functions.""" + """Tests the Is* functions.""" path_spec = path_spec_factory.Factory.NewPathSpec( definitions.TYPE_INDICATOR_EXT, inode=self._INODE_ANOTHER_FILE, location='/a_directory/another_file', parent=self._raw_path_spec) @@ -474,7 +474,7 @@ def testGetParentFileEntry(self): self.assertEqual(parent_file_entry.name, 'a_directory') def testIsFunctions(self): - """Tests the Is? functions.""" + """Tests the Is* functions.""" path_spec = path_spec_factory.Factory.NewPathSpec( definitions.TYPE_INDICATOR_EXT, inode=self._INODE_ANOTHER_FILE, location='/a_directory/another_file', parent=self._raw_path_spec) diff --git a/tests/vfs/fake_file_entry.py b/tests/vfs/fake_file_entry.py index 69260dcf..a85e0da7 100644 --- a/tests/vfs/fake_file_entry.py +++ b/tests/vfs/fake_file_entry.py @@ -153,7 +153,7 @@ def testGetParentFileEntry(self): self.assertEqual(parent_file_entry.name, 'testdir_fake') def testIsFunctions(self): - """Test the Is? functions.""" + """Test the Is* functions.""" test_file = '/test_data/testdir_fake/file1.txt' path_spec = fake_path_spec.FakePathSpec(location=test_file) file_entry = self._file_system.GetFileEntryByPathSpec(path_spec) diff --git a/tests/vfs/fat_file_entry.py b/tests/vfs/fat_file_entry.py index 22927260..56a410aa 100644 --- a/tests/vfs/fat_file_entry.py +++ b/tests/vfs/fat_file_entry.py @@ -289,7 +289,7 @@ def testGetParentFileEntry(self): self.assertEqual(parent_file_entry.name, 'a_directory') def testIsFunctions(self): - """Tests the Is? functions.""" + """Tests the Is* functions.""" path_spec = path_spec_factory.Factory.NewPathSpec( definitions.TYPE_INDICATOR_FAT, identifier=self._IDENTIFIER_ANOTHER_FILE, diff --git a/tests/vfs/gpt_file_entry.py b/tests/vfs/gpt_file_entry.py index 0ae7f347..81f4eb00 100644 --- a/tests/vfs/gpt_file_entry.py +++ b/tests/vfs/gpt_file_entry.py @@ -113,7 +113,7 @@ def testGetParentFileEntry(self): self.assertIsNone(parent_file_entry) def testIsFunctions(self): - """Test the Is? functions.""" + """Test the Is* functions.""" path_spec = path_spec_factory.Factory.NewPathSpec( definitions.TYPE_INDICATOR_GPT, entry_index=0, parent=self._raw_path_spec) diff --git a/tests/vfs/gzip_file_entry.py b/tests/vfs/gzip_file_entry.py index bd849093..4a0556ea 100644 --- a/tests/vfs/gzip_file_entry.py +++ b/tests/vfs/gzip_file_entry.py @@ -74,7 +74,7 @@ def testGetParentFileEntry(self): self.assertIsNone(parent_file_entry) def testIsFunctions(self): - """Test the Is? functions.""" + """Test the Is* functions.""" file_entry = self._file_system.GetFileEntryByPathSpec(self._gzip_path_spec) self.assertIsNotNone(file_entry) diff --git a/tests/vfs/hfs_file_entry.py b/tests/vfs/hfs_file_entry.py index a2dfa40c..e660ea3f 100644 --- a/tests/vfs/hfs_file_entry.py +++ b/tests/vfs/hfs_file_entry.py @@ -398,7 +398,7 @@ def testGetParentFileEntry(self): self.assertEqual(parent_file_entry.name, 'a_directory') def testIsFunctions(self): - """Tests the Is? functions.""" + """Tests the Is* functions.""" path_spec = path_spec_factory.Factory.NewPathSpec( definitions.TYPE_INDICATOR_HFS, identifier=self._IDENTIFIER_ANOTHER_FILE, diff --git a/tests/vfs/luksde_file_entry.py b/tests/vfs/luksde_file_entry.py index e1543f0e..3ebb92e4 100644 --- a/tests/vfs/luksde_file_entry.py +++ b/tests/vfs/luksde_file_entry.py @@ -117,7 +117,7 @@ def testGetParentFileEntry(self): self.assertIsNone(parent_file_entry) def testIsFunctions(self): - """Test the Is? functions.""" + """Test the Is* functions.""" file_entry = self._file_system.GetFileEntryByPathSpec( self._luksde_path_spec) self.assertIsNotNone(file_entry) diff --git a/tests/vfs/lvm_file_entry.py b/tests/vfs/lvm_file_entry.py index fc21c83d..3f2992dc 100644 --- a/tests/vfs/lvm_file_entry.py +++ b/tests/vfs/lvm_file_entry.py @@ -189,7 +189,7 @@ def testGetParentFileEntry(self): self.assertIsNone(parent_file_entry) def testIsFunctions(self): - """Test the Is? functions.""" + """Test the Is* functions.""" path_spec = path_spec_factory.Factory.NewPathSpec( definitions.TYPE_INDICATOR_LVM, parent=self._raw_path_spec, volume_index=0) diff --git a/tests/vfs/os_file_entry.py b/tests/vfs/os_file_entry.py index 775c0b0b..cff6e19f 100644 --- a/tests/vfs/os_file_entry.py +++ b/tests/vfs/os_file_entry.py @@ -166,7 +166,7 @@ def testGetParentFileEntry(self): self.assertEqual(parent_file_entry.name, 'testdir_os') def testIsFunctions(self): - """Test the Is? functions.""" + """Test the Is* functions.""" test_path = self._GetTestFilePath(['testdir_os', 'file1.txt']) self._SkipIfPathNotExists(test_path) diff --git a/tests/vfs/os_file_system.py b/tests/vfs/os_file_system.py index 8b066197..047295a1 100644 --- a/tests/vfs/os_file_system.py +++ b/tests/vfs/os_file_system.py @@ -15,7 +15,7 @@ def TestPlatformSystem(): - """Test function to emulate platform.system() == 'Windows'""" + """Test function to emulate platform.system() == 'Windows'.""" return 'Windows' diff --git a/tests/vfs/sqlite_blob_file_entry.py b/tests/vfs/sqlite_blob_file_entry.py index 1e14d081..174d46cb 100644 --- a/tests/vfs/sqlite_blob_file_entry.py +++ b/tests/vfs/sqlite_blob_file_entry.py @@ -115,7 +115,7 @@ def testGetParentFileEntry(self): self.assertEqual(parent_file_entry.name, 'myblobs.blobs') def testIsFunctions(self): - """Test the Is? functions.""" + """Test the Is* functions.""" file_entry = self._file_system.GetFileEntryByPathSpec( self._sqlite_blob_path_spec) diff --git a/tests/vfs/tar_file_entry.py b/tests/vfs/tar_file_entry.py index 260c7819..59787044 100644 --- a/tests/vfs/tar_file_entry.py +++ b/tests/vfs/tar_file_entry.py @@ -106,7 +106,7 @@ def testGetParentFileEntry(self): # TODO: add tests for GetTARInfo def testIsFunctions(self): - """Test the Is? functions.""" + """Test the Is* functions.""" path_spec = path_spec_factory.Factory.NewPathSpec( definitions.TYPE_INDICATOR_TAR, location='/syslog', parent=self._os_path_spec) diff --git a/tests/vfs/tsk_file_entry.py b/tests/vfs/tsk_file_entry.py index ef03a4a4..ebd79bc7 100644 --- a/tests/vfs/tsk_file_entry.py +++ b/tests/vfs/tsk_file_entry.py @@ -400,7 +400,7 @@ def testGetParentFileEntry(self): # TODO: add tests for GetTSKFile def testIsFunctions(self): - """Tests the Is? functions.""" + """Tests the Is* functions.""" path_spec = path_spec_factory.Factory.NewPathSpec( definitions.TYPE_INDICATOR_TSK, inode=self._INODE_ANOTHER_FILE, location='/a_directory/another_file', parent=self._raw_path_spec) @@ -754,7 +754,7 @@ def testGetParentFileEntry(self): # TODO: add tests for GetTSKFile def testIsFunctions(self): - """Tests the Is? functions.""" + """Tests the Is* functions.""" path_spec = path_spec_factory.Factory.NewPathSpec( definitions.TYPE_INDICATOR_TSK, inode=self._INODE_ANOTHER_FILE, location='/a_directory/another_file', parent=self._raw_path_spec) @@ -1172,7 +1172,7 @@ def testGetParentFileEntry(self): # TODO: add tests for GetTSKFile def testIsFunctions(self): - """Tests the Is? functions.""" + """Tests the Is* functions.""" path_spec = path_spec_factory.Factory.NewPathSpec( definitions.TYPE_INDICATOR_TSK, inode=self._INODE_ANOTHER_FILE, location='/a_directory/another_file', parent=self._raw_path_spec) @@ -1583,7 +1583,7 @@ def testGetParentFileEntry(self): # TODO: add tests for GetTSKFile def testIsFunctions(self): - """Tests the Is? functions.""" + """Tests the Is* functions.""" path_spec = path_spec_factory.Factory.NewPathSpec( definitions.TYPE_INDICATOR_TSK, inode=self._INODE_ANOTHER_FILE, location='/A_DIRECTORY/ANOTHER_FILE', parent=self.test_os_path_spec) @@ -2295,7 +2295,7 @@ def testGetParentFileEntry(self): # TODO: add tests for GetTSKFile def testIsFunctions(self): - """Tests the Is? functions.""" + """Tests the Is* functions.""" path_spec = path_spec_factory.Factory.NewPathSpec( definitions.TYPE_INDICATOR_TSK, inode=self._INODE_ANOTHER_FILE, location='/a_directory/another_file', diff --git a/tests/vfs/tsk_partition_file_entry.py b/tests/vfs/tsk_partition_file_entry.py index 2398aab8..d16ca25f 100644 --- a/tests/vfs/tsk_partition_file_entry.py +++ b/tests/vfs/tsk_partition_file_entry.py @@ -102,7 +102,7 @@ def testGetTSKVsPart(self): self.assertIsNotNone(tsk_vs_part) def testIsFunctions(self): - """Test the Is? functions.""" + """Test the Is* functions.""" path_spec = path_spec_factory.Factory.NewPathSpec( definitions.TYPE_INDICATOR_TSK_PARTITION, part_index=0, parent=self._os_path_spec) @@ -292,7 +292,7 @@ def testGetTSKVsPart(self): self.assertIsNotNone(tsk_vs_part) def testIsFunctions(self): - """Test the Is? functions.""" + """Test the Is* functions.""" path_spec = path_spec_factory.Factory.NewPathSpec( definitions.TYPE_INDICATOR_TSK_PARTITION, part_index=2, parent=self._os_path_spec) @@ -487,7 +487,7 @@ def testGetTSKVsPart(self): self.assertIsNotNone(tsk_vs_part) def testIsFunctions(self): - """Test the Is? functions.""" + """Test the Is* functions.""" path_spec = path_spec_factory.Factory.NewPathSpec( definitions.TYPE_INDICATOR_TSK_PARTITION, part_index=1, parent=self._os_path_spec) diff --git a/tests/vfs/vshadow_file_entry.py b/tests/vfs/vshadow_file_entry.py index 217c5844..63db4b95 100644 --- a/tests/vfs/vshadow_file_entry.py +++ b/tests/vfs/vshadow_file_entry.py @@ -125,7 +125,7 @@ def testGetParentFileEntry(self): # TODO: add tests for HasExternalData def testIsFunctions(self): - """Test the Is? functions.""" + """Test the Is* functions.""" path_spec = path_spec_factory.Factory.NewPathSpec( definitions.TYPE_INDICATOR_VSHADOW, parent=self._raw_path_spec, store_index=1) diff --git a/tests/vfs/xfs_file_entry.py b/tests/vfs/xfs_file_entry.py index eac933bd..af776fb6 100644 --- a/tests/vfs/xfs_file_entry.py +++ b/tests/vfs/xfs_file_entry.py @@ -206,7 +206,7 @@ def testGetParentFileEntry(self): self.assertEqual(parent_file_entry.name, 'a_directory') def testIsFunctions(self): - """Tests the Is? functions.""" + """Tests the Is* functions.""" path_spec = path_spec_factory.Factory.NewPathSpec( definitions.TYPE_INDICATOR_XFS, inode=self._INODE_ANOTHER_FILE, location='/a_directory/another_file', parent=self._raw_path_spec) diff --git a/tox.ini b/tox.ini index 5d243ce5..4db297f6 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py3{7,8,9,10,11,12},coverage,docs,lint,wheel +envlist = py3{7,8,9,10,11,12},coverage,docformatter,docs,lint,wheel [testenv] allowlist_externals = ./run_tests.py @@ -25,6 +25,13 @@ commands = coverage: coverage xml wheel: python -m build --no-isolation --wheel +[testenv:docformatter] +usedevelop = True +deps = + docformatter +commands = + docformatter --in-place --recursive dfvfs tests + [testenv:docs] usedevelop = True deps = @@ -45,10 +52,14 @@ setenv = deps = -rrequirements.txt -rtest_requirements.txt + docformatter pylint >= 3.0.0, < 3.1.0 + setuptools yamllint >= 1.26.0 commands = + docformatter --version pylint --version yamllint -v + docformatter --check --diff --recursive dfvfs setup.py tests pylint --rcfile=.pylintrc dfvfs setup.py tests yamllint -c .yamllint.yaml dfvfs diff --git a/utils/update_release.sh b/utils/update_release.sh index ac492e91..c89acc5c 100755 --- a/utils/update_release.sh +++ b/utils/update_release.sh @@ -29,7 +29,7 @@ EOT # PYTHONPATH=. ./utils/export_supported_formats.py > docs/sources/Supported-formats.md # Regenerate the API documentation. -tox -edocs +tox -edocformatter,docs exit ${EXIT_SUCCESS};