Officially remove Python 2 support from this point forward
[pyelftools.git] / elftools / common / py3compat.py
1 #-------------------------------------------------------------------------------
2 # elftools: common/py3compat.py
3 #
4 # Python 2/3 compatibility code
5 #
6 # Eli Bendersky (eliben@gmail.com)
7 # This code is in the public domain
8 #-------------------------------------------------------------------------------
9 import sys
10 PY3 = sys.version_info[0] == 3
11 assert PY3, '''\
12 Python 2 is no longer supported by pyelftools; if you need to use Python 2,
13 please download an older pyelftools version (such as version 0.29).
14 '''
15
16
17 if PY3:
18 import io
19 from pathlib import Path
20
21 StringIO = io.StringIO
22 BytesIO = io.BytesIO
23
24 # Functions for acting on bytestrings and strings. In Python 2 and 3,
25 # strings and bytes are the same and chr/ord can be used to convert between
26 # numeric byte values and their string representations. In Python 3, bytes
27 # and strings are different types and bytes hold numeric values when
28 # iterated over.
29
30 def bytes2hex(b, sep=''):
31 if not sep:
32 return b.hex()
33 return sep.join(map('{:02x}'.format, b))
34
35 def bytes2str(b): return b.decode('latin-1')
36 def str2bytes(s): return s.encode('latin-1')
37 def int2byte(i): return bytes((i,))
38 def byte2int(b): return b
39
40 def iterbytes(b):
41 """Return an iterator over the elements of a bytes object.
42
43 For example, for b'abc' yields b'a', b'b' and then b'c'.
44 """
45 for i in range(len(b)):
46 yield b[i:i+1]
47
48 ifilter = filter
49
50 maxint = sys.maxsize
51
52 def path_to_posix(s):
53 return Path(s).as_posix()
54
55 else:
56 import cStringIO
57 import os
58 import posixpath
59
60 StringIO = BytesIO = cStringIO.StringIO
61
62 def bytes2hex(b, sep=''):
63 res = b.encode('hex')
64 if not sep:
65 return res
66 return sep.join(res[i:i+2] for i in range(0, len(res), 2))
67
68 def bytes2str(b): return b
69 def str2bytes(s): return s
70 int2byte = chr
71 byte2int = ord
72 def iterbytes(b):
73 return iter(b)
74
75 from itertools import ifilter
76
77 maxint = sys.maxint
78
79 def path_to_posix(s):
80 return posixpath.join(*os.path.split(s))
81
82
83 def iterkeys(d):
84 """Return an iterator over the keys of a dictionary."""
85 return getattr(d, 'keys' if PY3 else 'iterkeys')()
86
87 def itervalues(d):
88 """Return an iterator over the values of a dictionary."""
89 return getattr(d, 'values' if PY3 else 'itervalues')()
90
91 def iteritems(d):
92 """Return an iterator over the items of a dictionary."""
93 return getattr(d, 'items' if PY3 else 'iteritems')()
94
95 try:
96 from collections.abc import Mapping # python >= 3.3
97 except ImportError:
98 from collections import Mapping # python < 3.3