Rename resource_type and resource_id attributes to type and id

The old names were chosen to avoid conflicts with Python's type and id
builtins, but for attribute names this is not necessary.
This commit is contained in:
dgelessus 2019-09-15 15:56:03 +02:00
parent f4c2717720
commit c6337bdfbd
3 changed files with 31 additions and 20 deletions

View File

@ -56,7 +56,7 @@ Simple example
>>> rf
<rsrcfork.ResourceFile at 0x1046e6048, attributes ResourceFileAttrs.0, containing 4 resource types: [b'utxt', b'utf8', b'TEXT', b'drag']>
>>> rf[b"TEXT"]
<rsrcfork.ResourceFile._LazyResourceMap at 0x10470ed30 containing one resource: rsrcfork.Resource(resource_type=b'TEXT', resource_id=256, name=None, attributes=ResourceAttrs.0, data=b'Here is some text')>
<rsrcfork.ResourceFile._LazyResourceMap at 0x10470ed30 containing one resource: rsrcfork.Resource(type=b'TEXT', id=256, name=None, attributes=ResourceAttrs.0, data=b'Here is some text')>
Automatic selection of data/resource fork
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -133,6 +133,7 @@ Version 1.2.1 (next version)
* Added a ``--sort`` command line option to output resources sorted by type and ID, instead of using the order stored in the file.
* Added a ``--group`` command line option to group resources in list format by type (the default), ID, or with no grouping.
* Added a ``dump-text`` output format to the command line tool. This format is identical to ``dump``, but instead of a hex dump, it outputs the resource data as text. The data is decoded as MacRoman and classic Mac newlines (``\r``) are translated. This is useful for examining resources that contain mostly plain text.
* Renamed the ``rsrcfork.Resource`` attributes ``resource_type`` and ``resource_id`` to ``type`` and ``id``, respectively. The old names have been deprecated and will be removed in the future, but are still supported for now.
* Changed ``--format=dump`` output to match ``hexdump -C``'s format - spacing has been adjusted, and multiple subsequent identical lines are collapsed into a single ``*``.
Version 1.2.0

View File

