7
[Solved] Subclassing pathlib.PosixPath broken since Python 3.12 (actually its fixed, but workaround broken)
(beehaw.org)
Solved: Thanks to a user with this reply: https://programming.dev/comment/10034690
cross-posted from: https://beehaw.org/post/13901165
Hi all. I have a little problem and don't know how to solve. A CLI program in Python is broken since Python 3.12. It was working in Python 3.11. The reason is, that Python 3.12 changed how subclassing of a pathlib.Path works (basically fixed an issue), which now breaks a workaround.
The class in question is:
class File(PosixPath): def __new__(cls, *args: Any, **kwargs: Any) -> Any: return cls._from_parts(args).expanduser().resolve() # type: ignore def __init__(self, source: str | Path, *args: Any) -> None: super().__init__() self.__source = Path(source) @property def source(self) -> Path: return self.__source @property def modified(self) -> Time: return Time.fromtimestamp(os.path.getmtime(self)) @property def changed(self) -> Time: return Time.fromtimestamp(os.path.getctime(self)) @property def accessed(self) -> Time: return Time.fromtimestamp(os.path.getatime(self)) # Calculate sha512 hash of self file and compare result to the # checksum found in given file. Return True if identical. def verify_sha512(self, file: File, buffer_size: int = 4096) -> bool: compare_hash: str = file.read_text().split(" ")[0] self_hash: str = "" self_checksum = hashlib.sha512() with open(self.as_posix(), "rb") as f: for chunk in iter(lambda: f.read(buffer_size), b""): self_checksum.update(chunk) self_hash = self_checksum.hexdigest() return self_hash == compare_hash
and I get this error when running the script:
Traceback (most recent call last): File "/home/tuncay/.local/bin/geprotondl", line 1415, in sys.exit(main()) ^^^^^^ File "/home/tuncay/.local/bin/geprotondl", line 1334, in main arguments, status = parse_arguments(argv) ^^^^^^^^^^^^^^^^^^^^^ File "/home/tuncay/.local/bin/geprotondl", line 1131, in parse_arguments default, status = default_install_dir() ^^^^^^^^^^^^^^^^^^^^^ File "/home/tuncay/.local/bin/geprotondl", line 1101, in default_install_dir steam_root: File = File(path) ^^^^^^^^^^ File "/home/tuncay/.local/bin/geprotondl", line 97, in __new__ return cls._from_parts(args).expanduser().resolve() # type: ignore ^^^^^^^^^^^^^^^ AttributeError: type object 'File' has no attribute '_from_parts'. Did you mean: '_load_parts'?
Now replacing
_from_parts
with_load_parts
does not work either and I get this message in that case:Traceback (most recent call last): File "/home/tuncay/.local/bin/geprotondl", line 1415, in sys.exit(main()) ^^^^^^ File "/home/tuncay/.local/bin/geprotondl", line 1334, in main arguments, status = parse_arguments(argv) ^^^^^^^^^^^^^^^^^^^^^ File "/home/tuncay/.local/bin/geprotondl", line 1131, in parse_arguments default, status = default_install_dir() ^^^^^^^^^^^^^^^^^^^^^ File "/home/tuncay/.local/bin/geprotondl", line 1101, in default_install_dir steam_root: File = File(path) ^^^^^^^^^^ File "/home/tuncay/.local/bin/geprotondl", line 97, in __new__ return cls._load_parts(args).expanduser().resolve() # type: ignore ^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/pathlib.py", line 408, in _load_parts paths = self._raw_paths ^^^^^^^^^^^^^^^ AttributeError: 'tuple' object has no attribute '_raw_paths'
I have searched the web and don't understand how to fix this. Has anyone an idea what to do?