When you write
"C:\Program Files\7-Zip\7z.exe"
you should use the r string literal prefix to make it clear to the interpreter that you didn't intend to write escape sequences.
When you define a @dataclass, consider settings slots=True for performance and robustness reasons.
Is it really important to add size on FileEntry? You could just as easily write a @property that calls stat().st_size on the Path. Similar for is_dir.
This:
f" {str(file.path)
does not need to str(); string casts are implied in arguments to an interpolated string.
I discourage this pattern:
sub = subprocess.run(command_line, capture_output=True, check=False)
if sub.returncode != 0:
logger.error(
f"Command line {' '.join(map(str, command_line))} returned {sub.returncode}"
)
return None
You should check=True within a try. You have a logger (good!) so you can pass exc_info=True during your except. That means you could convert to check_output. You should also pass text=True and not bother about the encoding stuff.
For logger calls like this:
logger.debug(f"Listing {archive}, using password {password}")
Don't do string interpolation. Use the logger's own variadic-argument percent-style, as in
logger.debug('Listing %s, using password %s', archive, password)