Drop Py2 and six on tests/support/mock.py

This commit is contained in:
Pedro Algarvio 2021-02-19 17:30:58 +00:00
parent 93250dc1ab
commit 05bbe14088

View file

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
:codeauthor: Pedro Algarvio (pedro@algarvio.me)
@ -14,7 +13,6 @@
"""
# pylint: disable=unused-import,function-redefined,blacklisted-module,blacklisted-external-module
from __future__ import absolute_import
import collections
import copy
@ -43,9 +41,6 @@ from mock import (
sentinel,
)
# Import salt libs
from salt.ext import six
# pylint: disable=no-name-in-module,no-member
@ -57,7 +52,7 @@ if sys.version_info < (3, 6) and __mock_version < (2,):
raise ImportError("Please install mock>=2.0.0")
class MockFH(object):
class MockFH:
def __init__(self, filename, read_data, *args, **kwargs):
self.filename = filename
self.read_data = read_data
@ -89,7 +84,7 @@ class MockFH(object):
"""
# Newline will always be a bytestring on PY2 because mock_open will have
# normalized it to one.
newline = b"\n" if isinstance(read_data, six.binary_type) else "\n"
newline = b"\n" if isinstance(read_data, bytes) else "\n"
read_data = [line + newline for line in read_data.split(newline)]
@ -103,8 +98,7 @@ class MockFH(object):
# newline that we added in the list comprehension.
read_data[-1] = read_data[-1][:-1]
for line in read_data:
yield line
yield from read_data
@property
def write_calls(self):
@ -126,18 +120,18 @@ class MockFH(object):
def __check_read_data(self):
if not self.__read_data_ok:
if self.binary_mode:
if not isinstance(self.read_data, six.binary_type):
if not isinstance(self.read_data, bytes):
raise TypeError(
"{0} opened in binary mode, expected read_data to be "
"bytes, not {1}".format(
"{} opened in binary mode, expected read_data to be "
"bytes, not {}".format(
self.filename, type(self.read_data).__name__
)
)
else:
if not isinstance(self.read_data, str):
raise TypeError(
"{0} opened in non-binary mode, expected read_data to "
"be str, not {1}".format(
"{} opened in non-binary mode, expected read_data to "
"be str, not {}".format(
self.filename, type(self.read_data).__name__
)
)
@ -147,8 +141,8 @@ class MockFH(object):
def _read(self, size=0):
self.__check_read_data()
if not self.read_mode:
raise IOError("File not open for reading")
if not isinstance(size, six.integer_types) or size < 0:
raise OSError("File not open for reading")
if not isinstance(size, int) or size < 0:
raise TypeError("a positive integer is required")
joined = self.empty_string.join(self.read_data_iter)
@ -169,7 +163,7 @@ class MockFH(object):
# TODO: Implement "size" argument
self.__check_read_data()
if not self.read_mode:
raise IOError("File not open for reading")
raise OSError("File not open for reading")
ret = list(self.read_data_iter)
self.__loc += sum(len(x) for x in ret)
return ret
@ -178,7 +172,7 @@ class MockFH(object):
# TODO: Implement "size" argument
self.__check_read_data()
if not self.read_mode:
raise IOError("File not open for reading")
raise OSError("File not open for reading")
try:
ret = next(self.read_data_iter)
self.__loc += len(ret)
@ -189,7 +183,7 @@ class MockFH(object):
def __iter__(self):
self.__check_read_data()
if not self.read_mode:
raise IOError("File not open for reading")
raise OSError("File not open for reading")
while True:
try:
ret = next(self.read_data_iter)
@ -200,30 +194,23 @@ class MockFH(object):
def _write(self, content):
if not self.write_mode:
raise IOError("File not open for writing")
if six.PY2:
if isinstance(content, six.text_type):
# encoding intentionally not specified to force a
# UnicodeEncodeError when non-ascii unicode type is passed
content.encode()
raise OSError("File not open for writing")
else:
content_type = type(content)
if self.binary_mode and content_type is not bytes:
raise TypeError(
"a bytes-like object is required, not '{0}'".format(
"a bytes-like object is required, not '{}'".format(
content_type.__name__
)
)
elif not self.binary_mode and content_type is not str:
raise TypeError(
"write() argument must be str, not {0}".format(
content_type.__name__
)
"write() argument must be str, not {}".format(content_type.__name__)
)
def _writelines(self, lines):
if not self.write_mode:
raise IOError("File not open for writing")
raise OSError("File not open for writing")
for line in lines:
self._write(line)
@ -234,26 +221,24 @@ class MockFH(object):
pass
class MockCall(object):
class MockCall:
def __init__(self, *args, **kwargs):
self.args = args
self.kwargs = kwargs
def __repr__(self):
# future lint: disable=blacklisted-function
ret = str("MockCall(")
ret = "MockCall("
for arg in self.args:
ret += repr(arg) + str(", ")
ret += repr(arg) + ", "
if not self.kwargs:
if self.args:
# Remove trailing ', '
ret = ret[:-2]
else:
for key, val in six.iteritems(self.kwargs):
ret += str("{0}={1}").format(
salt.utils.stringutils.to_str(key), repr(val)
)
ret += str(")")
for key, val in self.kwargs.items():
ret += "{}={}".format(salt.utils.stringutils.to_str(key), repr(val))
ret += ")"
return ret
# future lint: enable=blacklisted-function
@ -264,7 +249,7 @@ class MockCall(object):
return self.args == other.args and self.kwargs == other.kwargs
class MockOpen(object):
class MockOpen:
r'''
This class can be used to mock the use of ``open()``.
@ -375,21 +360,6 @@ class MockOpen(object):
if not isinstance(read_data, dict):
read_data = {"*": read_data}
if six.PY2:
# .__class__() used here to preserve the dict class in the event that
# an OrderedDict was used.
new_read_data = read_data.__class__()
for key, val in six.iteritems(read_data):
try:
val = salt.utils.data.decode(val, to_str=True)
except TypeError:
if not isinstance(val, BaseException):
raise
new_read_data[key] = val
read_data = new_read_data
del new_read_data
self.read_data = read_data
self.filehandles = {}
self.calls = []
@ -424,7 +394,7 @@ class MockOpen(object):
except IndexError:
# We've run out of file contents, abort!
raise RuntimeError(
"File matching expression '{0}' opened more times than "
"File matching expression '{}' opened more times than "
"expected".format(matched_pattern)
)
@ -443,7 +413,7 @@ class MockOpen(object):
except KeyError:
# No matching glob in read_data, treat this as a file that does
# not exist and raise the appropriate exception.
raise IOError(errno.ENOENT, "No such file or directory", name)
raise OSError(errno.ENOENT, "No such file or directory", name)
def write_calls(self, path=None):
"""
@ -451,7 +421,7 @@ class MockOpen(object):
the results to files matching a given pattern.
"""
ret = []
for filename, handles in six.iteritems(self.filehandles):
for filename, handles in self.filehandles.items():
if path is None or fnmatch.fnmatch(filename, path):
for fh_ in handles:
ret.extend(fh_.write_calls)
@ -463,19 +433,19 @@ class MockOpen(object):
narrow the results to files matching a given pattern.
"""
ret = []
for filename, handles in six.iteritems(self.filehandles):
for filename, handles in self.filehandles.items():
if path is None or fnmatch.fnmatch(filename, path):
for fh_ in handles:
ret.extend(fh_.writelines_calls)
return ret
class MockTimedProc(object):
class MockTimedProc:
"""
Class used as a stand-in for salt.utils.timed_subprocess.TimedProc
"""
class _Process(object):
class _Process:
"""
Used to provide a dummy "process" attribute
"""