Skip to content

Commit

Permalink
Merge pull request #609 from Ravencentric/getinfo
Browse files Browse the repository at this point in the history
feat: add `getinfo()`
  • Loading branch information
miurahr authored Aug 8, 2024
2 parents 086bc92 + db40bd1 commit 5a3e9e3
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 0 deletions.
10 changes: 10 additions & 0 deletions py7zr/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import os
import pathlib
import platform
import posixpath
import sys
import time as _time
import zlib
Expand Down Expand Up @@ -436,6 +437,15 @@ def remove_relative_path_marker(path: str) -> str:
return processed_path


def remove_trailing_slash(path: str) -> str:
"""
Removes '/' from the end of a path-like string
"""
if path.endswith(posixpath.sep):
return path[:-1]
return path


def canonical_path(target: pathlib.PurePath) -> pathlib.PurePath:
"""Return a canonical path of target argument."""
stack: List[str] = []
Expand Down
17 changes: 17 additions & 0 deletions py7zr/py7zr.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
get_sanitized_output_path,
is_path_valid,
readlink,
remove_trailing_slash,
)
from py7zr.properties import DEFAULT_FILTERS, FILTER_DEFLATE64, MAGIC_7Z, get_default_blocksize, get_memory_limit

Expand Down Expand Up @@ -957,6 +958,22 @@ def namelist(self) -> List[str]:
"""Return a list of archive members by name."""
return list(map(lambda x: x.filename, self.files))

def getinfo(self, name: str) -> FileInfo:
"""Return a FileInfo object with information about the archive member *name*.
Calling getinfo() for a name not currently contained in the archive will raise a KeyError."""
# For interoperability with ZipFile
name = remove_trailing_slash(name)

# https://more-itertools.readthedocs.io/en/stable/_modules/more_itertools/recipes.html#first_true
sevenzipinfo = next(filter(lambda member: member.filename == name, self.files), None)

# ZipFile and TarFile raise KeyError if the named member is not found
# So for consistency, we'll also raise KeyError here
if sevenzipinfo is None:
raise KeyError(f"'{name}' not found in archive.")

return sevenzipinfo

def archiveinfo(self) -> ArchiveInfo:
total_uncompressed = functools.reduce(lambda x, y: x + y, [f.uncompressed for f in self.files])
if isinstance(self.fp, multivolumefile.MultiVolume):
Expand Down
41 changes: 41 additions & 0 deletions tests/test_getinfo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import os

import pytest

from py7zr import SevenZipFile

testdata_path = os.path.join(os.path.dirname(__file__), "data")


def test_getinfo_file():
with SevenZipFile(os.path.join(testdata_path, "copy.7z")) as archive:
member = archive.getinfo("test1.txt")
assert member.filename == "test1.txt"
assert member.is_directory is False


def test_getinfo_dir():
with SevenZipFile(os.path.join(testdata_path, "copy.7z")) as archive:
member = archive.getinfo("test")
assert member.filename == "test"
assert member.is_directory is True


def test_getinfo_file_with_trailing_slash():
with SevenZipFile(os.path.join(testdata_path, "copy.7z")) as archive:
member = archive.getinfo("test1.txt/")
assert member.filename == "test1.txt"
assert member.is_directory is False


def test_getinfo_dir_with_trailing_slash():
with SevenZipFile(os.path.join(testdata_path, "copy.7z")) as archive:
member = archive.getinfo("test/")
assert member.filename == "test"
assert member.is_directory is True


def test_getinfo_missing_member():
with pytest.raises(KeyError):
with SevenZipFile(os.path.join(testdata_path, "copy.7z")) as archive:
archive.getinfo("doesn't exist")

0 comments on commit 5a3e9e3

Please sign in to comment.