Change attribute type annotations to standard format

Previously, the types of instance attributes were annotated with the
first assignment of each attribute. The standard way to annotate
instance attributes is to do so at class level without assigning any
value.
This commit is contained in:
dgelessus 2019-09-29 14:58:18 +02:00
parent 9ef084de58
commit 97c459bca7
2 changed files with 59 additions and 30 deletions

View File

@ -98,16 +98,24 @@ class Resource(object):
__slots__ = ("type", "id", "name", "attributes", "data_raw", "_compressed_info", "_data_decompressed") __slots__ = ("type", "id", "name", "attributes", "data_raw", "_compressed_info", "_data_decompressed")
type: bytes
id: int
name: typing.Optional[bytes]
attributes: ResourceAttrs
data_raw: bytes
_compressed_info: compress.common.CompressedHeaderInfo
_data_decompressed: bytes
def __init__(self, resource_type: bytes, resource_id: int, name: typing.Optional[bytes], attributes: ResourceAttrs, data_raw: bytes): def __init__(self, resource_type: bytes, resource_id: int, name: typing.Optional[bytes], attributes: ResourceAttrs, data_raw: bytes):
"""Create a new resource with the given type code, ID, name, attributes, and data.""" """Create a new resource with the given type code, ID, name, attributes, and data."""
super().__init__() super().__init__()
self.type: bytes = resource_type self.type = resource_type
self.id: int = resource_id self.id = resource_id
self.name: typing.Optional[bytes] = name self.name = name
self.attributes: ResourceAttrs = attributes self.attributes = attributes
self.data_raw: bytes = data_raw self.data_raw = data_raw
def __repr__(self): def __repr__(self):
try: try:
@ -198,14 +206,18 @@ class ResourceFile(collections.abc.Mapping):
class _LazyResourceMap(collections.abc.Mapping): class _LazyResourceMap(collections.abc.Mapping):
"""Internal class: Lazy mapping of resource IDs to resource objects, returned when subscripting a ResourceFile.""" """Internal class: Lazy mapping of resource IDs to resource objects, returned when subscripting a ResourceFile."""
_resfile: "ResourceFile"
_restype: bytes
_submap: typing.Mapping[int, typing.Tuple[int, ResourceAttrs, int]]
def __init__(self, resfile: "ResourceFile", restype: bytes): def __init__(self, resfile: "ResourceFile", restype: bytes):
"""Create a new _LazyResourceMap "containing" all resources in resfile that have the type code restype.""" """Create a new _LazyResourceMap "containing" all resources in resfile that have the type code restype."""
super().__init__() super().__init__()
self._resfile: "ResourceFile" = resfile self._resfile = resfile
self._restype: bytes = restype self._restype = restype
self._submap: typing.Mapping[int, typing.Tuple[int, ResourceAttrs, int]] = self._resfile._references[self._restype] self._submap = self._resfile._references[self._restype]
def __len__(self): def __len__(self):
"""Get the number of resources with this type code.""" """Get the number of resources with this type code."""
@ -246,6 +258,23 @@ class ResourceFile(collections.abc.Mapping):
else: else:
return f"<{type(self).__module__}.{type(self).__qualname__} at {id(self):#x} containing {len(self)} resources with IDs: {list(self)}>" return f"<{type(self).__module__}.{type(self).__qualname__} at {id(self):#x} containing {len(self)} resources with IDs: {list(self)}>"
_close_stream: bool
_stream: typing.BinaryIO
data_offset: int
map_offset: int
data_length: int
map_length: int
header_system_data: bytes
header_application_data: bytes
map_type_list_offset: int
map_name_list_offset: int
file_attributes: ResourceFileAttrs
_reference_counts: typing.MutableMapping[bytes, int]
_references: typing.MutableMapping[bytes, typing.MutableMapping[int, typing.Tuple[int, ResourceAttrs, int]]]
@classmethod @classmethod
def open(cls, filename: typing.Union[str, bytes, os.PathLike], *, fork: str="auto", **kwargs) -> "ResourceFile": def open(cls, filename: typing.Union[str, bytes, os.PathLike], *, fork: str="auto", **kwargs) -> "ResourceFile":
"""Open the file at the given path as a ResourceFile. """Open the file at the given path as a ResourceFile.
@ -320,8 +349,7 @@ class ResourceFile(collections.abc.Mapping):
super().__init__() super().__init__()
self._close_stream: bool = close self._close_stream = close
self._stream: typing.BinaryIO
if stream.seekable(): if stream.seekable():
self._stream = stream self._stream = stream
else: else:
@ -358,12 +386,6 @@ class ResourceFile(collections.abc.Mapping):
assert self._stream.tell() == 0 assert self._stream.tell() == 0
self.data_offset: int
self.map_offset: int
self.data_length: int
self.map_length: int
self.header_system_data: bytes
self.header_application_data: bytes
( (
self.data_offset, self.data_offset,
self.map_offset, self.map_offset,
@ -381,20 +403,18 @@ class ResourceFile(collections.abc.Mapping):
assert self._stream.tell() == self.map_offset assert self._stream.tell() == self.map_offset
self.map_type_list_offset: int
self.map_name_list_offset: int
( (
_file_attributes, _file_attributes,
self.map_type_list_offset, self.map_type_list_offset,
self.map_name_list_offset, self.map_name_list_offset,
) = self._stream_unpack(STRUCT_RESOURCE_MAP_HEADER) ) = self._stream_unpack(STRUCT_RESOURCE_MAP_HEADER)
self.file_attributes: ResourceFileAttrs = ResourceFileAttrs(_file_attributes) self.file_attributes = ResourceFileAttrs(_file_attributes)
def _read_all_resource_types(self): def _read_all_resource_types(self):
"""Read all resource types, starting at the current stream position.""" """Read all resource types, starting at the current stream position."""
self._reference_counts: typing.MutableMapping[bytes, int] = collections.OrderedDict() self._reference_counts = collections.OrderedDict()
(type_list_length_m1,) = self._stream_unpack(STRUCT_RESOURCE_TYPE_LIST_HEADER) (type_list_length_m1,) = self._stream_unpack(STRUCT_RESOURCE_TYPE_LIST_HEADER)
type_list_length = (type_list_length_m1 + 1) % 0x10000 type_list_length = (type_list_length_m1 + 1) % 0x10000
@ -411,11 +431,10 @@ class ResourceFile(collections.abc.Mapping):
def _read_all_references(self): def _read_all_references(self):
"""Read all resource references, starting at the current stream position.""" """Read all resource references, starting at the current stream position."""
self._references: typing.MutableMapping[bytes, typing.MutableMapping[int, typing.Tuple[int, ResourceAttrs, int]]] = collections.OrderedDict() self._references = collections.OrderedDict()
for resource_type, count in self._reference_counts.items(): for resource_type, count in self._reference_counts.items():
resmap: typing.MutableMapping[int, typing.Tuple[int, ResourceAttrs, int]] = collections.OrderedDict() self._references[resource_type] = resmap = collections.OrderedDict()
self._references[resource_type] = resmap
for _ in range(count): for _ in range(count):
( (
resource_id, resource_id,

View File

@ -60,31 +60,41 @@ class CompressedHeaderInfo(object):
else: else:
raise DecompressError(f"Unsupported compression type: 0x{compression_type:>04x}") raise DecompressError(f"Unsupported compression type: 0x{compression_type:>04x}")
header_length: int
compression_type: int
decompressed_length: int
dcmp_id: int
def __init__(self, header_length: int, compression_type: int, decompressed_length: int, dcmp_id: int) -> None: def __init__(self, header_length: int, compression_type: int, decompressed_length: int, dcmp_id: int) -> None:
super().__init__() super().__init__()
self.header_length: int = header_length self.header_length = header_length
self.compression_type: int = compression_type self.compression_type = compression_type
self.decompressed_length: int = decompressed_length self.decompressed_length = decompressed_length
self.dcmp_id: int = dcmp_id self.dcmp_id = dcmp_id
class CompressedApplicationHeaderInfo(CompressedHeaderInfo): class CompressedApplicationHeaderInfo(CompressedHeaderInfo):
working_buffer_fractional_size: int
expansion_buffer_size: int
def __init__(self, header_length: int, compression_type: int, decompressed_length: int, dcmp_id: int, working_buffer_fractional_size: int, expansion_buffer_size: int) -> None: def __init__(self, header_length: int, compression_type: int, decompressed_length: int, dcmp_id: int, working_buffer_fractional_size: int, expansion_buffer_size: int) -> None:
super().__init__(header_length, compression_type, decompressed_length, dcmp_id) super().__init__(header_length, compression_type, decompressed_length, dcmp_id)
self.working_buffer_fractional_size: int = working_buffer_fractional_size self.working_buffer_fractional_size = working_buffer_fractional_size
self.expansion_buffer_size: int = expansion_buffer_size self.expansion_buffer_size = expansion_buffer_size
def __repr__(self): def __repr__(self):
return f"{type(self).__qualname__}(header_length={self.header_length}, compression_type=0x{self.compression_type:>04x}, decompressed_length={self.decompressed_length}, dcmp_id={self.dcmp_id}, working_buffer_fractional_size={self.working_buffer_fractional_size}, expansion_buffer_size={self.expansion_buffer_size})" return f"{type(self).__qualname__}(header_length={self.header_length}, compression_type=0x{self.compression_type:>04x}, decompressed_length={self.decompressed_length}, dcmp_id={self.dcmp_id}, working_buffer_fractional_size={self.working_buffer_fractional_size}, expansion_buffer_size={self.expansion_buffer_size})"
class CompressedSystemHeaderInfo(CompressedHeaderInfo): class CompressedSystemHeaderInfo(CompressedHeaderInfo):
parameters: bytes
def __init__(self, header_length: int, compression_type: int, decompressed_length: int, dcmp_id: int, parameters: bytes) -> None: def __init__(self, header_length: int, compression_type: int, decompressed_length: int, dcmp_id: int, parameters: bytes) -> None:
super().__init__(header_length, compression_type, decompressed_length, dcmp_id) super().__init__(header_length, compression_type, decompressed_length, dcmp_id)
self.parameters: bytes = parameters self.parameters = parameters
def __repr__(self): def __repr__(self):
return f"{type(self).__qualname__}(header_length={self.header_length}, compression_type=0x{self.compression_type:>04x}, decompressed_length={self.decompressed_length}, dcmp_id={self.dcmp_id}, parameters={self.parameters!r})" return f"{type(self).__qualname__}(header_length={self.header_length}, compression_type=0x{self.compression_type:>04x}, decompressed_length={self.decompressed_length}, dcmp_id={self.dcmp_id}, parameters={self.parameters!r})"