mirror of
https://github.com/dgelessus/python-rsrcfork.git
synced 2024-11-22 14:32:11 +00:00
Replace rsrcfork.open's rsrcfork parameter with a more usable version
The new fork parameter accepts strings, which are more understandable than the old None/True/False values, and can be extended in the future.
This commit is contained in:
parent
c4fe09dbf0
commit
e6779b021a
@ -144,6 +144,10 @@ Version 1.2.0 (next version)
|
|||||||
|
|
||||||
* This fixes reading certain system files with resource data in their data fork (such as HIToolbox.rsrc in HIToolbox.framework, or .dfont fonts) on recent macOS versions (at least macOS 10.14, possibly earlier). Although these files have no resource fork, recent macOS versions will successfully open the resource fork and return garbage data for it. This behavior is now detected and handled by using the data fork instead.
|
* This fixes reading certain system files with resource data in their data fork (such as HIToolbox.rsrc in HIToolbox.framework, or .dfont fonts) on recent macOS versions (at least macOS 10.14, possibly earlier). Although these files have no resource fork, recent macOS versions will successfully open the resource fork and return garbage data for it. This behavior is now detected and handled by using the data fork instead.
|
||||||
|
|
||||||
|
* Replaced the ``rsrcfork`` parameter of ``rsrcfork.open``/``ResourceFork.open`` with a new ``fork`` parameter. ``fork`` accepts string values (like the command line ``--fork`` option) rather than ``rsrcfork``'s hard to understand ``None``/``True``/``False``.
|
||||||
|
|
||||||
|
* The old ``rsrcfork`` parameter has been deprecated and will be removed in the future, but for now it still works as before.
|
||||||
|
|
||||||
* Added an explanatory message when a resource filter on the command line doesn't match any resources in the resource file. Previously there would either be no output or a confusing error, depending on the selected ``--format``.
|
* Added an explanatory message when a resource filter on the command line doesn't match any resources in the resource file. Previously there would either be no output or a confusing error, depending on the selected ``--format``.
|
||||||
* Improved error messages when attempting to read multiple resources using ``--format=hex`` or ``--format=raw``.
|
* Improved error messages when attempting to read multiple resources using ``--format=hex`` or ``--format=raw``.
|
||||||
* Fixed reading from non-seekable streams not working for some resource files.
|
* Fixed reading from non-seekable streams not working for some resource files.
|
||||||
|
@ -196,8 +196,6 @@ def main():
|
|||||||
|
|
||||||
ns = ap.parse_args()
|
ns = ap.parse_args()
|
||||||
|
|
||||||
ns.fork = {"auto": None, "data": False, "rsrc": True}[ns.fork]
|
|
||||||
|
|
||||||
if ns.file == "-":
|
if ns.file == "-":
|
||||||
if ns.fork is not None:
|
if ns.fork is not None:
|
||||||
print("Cannot specify an explicit fork when reading from stdin", file=sys.stderr)
|
print("Cannot specify an explicit fork when reading from stdin", file=sys.stderr)
|
||||||
@ -205,7 +203,7 @@ def main():
|
|||||||
|
|
||||||
rf = api.ResourceFile(sys.stdin.buffer)
|
rf = api.ResourceFile(sys.stdin.buffer)
|
||||||
else:
|
else:
|
||||||
rf = api.ResourceFile.open(ns.file, rsrcfork=ns.fork)
|
rf = api.ResourceFile.open(ns.file, fork=ns.fork)
|
||||||
|
|
||||||
with rf:
|
with rf:
|
||||||
if ns.header_system or ns.header_application:
|
if ns.header_system or ns.header_application:
|
||||||
|
@ -5,6 +5,7 @@ import io
|
|||||||
import os
|
import os
|
||||||
import struct
|
import struct
|
||||||
import typing
|
import typing
|
||||||
|
import warnings
|
||||||
|
|
||||||
from . import compress
|
from . import compress
|
||||||
|
|
||||||
@ -199,11 +200,16 @@ class ResourceFile(collections.abc.Mapping):
|
|||||||
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)}>"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def open(cls, filename: typing.Union[str, bytes, os.PathLike], *, rsrcfork: typing.Optional[bool]=None, **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.
|
||||||
|
|
||||||
If rsrcfork is not None, it is treated as boolean and controls whether the data or resource fork of the file should be opened. (On systems other than macOS, opening resource forks will not work of course, since they don't exist.)
|
The fork parameter controls which fork of the file the resource data will be read from. It accepts the following values:
|
||||||
If rsrcfork is None, the resource fork is opened if it exists and contains valid resource data, otherwise the data fork is opened instead.
|
|
||||||
|
* "auto" (the default): Automatically select the correct fork. The resource fork will be used if the file has one and it contains valid resource data. Otherwise the data fork will be used.
|
||||||
|
* "rsrc": Force use of the resource fork and never fall back to the data fork. This will not work on systems other than macOS, because they do not support resource forks natively.
|
||||||
|
* "data": Force use of the data fork, even if a resource fork is present.
|
||||||
|
|
||||||
|
The rsrcfork parameter is deprecated and will be removed in the future. It has the same purpose as the fork parameter, but accepts different argument values: None stands for "auto", True stands for "rsrc", and False stands for "data". These argument values are less understandable than the string versions and are not easily extensible in the future, which is why the parameter has been deprecated.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if "close" in kwargs:
|
if "close" in kwargs:
|
||||||
@ -211,7 +217,20 @@ class ResourceFile(collections.abc.Mapping):
|
|||||||
|
|
||||||
kwargs["close"] = True
|
kwargs["close"] = True
|
||||||
|
|
||||||
if rsrcfork is None:
|
if "rsrcfork" in kwargs:
|
||||||
|
if fork != "auto":
|
||||||
|
raise TypeError("The fork and rsrcfork parameters cannot be used together. Please use only the fork parameter; it replaces the deprecated rsrcfork parameter.")
|
||||||
|
|
||||||
|
if kwargs["rsrcfork"] is None:
|
||||||
|
fork = "auto"
|
||||||
|
elif kwargs["rsrcfork"]:
|
||||||
|
fork = "rsrc"
|
||||||
|
else:
|
||||||
|
fork = "data"
|
||||||
|
warnings.warn(DeprecationWarning(f"The rsrcfork parameter has been deprecated and will be removed in a future version. Please use fork={fork!r} instead of rsrcfork={kwargs['rsrcfork']!r}."))
|
||||||
|
del kwargs["rsrcfork"]
|
||||||
|
|
||||||
|
if fork == "auto":
|
||||||
# Determine whether the file has a usable resource fork.
|
# Determine whether the file has a usable resource fork.
|
||||||
try:
|
try:
|
||||||
# Try to open the resource fork.
|
# Try to open the resource fork.
|
||||||
@ -231,12 +250,14 @@ class ResourceFile(collections.abc.Mapping):
|
|||||||
except BaseException:
|
except BaseException:
|
||||||
f.close()
|
f.close()
|
||||||
raise
|
raise
|
||||||
elif rsrcfork:
|
elif fork == "rsrc":
|
||||||
# Force use of the resource fork.
|
# Force use of the resource fork.
|
||||||
return cls(open(os.path.join(filename, "..namedfork", "rsrc"), "rb"), **kwargs)
|
return cls(open(os.path.join(filename, "..namedfork", "rsrc"), "rb"), **kwargs)
|
||||||
else:
|
elif fork == "data":
|
||||||
# Force use of the data fork.
|
# Force use of the data fork.
|
||||||
return cls(open(filename, "rb"), **kwargs)
|
return cls(open(filename, "rb"), **kwargs)
|
||||||
|
else:
|
||||||
|
raise ValueError(f"Unsupported value for the fork parameter: {fork!r}")
|
||||||
|
|
||||||
def __init__(self, stream: typing.io.BinaryIO, *, close: bool=False):
|
def __init__(self, stream: typing.io.BinaryIO, *, close: bool=False):
|
||||||
"""Create a ResourceFile wrapping the given byte stream.
|
"""Create a ResourceFile wrapping the given byte stream.
|
||||||
|
Loading…
Reference in New Issue
Block a user