"Fossies" - the Fresh Open Source Software Archive 
Member "salt-3002.2/salt/_compat.py" (18 Nov 2020, 7368 Bytes) of package /linux/misc/salt-3002.2.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style:
standard) with prefixed line numbers.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "_compat.py" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
3002.1_vs_3002.2.
1 """
2 Salt compatibility code
3 """
4 # pylint: disable=import-error,unused-import,invalid-name,W0231,W0233
5
6
7 import binascii
8 import logging
9 import sys
10
11 from salt.exceptions import SaltException
12 from salt.ext.six import binary_type, integer_types, string_types, text_type
13 from salt.ext.six.moves import StringIO, cStringIO
14
15 log = logging.getLogger(__name__)
16
17 try:
18 # Python >2.5
19 import xml.etree.cElementTree as ElementTree
20 except Exception: # pylint: disable=broad-except
21 try:
22 # Python >2.5
23 import xml.etree.ElementTree as ElementTree
24 except Exception: # pylint: disable=broad-except
25 try:
26 # normal cElementTree install
27 import elementtree.cElementTree as ElementTree
28 except Exception: # pylint: disable=broad-except
29 try:
30 # normal ElementTree install
31 import elementtree.ElementTree as ElementTree
32 except Exception: # pylint: disable=broad-except
33 ElementTree = None
34
35
36 # True if we are running on Python 3.
37 PY3 = sys.version_info.major == 3
38
39
40 if PY3:
41 import builtins
42
43 exceptions = builtins
44 else:
45 import exceptions
46
47
48 if ElementTree is not None:
49 if not hasattr(ElementTree, "ParseError"):
50
51 class ParseError(Exception):
52 """
53 older versions of ElementTree do not have ParseError
54 """
55
56 ElementTree.ParseError = ParseError
57
58
59 def text_(s, encoding="latin-1", errors="strict"):
60 """
61 If ``s`` is an instance of ``binary_type``, return
62 ``s.decode(encoding, errors)``, otherwise return ``s``
63 """
64 return s.decode(encoding, errors) if isinstance(s, binary_type) else s
65
66
67 def bytes_(s, encoding="latin-1", errors="strict"):
68 """
69 If ``s`` is an instance of ``text_type``, return
70 ``s.encode(encoding, errors)``, otherwise return ``s``
71 """
72 return s.encode(encoding, errors) if isinstance(s, text_type) else s
73
74
75 def ascii_native_(s):
76 """
77 Python 3: If ``s`` is an instance of ``text_type``, return
78 ``s.encode('ascii')``, otherwise return ``str(s, 'ascii', 'strict')``
79
80 Python 2: If ``s`` is an instance of ``text_type``, return
81 ``s.encode('ascii')``, otherwise return ``str(s)``
82 """
83 if isinstance(s, text_type):
84 s = s.encode("ascii")
85
86 return str(s, "ascii", "strict") if PY3 else s
87
88
89 def native_(s, encoding="latin-1", errors="strict"):
90 """
91 Python 3: If ``s`` is an instance of ``text_type``, return ``s``, otherwise
92 return ``str(s, encoding, errors)``
93
94 Python 2: If ``s`` is an instance of ``text_type``, return
95 ``s.encode(encoding, errors)``, otherwise return ``str(s)``
96 """
97 if PY3:
98 out = s if isinstance(s, text_type) else str(s, encoding, errors)
99 else:
100 out = s.encode(encoding, errors) if isinstance(s, text_type) else str(s)
101
102 return out
103
104
105 def string_io(data=None): # cStringIO can't handle unicode
106 """
107 Pass data through to stringIO module and return result
108 """
109 try:
110 return cStringIO(bytes(data))
111 except (UnicodeEncodeError, TypeError):
112 return StringIO(data)
113
114
115 try:
116 if PY3:
117 import ipaddress
118 else:
119 import salt.ext.ipaddress as ipaddress
120 except ImportError:
121 ipaddress = None
122
123
124 class IPv6AddressScoped(ipaddress.IPv6Address):
125 """
126 Represent and manipulate single IPv6 Addresses.
127 Scope-aware version
128 """
129
130 def __init__(self, address):
131 """
132 Instantiate a new IPv6 address object. Scope is moved to an attribute 'scope'.
133
134 Args:
135 address: A string or integer representing the IP
136
137 Additionally, an integer can be passed, so
138 IPv6Address('2001:db8::') == IPv6Address(42540766411282592856903984951653826560)
139 or, more generally
140 IPv6Address(int(IPv6Address('2001:db8::'))) == IPv6Address('2001:db8::')
141
142 Raises:
143 AddressValueError: If address isn't a valid IPv6 address.
144
145 :param address:
146 """
147 # pylint: disable-all
148 if not hasattr(self, "_is_packed_binary"):
149 # This method (below) won't be around for some Python 3 versions
150 # and we need check this differently anyway
151 self._is_packed_binary = lambda p: isinstance(p, bytes)
152 # pylint: enable-all
153 if isinstance(address, string_types) and "%" in address:
154 buff = address.split("%")
155 if len(buff) != 2:
156 raise SaltException('Invalid IPv6 address: "{}"'.format(address))
157 address, self.__scope = buff
158 else:
159 self.__scope = None
160
161 # For compatibility with python3.9 ipaddress
162 self._scope_id = self.__scope
163
164 if sys.version_info.major == 2:
165 ipaddress._BaseAddress.__init__(self, address)
166 ipaddress._BaseV6.__init__(self, address)
167 else:
168 # Python 3.4 fix. Versions higher are simply not affected
169 # https://github.com/python/cpython/blob/3.4/Lib/ipaddress.py#L543-L544
170 self._version = 6
171 self._max_prefixlen = ipaddress.IPV6LENGTH
172
173 # Efficient constructor from integer.
174 if isinstance(address, integer_types):
175 self._check_int_address(address)
176 self._ip = address
177 elif self._is_packed_binary(address):
178 self._check_packed_address(address, 16)
179 self._ip = int(binascii.hexlify(address), 16)
180 else:
181 address = str(address)
182 if "/" in address:
183 raise ipaddress.AddressValueError(
184 "Unexpected '/' in {}".format(address)
185 )
186 self._ip = self._ip_int_from_string(address)
187
188 def _is_packed_binary(self, data):
189 """
190 Check if data is hexadecimal packed
191
192 :param data:
193 :return:
194 """
195 packed = False
196 if isinstance(data, bytes) and len(data) == 16 and b":" not in data:
197 try:
198 packed = bool(int(binascii.hexlify(data), 16))
199 except ValueError:
200 pass
201
202 return packed
203
204 @property
205 def scope(self):
206 """
207 Return scope of IPv6 address.
208
209 :return:
210 """
211 return self.__scope
212
213 def __str__(self):
214 return text_type(
215 self._string_from_ip_int(self._ip)
216 + ("%" + self.scope if self.scope is not None else "")
217 )
218
219
220 class IPv6InterfaceScoped(ipaddress.IPv6Interface, IPv6AddressScoped):
221 """
222 Update
223 """
224
225 def __init__(self, address):
226 if (
227 PY3
228 and isinstance(address, (bytes, int))
229 or not PY3
230 and isinstance(address, int)
231 ):
232 IPv6AddressScoped.__init__(self, address)
233 self.network = ipaddress.IPv6Network(self._ip)
234 self._prefixlen = self._max_prefixlen
235 return
236
237 addr = ipaddress._split_optional_netmask(address)
238 IPv6AddressScoped.__init__(self, addr[0])
239 self.network = ipaddress.IPv6Network(address, strict=False)
240 self.netmask = self.network.netmask
241 self._prefixlen = self.network._prefixlen
242 self.hostmask = self.network.hostmask
243
244
245 if ipaddress:
246 ipaddress.IPv6Address = IPv6AddressScoped
247 if sys.version_info.major == 2:
248 ipaddress.IPv6Interface = IPv6InterfaceScoped