miurahr / py7zr

7zip in python3 with ZStandard, PPMd, LZMA2, LZMA1, Delta, BCJ, BZip2, and Deflate compressions, and AES encryption.
https://pypi.org/project/py7zr/
GNU Lesser General Public License v2.1
462 stars 74 forks source link

Add `getinfo()` method to get a single `FileInfo` by name #608

Closed Ravencentric closed 3 months ago

Ravencentric commented 3 months ago

Is your feature request related to a problem? Please describe. Ability to retrieve a single FileInfo from a sevenzipfile by it's name.

Describe the solution you'd like A method to retrieve a single FileInfo from a sevenzipfile by it's name. Examples: https://docs.python.org/3/library/zipfile.html#zipfile.ZipFile.getinfo https://docs.python.org/3/library/tarfile.html#tarfile.TarFile.getmember

Describe alternatives you've considered Writing my own solution:

    def get_member(self, member: StrPath) -> ArchiveMember:
        # Unlike the rest, SevenZip member directories do not end with `/`, so we need to strip it out
        # i.e, `spam/eggs/` in a ZipFile is equivalent to `spam/eggs` in SevenZipFile
        name = member.removesuffix("/")

        # SevenZipFile doesn't have an equivalent for `get_member` like the rest, so we hand craft it instead
        # https://more-itertools.readthedocs.io/en/stable/_modules/more_itertools/recipes.html#first_true
        sevenzipinfo = next(filter(lambda mem: mem.filename == name, self._sevenzipfile.list()), None)

        # ZipFile and TarFile raise KeyError
        # So for consistency (and because I like KeyError over None), we'll also raise KeyError here
        if sevenzipinfo is None:
            raise KeyError(f"{name} not found in {self._file}")

Additional context Some things to consider: Directories end with / in ZipFile but NOT in TarFile and SevenZipFile. TarFile accepts BOTH, i.e, tarfile.getmember("src/directory/") == tarfile.getmember("src/directory") ZipFile is strict and will not accept ZipFile.getinfo("src/directory")

I think if SevenZipFile were to add this method, it should be lenient and strip / from the end if present

miurahr commented 3 months ago

If you can help further, adding manual description will be worth.

Ravencentric commented 3 months ago

Docs? I'll update them later today