# Buggy code
def next(self):
    """
    Return the next iteration by popping `chunk_size` from the left and
    appending `chunk_size` to the right if there's info on the file left
    to be read.
    """
    if self.__buffered is None:
        # Use floor division to force multiplier to an integer
        multiplier = self.__max_in_mem // self.__chunk_size
        self.__buffered = ""
    else:
        multiplier = 1
        self.__buffered = self.__buffered[self.__chunk_size :]

    if six.PY3:
        # Data is a byte object in Python 3
        # Decode it in order to append to self.__buffered str later
        data = self.__file.read(self.__chunk_size * multiplier).decode(
            __salt_system_encoding__
        )
    else:
        data = self.__file.read(self.__chunk_size * multiplier)

    if not data:
        self.__file.close()
        raise StopIteration

    self.__buffered += data
    return self.__buffered


# Traceback (AttributeError)
jid: 20190124144146673217
minion:
----------
ID: test
Function: module.run
Result: False
Comment: An exception occurred in this state: Traceback (most recent call last):
File "c:\salt\bin\lib\site-packages\salt\state.py", line 1913, in call
**cdata['kwargs'])
File "c:\salt\bin\lib\site-packages\salt\loader.py", line 1898, in wrapper
return f(*args, **kwargs)
File "c:\salt\bin\lib\site-packages\salt\utils\decorators\__init__.py", line 558, in _decorate
return self._call_function(kwargs)
File "c:\salt\bin\lib\site-packages\salt\utils\decorators\__init__.py", line 263, in _call_function
raise error
File "c:\salt\bin\lib\site-packages\salt\utils\decorators\__init__.py", line 250, in _call_function
return self._function(*args, **kwargs)
File "c:\salt\bin\lib\site-packages\salt\states\module.py", line 293, in run
func_args=kwargs.get(func))
File "c:\salt\bin\lib\site-packages\salt\states\module.py", line 357, in _call_function
mret = __salt__[name](*arg_type, **func_kw)
File "c:\salt\bin\lib\site-packages\salt\modules\file.py", line 2875, in contains
for chunk in breader:
File "c:\salt\bin\lib\site-packages\salt\utils\filebuffer.py", line 91, in next
data = self.__file.read(self.__chunk_size * multiplier).decode(
AttributeError: 'str' object has no attribute 'decode'
Started: 06:45:21.732349
Duration: 19.308 ms
Changes:

Summary for minion
------------
Succeeded: 1 (changed=1)
Failed:    1
------------
Total states run:     2
Total run time:   2.697 s
ERROR: Minions returned with non-zero exit code

# Fixed code
def next(self):
    """
    Return the next iteration by popping `chunk_size` from the left and
    appending `chunk_size` to the right if there's info on the file left
    to be read.
    """
    if self.__buffered is None:
        # Use floor division to force multiplier to an integer
        multiplier = self.__max_in_mem // self.__chunk_size
        self.__buffered = ""
    else:
        multiplier = 1
        self.__buffered = self.__buffered[self.__chunk_size :]

    data = self.__file.read(self.__chunk_size * multiplier)
    # Data is a byte object in Python 3
    # Decode it in order to append to self.__buffered str later
    # Use the salt util in case it's already a string (Windows)
    data = salt.utils.stringutils.to_str(data)

    if not data:
        self.__file.close()
        raise StopIteration

    self.__buffered += data
    return self.__buffered