@ -93,7 +93,7 @@ def _filter_resources(rf: api.ResourceFile, filters: typing.Sequence[str]) -> ty
continue
for res in resources.values():
matching[res.resource_type, res.resource_id] = res
matching[res.type, res.id] = res
elif filter[0] == filter[-1] == "'":
try:
resources = rf[_bytes_unescape(filter[1:-1])]
@ -101,7 +101,7 @@ def _filter_resources(rf: api.ResourceFile, filters: typing.Sequence[str]) -> ty
continue
for res in resources.values():
matching[res.resource_type, res.resource_id] = res
matching[res.type, res.id] = res
else:
pos = filter.find("'", 1)
if pos == -1:
@ -134,7 +134,7 @@ def _filter_resources(rf: api.ResourceFile, filters: typing.Sequence[str]) -> ty
for res in resources.values():
if res.name == name:
matching[res.resource_type, res.resource_id] = res
matching[res.type, res.id] = res
break
elif ":" in resid:
if resid.count(":") > 1:
@ -143,15 +143,15 @@ def _filter_resources(rf: api.ResourceFile, filters: typing.Sequence[str]) -> ty
start, end = int(start), int(end)
for res in resources.values():
if start <= res.resource_id <= end:
matching[res.resource_type, res.resource_id] = res
if start <= res.id <= end:
matching[res.type, res.id] = res
else:
resid = int(resid)
try:
res = resources[resid]
except KeyError:
continue
matching[res.resource_type, res.resource_id] = res
matching[res.type, res.id] = res
return list(matching.values())
@ -185,7 +185,7 @@ def _translate_text(data: bytes) -> str:
return data.decode(_TEXT_ENCODING).replace("\r", "\n")
def _describe_resource(res: api.Resource, *, include_type: bool, decompress: bool) -> str:
id_desc_parts = [f"{res.resource_id}"]
id_desc_parts = [f"{res.id}"]
if res.name is not None:
name = _bytes_escape(res.name, quote='"')
@ -214,7 +214,7 @@ def _describe_resource(res: api.Resource, *, include_type: bool, decompress: boo
desc = f"({id_desc}): {content_desc}"
if include_type:
restype = _bytes_escape(res.resource_type, quote="'")
restype = _bytes_escape(res.type, quote="'")
desc = f"'{restype}' {desc}"
return desc
@ -327,7 +327,7 @@ def _show_filtered_resources(resources: typing.Sequence[api.Resource], format: s
if None in attr_descs:
attr_descs[:] = [f"${res.attributes.value:02X}"]
parts = [str(res.resource_id)]
parts = [str(res.id)]
if res.name is not None:
name = _bytes_escape(res.name, quote='"')
@ -335,7 +335,7 @@ def _show_filtered_resources(resources: typing.Sequence[api.Resource], format: s
parts += attr_descs
restype = _bytes_escape(res.resource_type, quote="'")
restype = _bytes_escape(res.type, quote="'")
print(f"data '{restype}' ({', '.join(parts)}{attrs_comment}) {{")
for i in range(0, len(data), 16):
@ -380,7 +380,7 @@ def _list_resource_file(rf: api.ResourceFile, *, sort: bool, group: str, decompr
for reses in rf.values():
all_resources.extend(reses.values())
if sort:
all_resources.sort(key=lambda res: (res.resource_type, res.resource_id))
all_resources.sort(key=lambda res: (res.type, res.id))
print(f"{len(all_resources)} resources:")
for res in all_resources:
print(_describe_resource(res, include_type=True, decompress=decompress))
@ -402,13 +402,13 @@ def _list_resource_file(rf: api.ResourceFile, *, sort: bool, group: str, decompr
all_resources = []
for reses in rf.values():
all_resources.extend(reses.values())
all_resources.sort(key=lambda res: res.resource_id)
resources_by_id = {resid: list(reses) for resid, reses in itertools.groupby(all_resources, key=lambda res: res.resource_id)}
all_resources.sort(key=lambda res: res.id)
resources_by_id = {resid: list(reses) for resid, reses in itertools.groupby(all_resources, key=lambda res: res.id)}
print(f"{len(resources_by_id)} resource IDs:")
for resid, resources in resources_by_id.items():
print(f"{resid}: {len(resources)} resources:")
if sort:
resources.sort(key=lambda res: res.resource_type)
resources.sort(key=lambda res: res.type)
for res in resources:
print(_describe_resource(res, include_type=True, decompress=decompress))
print()
@ -444,7 +444,7 @@ def main():
resources.extend(reses.values())
if ns.sort:
resources.sort(key=lambda res: (res.resource_type, res.resource_id))
resources.sort(key=lambda res: (res.type, res.id))
_show_filtered_resources(resources, format=ns.format, decompress=ns.decompress)
else:

View File

@ -96,15 +96,15 @@ class ResourceAttrs(enum.Flag):
class Resource(object):
"""A single resource from a resource file."""
__slots__ = ("resource_type", "resource_id", "name", "attributes", "data_raw", "_data_decompressed")
__slots__ = ("type", "id", "name", "attributes", "data_raw", "_data_decompressed")
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."""
super().__init__()
self.resource_type: bytes = resource_type
self.resource_id: int = resource_id
self.type: bytes = resource_type
self.id: int = resource_id
self.name: typing.Optional[bytes] = name
self.attributes: ResourceAttrs = attributes
self.data_raw: bytes = data_raw
@ -126,7 +126,17 @@ class Resource(object):
if not decompress_ok:
data_repr = f"<decompression failed - compressed data: {data_repr}>"
return f"{type(self).__module__}.{type(self).__qualname__}(resource_type={self.resource_type}, resource_id={self.resource_id}, name={self.name}, attributes={self.attributes}, data={data_repr})"
return f"{type(self).__module__}.{type(self).__qualname__}(type={self.type}, id={self.id}, name={self.name}, attributes={self.attributes}, data={data_repr})"
@property
def resource_type(self) -> bytes:
warnings.warn(DeprecationWarning("The resource_type attribute has been deprecated and will be removed in a future version. Please use the type attribute instead."))
return self.type
@property
def resource_id(self) -> int:
warnings.warn(DeprecationWarning("The resource_id attribute has been deprecated and will be removed in a future version. Please use the id attribute instead."))
return self.id
@property
def data(self) -> bytes: