File fopen-workaround-bad-buffering-for-binary-mode-563.patch of Package salt

From 6c1c81aba71711632a14b725426077f9183065e9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?=
 <psuarezhernandez@suse.com>
Date: Thu, 6 Oct 2022 10:55:50 +0100
Subject: [PATCH] fopen: Workaround bad buffering for binary mode
 (#563)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

A lot of code assumes Python 2.x behavior for buffering, in which 1 is a
special value meaning line buffered.

Python 3 makes this value unusable, so fallback to the default buffering
size, and report these calls to be fixed.

Fixes: https://github.com/saltstack/salt/issues/57584

Do not drop buffering from kwargs to avoid errors

Add unit test around linebuffering in binary mode

Add changelog file

Co-authored-by: Pablo Suárez Hernández <psuarezhernandez@suse.com>

Co-authored-by: Ismael Luceno <iluceno@suse.de>
---
 changelog/62817.fixed                  |  1 +
 salt/utils/files.py                    |  8 ++++++++
 tests/pytests/unit/utils/test_files.py | 13 ++++++++++++-
 3 files changed, 21 insertions(+), 1 deletion(-)
 create mode 100644 changelog/62817.fixed

diff --git a/changelog/62817.fixed b/changelog/62817.fixed
new file mode 100644
index 0000000000..ff335f2916
--- /dev/null
+++ b/changelog/62817.fixed
@@ -0,0 +1 @@
+Prevent annoying RuntimeWarning message about line buffering (buffering=1) not being supported in binary mode
diff --git a/salt/utils/files.py b/salt/utils/files.py
index 1cf636a753..3c57cce713 100644
--- a/salt/utils/files.py
+++ b/salt/utils/files.py
@@ -6,6 +6,7 @@ Functions for working with files
 import codecs
 import contextlib
 import errno
+import io
 import logging
 import os
 import re
@@ -382,6 +383,13 @@ def fopen(*args, **kwargs):
     if not binary and not kwargs.get("newline", None):
         kwargs["newline"] = ""
 
+    # Workaround callers with bad buffering setting for binary files
+    if kwargs.get("buffering") == 1 and "b" in kwargs.get("mode", ""):
+        log.debug(
+            "Line buffering (buffering=1) isn't supported in binary mode, the default buffer size will be used"
+        )
+        kwargs["buffering"] = io.DEFAULT_BUFFER_SIZE
+
     f_handle = open(*args, **kwargs)  # pylint: disable=resource-leakage
 
     if is_fcntl_available():
diff --git a/tests/pytests/unit/utils/test_files.py b/tests/pytests/unit/utils/test_files.py
index fd88167b16..bd18bc5750 100644
--- a/tests/pytests/unit/utils/test_files.py
+++ b/tests/pytests/unit/utils/test_files.py
@@ -4,11 +4,12 @@ Unit Tests for functions located in salt/utils/files.py
 
 
 import copy
+import io
 import os
 
 import pytest
 import salt.utils.files
-from tests.support.mock import patch
+from tests.support.mock import MagicMock, patch
 
 
 def test_safe_rm():
@@ -74,6 +75,16 @@ def test_fopen_with_disallowed_fds():
             )
 
 
+def test_fopen_binary_line_buffering(tmp_path):
+    tmp_file = os.path.join(tmp_path, "foobar")
+    with patch("builtins.open") as open_mock, patch(
+        "salt.utils.files.is_fcntl_available", MagicMock(return_value=False)
+    ):
+        salt.utils.files.fopen(os.path.join(tmp_path, "foobar"), mode="b", buffering=1)
+        assert open_mock.called
+        assert open_mock.call_args[1]["buffering"] == io.DEFAULT_BUFFER_SIZE
+
+
 def _create_temp_structure(temp_directory, structure):
     for folder, files in structure.items():
         current_directory = os.path.join(temp_directory, folder)
-- 
2.37.3


openSUSE Build Service is sponsored by