Skip to content

Commit

Permalink
Fix typehints and docstrings (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
Schamper committed Jul 11, 2023
1 parent e83e1d0 commit edb0e2d
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 117 deletions.
66 changes: 33 additions & 33 deletions dissect/ntfs/attr.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import io
from datetime import datetime
from typing import TYPE_CHECKING, Any, BinaryIO, Iterator, List, Optional, Tuple
from typing import TYPE_CHECKING, Any, BinaryIO, Iterator, Optional

from dissect.util.stream import RangeStream, RunlistStream
from dissect.util.ts import wintimestamp
Expand All @@ -24,7 +24,7 @@
class Attribute:
"""Parse and interact with MFT attributes.
Wrapper for an AttributeHeader and AttributeRecord combination.
Wrapper for an :class:`AttributeHeader` and :class:`AttributeRecord` combination.
Args:
record: The MFT record this attribute belongs to.
Expand Down Expand Up @@ -86,7 +86,7 @@ def name(self) -> str:
"""Return the name of this attribute."""
return self.header.name

def dataruns(self) -> List[Tuple[int, int]]:
def dataruns(self) -> list[tuple[int, int]]:
"""Return the dataruns of this attribute, if non-resident.
Raises:
Expand Down Expand Up @@ -194,7 +194,7 @@ def compression_unit(self) -> Optional[int]:
"""Return the compression unit if non-resident, else None."""
return self.header.Form.Nonresident.CompressionUnit if not self.resident else None

def dataruns(self) -> List[Tuple[int, int]]:
def dataruns(self) -> list[tuple[int, int]]:
"""Return the dataruns of this attribute, if non-resident.
Raises:
Expand Down Expand Up @@ -281,7 +281,7 @@ def from_fh(
) -> AttributeRecord:
"""Parse an attribute from a file-like object.
Selects a more specific AttributeRecord class if one is available for the given attribute type.
Selects a more specific :class:`AttributeRecord` class if one is available for the given attribute type.
Args:
fh: The file-like object to parse an attribute from.
Expand All @@ -292,7 +292,7 @@ def from_fh(


class AttributeList(AttributeRecord):
"""Specific AttributeRecord parser for $ATTRIBUTE_LIST."""
"""Specific :class:`AttributeRecord` parser for ``$ATTRIBUTE_LIST``."""

__slots__ = ("entries",)

Expand Down Expand Up @@ -320,7 +320,7 @@ def __repr__(self) -> str:
return "<$ATTRIBUTE_LIST>"

def attributes(self) -> Iterator[Attribute]:
"""Iterate all entries within this $ATTRIBUTE_LIST and yield all embedded attributes."""
"""Iterate all entries within this ``$ATTRIBUTE_LIST`` and yield all embedded attributes."""
if not self.record:
raise MftNotAvailableError("Can't iterate $ATTRIBUTE_LIST attributes without a bounded MFT record")

Expand All @@ -339,7 +339,7 @@ def attributes(self) -> Iterator[Attribute]:


class StandardInformation(AttributeRecord):
"""Specific AttributeRecord parser for $STANDARD_INFORMATION."""
"""Specific :class:`AttributeRecord` parser for ``$STANDARD_INFORMATION``."""

__slots__ = ("attr",)

Expand All @@ -354,62 +354,62 @@ def __repr__(self) -> str:

@property
def creation_time(self) -> datetime:
"""Return the $STANDARD_INFORMATION CreationTime."""
"""Return the ``$STANDARD_INFORMATION`` ``CreationTime``."""
return wintimestamp(self.attr.CreationTime)

@property
def creation_time_ns(self) -> int:
"""Return the $STANDARD_INFORMATION CreationTime in nanoseconds."""
"""Return the ``$STANDARD_INFORMATION`` ``CreationTime`` in nanoseconds."""
return ts_to_ns(self.attr.CreationTime)

@property
def last_modification_time(self) -> datetime:
"""Return the $STANDARD_INFORMATION LastModificationTime."""
"""Return the ``$STANDARD_INFORMATION`` ``LastModificationTime``."""
return wintimestamp(self.attr.LastModificationTime)

@property
def last_modification_time_ns(self) -> int:
"""Return the $STANDARD_INFORMATION LastModificationTime in nanoseconds."""
"""Return the ``$STANDARD_INFORMATION`` ``LastModificationTime`` in nanoseconds."""
return ts_to_ns(self.attr.LastModificationTime)

@property
def last_change_time(self) -> datetime:
"""Return the $STANDARD_INFORMATION LastChangeTime."""
"""Return the ``$STANDARD_INFORMATION`` ``LastChangeTime``."""
return wintimestamp(self.attr.LastChangeTime)

@property
def last_change_time_ns(self) -> int:
"""Return the $STANDARD_INFORMATION LastChangeTime in nanoseconds."""
"""Return the ``$STANDARD_INFORMATION`` ``LastChangeTime`` in nanoseconds."""
return ts_to_ns(self.attr.LastChangeTime)

@property
def last_access_time(self) -> datetime:
"""Return the $STANDARD_INFORMATION LastAccessTime."""
"""Return the ``$STANDARD_INFORMATION`` ``LastAccessTime``."""
return wintimestamp(self.attr.LastAccessTime)

@property
def last_access_time_ns(self) -> int:
"""Return the $STANDARD_INFORMATION LastAccessTime in nanoseconds."""
"""Return the ``$STANDARD_INFORMATION`` ``LastAccessTime`` in nanoseconds."""
return ts_to_ns(self.attr.LastAccessTime)

@property
def file_attributes(self) -> int:
"""Return the $STANDARD_INFORMATION FileAttributes."""
"""Return the ``$STANDARD_INFORMATION`` ``FileAttributes``."""
return self.attr.FileAttributes

@property
def owner_id(self) -> int:
"""Return the $STANDARD_INFORMATION OwnerId."""
"""Return the ``$STANDARD_INFORMATION`` ``OwnerId``."""
return self.attr.OwnerId

@property
def security_id(self) -> int:
"""Return the $STANDARD_INFORMATION SecurityId."""
"""Return the ``$STANDARD_INFORMATION`` ``SecurityId``."""
return self.attr.SecurityId


class FileName(AttributeRecord):
"""Specific AttributeRecord parser for $FILE_NAME."""
"""Specific :class:`AttributeRecord` parser for ``$FILE_NAME``."""

__slots__ = ("attr",)

Expand All @@ -423,62 +423,62 @@ def __repr__(self) -> str:

@property
def creation_time(self) -> datetime:
"""Return the $FILE_NAME file CreationTime."""
"""Return the ``$FILE_NAME``file ``CreationTime``."""
return wintimestamp(self.attr.CreationTime)

@property
def creation_time_ns(self) -> int:
"""Return the $FILE_NAME file CreationTime in nanoseconds."""
"""Return the ``$FILE_NAME`` file ``CreationTime`` in nanoseconds."""
return ts_to_ns(self.attr.CreationTime)

@property
def last_modification_time(self) -> datetime:
"""Return the $FILE_NAME file LastModificationTime."""
"""Return the ``$FILE_NAME`` file ``LastModificationTime``."""
return wintimestamp(self.attr.LastModificationTime)

@property
def last_modification_time_ns(self) -> int:
"""Return the $FILE_NAME file LastModificationTime in nanoseconds."""
"""Return the ``$FILE_NAME`` file ``LastModificationTime`` in nanoseconds."""
return ts_to_ns(self.attr.LastModificationTime)

@property
def last_change_time(self) -> datetime:
"""Return the $FILE_NAME file LastChangeTime."""
"""Return the ``$FILE_NAME`` file ``LastChangeTime``."""
return wintimestamp(self.attr.LastChangeTime)

@property
def last_change_time_ns(self) -> int:
"""Return the $FILE_NAME file LastChangeTime in nanoseconds."""
"""Return the ``$FILE_NAME`` file ``LastChangeTime`` in nanoseconds."""
return ts_to_ns(self.attr.LastChangeTime)

@property
def last_access_time(self) -> datetime:
"""Return the $FILE_NAME file LastAccessTime."""
"""Return the ``$FILE_NAME`` file ``LastAccessTime``."""
return wintimestamp(self.attr.LastAccessTime)

@property
def last_access_time_ns(self) -> int:
"""Return the $FILE_NAME file LastAccessTime in nanoseconds."""
"""Return the ``$FILE_NAME`` file ``LastAccessTime`` in nanoseconds."""
return ts_to_ns(self.attr.LastAccessTime)

@property
def file_size(self) -> int:
"""Return the $FILE_NAME file FileSize."""
"""Return the ``$FILE_NAME`` file ``FileSize``."""
return self.attr.FileSize

@property
def file_attributes(self) -> int:
"""Return the $FILE_NAME file FileAttributes."""
"""Return the ``$FILE_NAME`` file ``FileAttributes``."""
return self.attr.FileAttributes

@property
def flags(self) -> int:
"""Return the $FILE_NAME flags, which can be either FILE_NAME_NTFS or FILE_NAME_DOS."""
"""Return the ``$FILE_NAME`` flags, which can be either ``FILE_NAME_NTFS`` or ``FILE_NAME_DOS``."""
return self.attr.Flags

@property
def file_name(self) -> str:
"""Return the file name string stored in this $FILE_NAME attribute."""
"""Return the file name string stored in this ``$FILE_NAME`` attribute."""
return self.attr.FileName

def full_path(self) -> str:
Expand All @@ -487,7 +487,7 @@ def full_path(self) -> str:


class ReparsePoint(AttributeRecord):
"""Specific AttributeRecord parser for $REPARSE_POINT."""
"""Specific :class:`AttributeRecord` parser for ``$REPARSE_POINT``."""

__slots__ = ("attr", "tag_header", "buffer")

Expand Down
28 changes: 14 additions & 14 deletions dissect/ntfs/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import io
from enum import Enum, auto
from functools import cached_property, lru_cache
from typing import TYPE_CHECKING, Any, BinaryIO, Callable, Iterator, List, Optional
from typing import TYPE_CHECKING, Any, BinaryIO, Callable, Iterator, Optional

from dissect.ntfs.attr import AttributeRecord
from dissect.ntfs.c_ntfs import (
Expand Down Expand Up @@ -64,7 +64,7 @@ def __iter__(self) -> Iterator[IndexEntry]:

@lru_cache(128)
def index_buffer(self, vcn: int) -> IndexBuffer:
"""Return the IndexBuffer at the specified cluster number.
"""Return the :class:`IndexBuffer` at the specified cluster number.
Args:
vcn: The virtual cluster number within the index allocation to read.
Expand Down Expand Up @@ -122,7 +122,7 @@ def search(
return entry

def entries(self) -> Iterator[IndexEntry]:
"""Yield all IndexEntry's in this Index."""
"""Yield all :class:`IndexEntry`'s in this :class:`Index`."""

for entry in self.root.entries():
if entry.is_end:
Expand All @@ -148,10 +148,10 @@ def entries(self) -> Iterator[IndexEntry]:


class IndexRoot:
"""Represents the $INDEX_ROOT.
"""Represents the ``$INDEX_ROOT``.
Args:
index: The Index class instance this IndexRoot belongs to.
index: The :class:`Index`` class instance this :class:`IndexRoot` belongs to.
fh: The file-like object to parse an index root on.
"""

Expand Down Expand Up @@ -182,7 +182,7 @@ def clusters_per_index_buffer(self) -> int:
return self.header.ClustersPerIndexBuffer

def entries(self) -> Iterator[IndexEntry]:
"""Yield all IndexEntry's in this IndexRoot."""
"""Yield all :class:`IndexEntry`'s in this :class:`IndexRoot`."""
yield from _iter_entries(
self.index,
self.fh,
Expand All @@ -193,11 +193,11 @@ def entries(self) -> Iterator[IndexEntry]:


class IndexBuffer:
"""Represent an index buffer in $INDEX_ALLOCATION.
"""Represent an index buffer in ``$INDEX_ALLOCATION``.
Args:
index: The Index class instance this IndexRoot belongs to.
fh: The file-like object of $INDEX_ALLOCATION.
index: The :class:`Index` class instance this :class:`IndexRoot` belongs to.
fh: The file-like object of ``$INDEX_ALLOCATION``.
offset: The offset in bytes to the index buffer on the file-like object we want to read.
size: The size of the index buffer in bytes.
Expand All @@ -224,7 +224,7 @@ def __init__(self, index: Index, fh: BinaryIO, offset: int, size: int):
self.header = c_ntfs._INDEX_ALLOCATION_BUFFER(self.data)

def entries(self) -> Iterator[IndexEntry]:
"""Yield all IndexEntry's in this IndexBuffer."""
"""Yield all :class:`IndexEntry`'s in this :class:`IndexBuffer`."""
yield from _iter_entries(
self.index,
io.BytesIO(self.data),
Expand All @@ -238,7 +238,7 @@ class IndexEntry:
"""Parse and interact with index entries.
Args:
index: The Index class instance this IndexEntry belongs to.
index: The :class:`Index` class instance this :class:`IndexEntry` belongs to.
fh: The file-like object to parse an index entry on.
offset: The offset in the file-like object to parse an index entry at.
"""
Expand All @@ -253,7 +253,7 @@ def __init__(self, index: Index, fh: BinaryIO, offset: int):
self.buf = fh.read(self.header.Length - len(c_ntfs._INDEX_ENTRY))

def dereference(self) -> MftRecord:
"""Dereference this IndexEntry to the MFT record it points to.
"""Dereference this :class:`IndexEntry` to the MFT record it points to.
Note that the file reference is a union with the data part so only access this if you know the entry has
a file reference and not a data part.
Expand Down Expand Up @@ -284,7 +284,7 @@ def data(self) -> bytes:

@cached_property
def attribute(self) -> Optional[AttributeRecord]:
"""Return the AttributeRecord of the attribute contained in this entry."""
"""Return the :class:`dissect.ntfs.attr.AttributeRecord` of the attribute contained in this entry."""
if self.key_length and self.index.root.attribute_type:
return AttributeRecord.from_fh(
io.BytesIO(self.buf),
Expand Down Expand Up @@ -337,7 +337,7 @@ def _iter_entries(index: Index, fh: BinaryIO, offset: int, size: int) -> Iterato
offset += entry.length


def _bsearch(entries: List[IndexEntry], value: Any, cmp: Callable[[IndexEntry, Any], Match]) -> IndexEntry:
def _bsearch(entries: list[IndexEntry], value: Any, cmp: Callable[[IndexEntry, Any], Match]) -> IndexEntry:
min_idx = 0
max_idx = len(entries) - 1

Expand Down
Loading

0 comments on commit edb0e2d

Please sign in to comment.