1"""
2Compatibility functions for utils
3"""
4
5
6import copy
7import importlib
8import sys
9import types
10
11import salt.loader
12
13
14def pack_dunder(name):
15    """
16    Compatibility helper function to make __utils__ available on demand.
17    """
18    # TODO: Deprecate starting with Beryllium
19
20    mod = sys.modules[name]
21    if not hasattr(mod, "__utils__"):
22        setattr(
23            mod, "__utils__", salt.loader.utils(mod.__opts__, pack_self="__utils__")
24        )
25
26
27def deepcopy_bound(name):
28    """
29    Compatibility helper function to allow copy.deepcopy copy bound methods
30    which is broken on Python 2.6, due to the following bug:
31    https://bugs.python.org/issue1515
32
33    Warnings:
34        - This method will mutate the global deepcopy dispatcher, which means that
35        this function is NOT threadsafe!
36
37        - Not Py3 compatible. The intended use case is deepcopy compat for Py2.6
38
39    """
40
41    def _deepcopy_method(x, memo):
42        # pylint: disable=incompatible-py3-code
43        return type(x)(x.im_func, copy.deepcopy(x.im_self, memo), x.im_class)
44        # pylint: enable=incompatible-py3-code
45
46    try:
47        pre_dispatch = copy._deepcopy_dispatch
48        copy._deepcopy_dispatch[types.MethodType] = _deepcopy_method
49        ret = copy.deepcopy(name)
50    finally:
51        copy._deepcopy_dispatch = pre_dispatch
52    return ret
53
54
55def cmp(x, y):
56    """
57    Compatibility helper function to replace the ``cmp`` function from Python 2. The
58    ``cmp`` function is no longer available in Python 3.
59
60    cmp(x, y) -> integer
61
62    Return negative if x<y, zero if x==y, positive if x>y.
63    """
64    return (x > y) - (x < y)
65
66
67def reload(mod):
68    """
69    Compatibility helper function to replace the ``reload`` builtin from Python 2.
70    """
71    try:
72        return importlib.reload(mod)
73    except AttributeError:
74        return reload(mod)
75