From 0518c8090ddf5833851646840315eee53a92339e Mon Sep 17 00:00:00 2001 From: Hiroshi Miura Date: Fri, 12 Feb 2021 08:31:57 +0900 Subject: [PATCH] workaournd writef() on pypy3 pypy3's BufferedReader don't have __sizeof__() so alternatively calculate it with seek() and tell() Signed-off-by: Hiroshi Miura --- py7zr/py7zr.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/py7zr/py7zr.py b/py7zr/py7zr.py index 04cb595f..40abf30c 100644 --- a/py7zr/py7zr.py +++ b/py7zr/py7zr.py @@ -917,13 +917,21 @@ def writef(self, bio: BinaryIO, arcname: str): elif isinstance(bio, io.TextIOBase): # First check whether is it Text? raise ValueError("Unsupported file object type: please open file with Binary mode.") - elif isinstance(bio, io.BufferedIOBase): - size = bio.__sizeof__() elif hasattr(bio, "read") and hasattr(bio, "__sizeof__"): - # Allow objet type which has read() and length methods for duck typing + # CPython's io.BufferedIOBase or io.BufferedReader has __sizeof__, but + # pypy3 don't have. So first check __sizeof__ and then goes to alternative. + # Also allowing objet type which has read() and length methods for duck typing size = bio.__sizeof__() + elif isinstance(bio, io.BufferedIOBase): + # come here when subtype of io.BufferedIOBase that don't have __sizeof__ (eg. pypy) + # alternative for `size = bio.__sizeof__()` + current = bio.tell() + bio.seek(0, os.SEEK_END) + last = bio.tell() + bio.seek(current, os.SEEK_SET) + size = last - current else: - raise ValueError("Wrong argument passed for bio.") + raise ValueError("Wrong argument passed for argument bio.") file_info = self._make_file_info_from_name(bio, size, arcname) self.header.files_info.files.append(file_info) self.header.files_info.emptyfiles.append(file_info['emptystream'])