From 5d1e5f08040c622af72596335d8e924695349efb Mon Sep 17 00:00:00 2001 From: kznr Date: Thu, 20 May 2021 23:23:27 +0900 Subject: [PATCH] Resolve issue 207 and issue 226 It aims to avoid the unnecessary conversion by the decode method. The original hint was provided by Mr. Lutz K. Thank you very much --- src/harvesters/core.py | 32 ++++++++++++---------- src/harvesters/test/test_harvester_core.py | 17 ++++++++++++ 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/src/harvesters/core.py b/src/harvesters/core.py index 00d3f98..03922c0 100644 --- a/src/harvesters/core.py +++ b/src/harvesters/core.py @@ -3026,8 +3026,6 @@ def _release_buffers(self) -> None: _ = self._queue.get_nowait() - - def _save_file( *, xml_dir_to_store: Optional[str] = None, @@ -3057,26 +3055,20 @@ def _save_file( file_path = os.path.join(xml_dir_to_store, _file_name) # - mode_base = 'w+' - mode = mode_base - data_to_write = bytes_content = bytes_io.getvalue() - if pathlib.Path(file_path).suffix.lower() == '.zip': - mode += 'b' - else: - data_to_write = bytes_content.decode() - pos = data_to_write.find('\x00') - if pos != -1: - # Found a \x00: - data_to_write = data_to_write[:pos] + mode = 'w+' + data_to_write = bytes_io.getvalue() + if pathlib.Path(file_path).suffix.lower() != '.zip': + data_to_write = _drop_unnecessary_trailer(data_to_write) + # try: - with open(file_path, mode) as f: + with open(file_path, mode + 'b') as f: f.write(data_to_write) except UnicodeEncodeError: # Probably you've caught "UnicodeEncodeError: 'charmap' codec can't # encode characters"; the file must be a text file: try: - with io.open(file_path, mode_base, encoding="utf-8") as f: + with io.open(file_path, mode, encoding="utf-8") as f: f.write(data_to_write) except: e = sys.exc_info()[0] @@ -3090,6 +3082,16 @@ def _save_file( return file_path +def _drop_unnecessary_trailer(data_to_write: bytes): + assert data_to_write + pos = data_to_write.find(0x00) + if pos != -1: + # Found a \x00: + return data_to_write[:pos] + else: + return data_to_write + + class _CallbackDestroyImageAcquirer(Callback): def __init__(self, harvester): self._harvester = harvester diff --git a/src/harvesters/test/test_harvester_core.py b/src/harvesters/test/test_harvester_core.py index b921d6e..d457bdc 100644 --- a/src/harvesters/test/test_harvester_core.py +++ b/src/harvesters/test/test_harvester_core.py @@ -40,6 +40,7 @@ from harvesters.core import Callback from harvesters.core import Harvester from harvesters.core import ImageAcquirer +from harvesters.core import _drop_unnecessary_trailer from harvesters.test.helper import get_package_dir from harvesters.util.pfnc import Dictionary from harvesters.core import Component2DImage @@ -1011,5 +1012,21 @@ def test_issue_238(self): ) +class TestUtility(unittest.TestCase): + def test_issue_207_and_226(self): + body = b'\xc2\xb0' # ° + padding = b'\x00\x00' + data = body + padding + data = _drop_unnecessary_trailer(data) + self.assertEqual(data, body) + self.assertEqual('°', str(data, encoding='utf-8')) + + @unittest.skip # experimental + def test_issue_207_and_226_in_orignal_way(self): + data = b'\xc2\xb0' # ° + decoded = data.decode() + self.assertEqual('°', decoded) + + if __name__ == '__main__': unittest.main()