Skip to content

Commit f92bb71

Browse files
authored
Remove remaining legacy Python 2 code (#599)
* Replace OrderedDict with plain dict() <https://docs.python.org/3/library/collections.html#ordereddict-objects>: > Ordered dictionaries are just like regular dictionaries but have some > extra capabilities relating to ordering operations. They have become > less important now that the built-in dict class gained the ability to > remember insertion order (this new behavior became guaranteed in > Python 3.7). Signed-off-by: Philipp Hahn <[email protected]> * construct/lib/container: Remove unneeded methods `collections.abc.MutableMapping` already implements `keys()`, `update()`, `__eq__()`, `__ne__()` and `__contains__()` – most importantly correctly, e.g. `update()` has many variants which the current implementation does not handle. Signed-off-by: Philipp Hahn <[email protected]> * construct: Remove Python 2 compatibility layer Remove the compatibility layer `py3compat`. PS: There is #548 to migrate from the interned version of `construct` back to "Construct 2.10+" now that it is maintained again. When that happens, this change will become moot. Until then restore some sanity back into our copy as handling Python type annotations for both Python 2 and 3 is a major pain. Signed-off-by: Philipp Hahn <[email protected]> * Drop remaining Python 2 compatibility code Signed-off-by: Philipp Hahn <[email protected]> * Drop from __future__ import print_function The project is Python 3 only, so remove the legacy Python 2 compatibility. Signed-off-by: Philipp Hahn <[email protected]> * Replace `bytelist2string` with `bytes` The function was used in only one place. Just use the much more efficient `bytes(list[int])` to convert from `list[int]` to `bytes`. Signed-off-by: Philipp Hahn <[email protected]> --------- Signed-off-by: Philipp Hahn <[email protected]>
1 parent aad8631 commit f92bb71

32 files changed

+32
-184
lines changed

elftools/common/construct_utils.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,6 @@ def _sizeof(self, context):
4949

5050
class ULEB128(Construct):
5151
"""A construct based parser for ULEB128 encoding.
52-
53-
Incompatible with Python 2 - assumes that the return of read()
54-
is an indexed collection of numbers.
5552
"""
5653
def _parse(self, stream, context):
5754
value = 0
@@ -68,9 +65,6 @@ def _parse(self, stream, context):
6865

6966
class SLEB128(Construct):
7067
"""A construct based parser for SLEB128 encoding.
71-
72-
Incompatible with Python 2 - assumes that the return of read()
73-
is an indexed collection of numbers.
7468
"""
7569
def _parse(self, stream, context):
7670
value = 0

elftools/common/utils.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,6 @@ def bytes2str(b):
2323
"""Decode a bytes object into a string."""
2424
return b.decode('latin-1')
2525

26-
def bytelist2string(bytelist):
27-
""" Convert a list of byte values (e.g. [0x10 0x20 0x00]) to a bytes object
28-
(e.g. b'\x10\x20\x00').
29-
"""
30-
return b''.join(bytes((b,)) for b in bytelist)
31-
32-
3326
def struct_parse(struct, stream, stream_pos=None):
3427
""" Convenience function for using the given struct to parse a stream.
3528
If stream_pos is provided, the stream is seeked to this position before

elftools/construct/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
... )
2323
>>> s.parse("\\x01\\x02\\x03")
2424
Container(a = 1, b = 515)
25-
>>> print s.parse("\\x01\\x02\\x03")
25+
>>> print(s.parse("\\x01\\x02\\x03"))
2626
Container:
2727
a = 1
2828
b = 515

elftools/construct/adapters.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
from io import BytesIO
2+
13
from .core import Adapter, AdaptationError, Pass
24
from .lib import int_to_bin, bin_to_int, swap_bytes
35
from .lib import FlagsContainer, HexString
4-
from .lib.py3compat import BytesIO, decodebytes
56

67

78
#===============================================================================

elftools/construct/core.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
from io import BytesIO
12
from struct import Struct as Packer
23

3-
from .lib.py3compat import BytesIO, advance_iterator, bchr
44
from .lib import Container, ListContainer, LazyContainer
55

66

@@ -520,13 +520,13 @@ def _build(self, obj, stream, context):
520520
if self.subcon.conflags & self.FLAG_COPY_CONTEXT:
521521
for subobj in obj:
522522
if isinstance(obj, bytes):
523-
subobj = bchr(subobj)
523+
subobj = bytes((subobj,))
524524
self.subcon._build(subobj, stream, context.__copy__())
525525
cnt += 1
526526
else:
527527
for subobj in obj:
528528
if isinstance(obj, bytes):
529-
subobj = bchr(subobj)
529+
subobj = bytes((subobj,))
530530
self.subcon._build(subobj, stream, context)
531531
cnt += 1
532532
except ConstructError as ex:
@@ -587,7 +587,7 @@ def _build(self, obj, stream, context):
587587
break
588588
else:
589589
for subobj in obj:
590-
subobj = bchr(subobj)
590+
subobj = bytes((subobj,))
591591
self.subcon._build(subobj, stream, context.__copy__())
592592
if self.predicate(subobj, context):
593593
terminated = True
@@ -722,7 +722,7 @@ def _build(self, obj, stream, context):
722722
elif sc.name is None:
723723
subobj = None
724724
else:
725-
subobj = advance_iterator(objiter)
725+
subobj = next(objiter)
726726
context[sc.name] = subobj
727727
sc._build(subobj, stream, context)
728728

@@ -881,7 +881,7 @@ def _parse(self, stream, context):
881881
except ConstructError:
882882
stream.seek(pos)
883883
else:
884-
context.__update__(context2)
884+
context.update(context2)
885885
if self.include_name:
886886
return sc.name, obj
887887
else:
@@ -903,7 +903,7 @@ def _build(self, obj, stream, context):
903903
except Exception:
904904
pass
905905
else:
906-
context.__update__(context2)
906+
context.update(context2)
907907
stream.write(stream2.getvalue())
908908
return
909909
raise SelectError("no subconstruct matched", obj)

elftools/construct/debug.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
"""
22
Debugging utilities for constructs
33
"""
4-
from __future__ import print_function
54
import sys
65
import traceback
76
import pdb
@@ -81,7 +80,7 @@ def printout(self, stream, context):
8180
frames.reverse()
8281
for f in frames:
8382
a = Container()
84-
a.__update__(f.f_locals)
83+
a.update(f.f_locals)
8584
obj.stack.append(a)
8685

8786
print("=" * 80)

elftools/construct/lib/binary.py

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
from .py3compat import int2byte
2-
3-
41
def int_to_bin(number, width=32):
52
r"""
63
Convert an integer into its binary representation in a bytes object.
@@ -32,13 +29,6 @@ def int_to_bin(number, width=32):
3229
1: 1,
3330
48: 0, # '0'
3431
49: 1, # '1'
35-
36-
# The following are for Python 2, in which iteration over a bytes object
37-
# yields single-character bytes and not integers.
38-
'\x00': 0,
39-
'\x01': 1,
40-
'0': 0,
41-
'1': 1,
4232
}
4333

4434
def bin_to_int(bits, signed=False):
@@ -81,10 +71,8 @@ def swap_bytes(bits, bytesize=8):
8171
_char_to_bin = {}
8272
_bin_to_char = {}
8373
for i in range(256):
84-
ch = int2byte(i)
74+
ch = bytes((i,))
8575
bin = int_to_bin(i, 8)
86-
# Populate with for both keys i and ch, to support Python 2 & 3
87-
_char_to_bin[ch] = bin
8876
_char_to_bin[i] = bin
8977
_bin_to_char[bin] = ch
9078

@@ -94,15 +82,15 @@ def encode_bin(data):
9482
Create a binary representation of the given b'' object. Assume 8-bit
9583
ASCII. Example:
9684
97-
>>> encode_bin('ab')
85+
>>> encode_bin(b'ab')
9886
b"\x00\x01\x01\x00\x00\x00\x00\x01\x00\x01\x01\x00\x00\x00\x01\x00"
9987
"""
10088
return b"".join(_char_to_bin[ch] for ch in data)
10189

10290

10391
def decode_bin(data):
10492
"""
105-
Locical opposite of decode_bin.
93+
Logical opposite of decode_bin.
10694
"""
10795
if len(data) & 7:
10896
raise ValueError("Data length must be a multiple of 8")

elftools/construct/lib/container.py

Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
Various containers.
33
"""
44

5+
from collections.abc import MutableMapping
56
from pprint import pformat
6-
from .py3compat import MutableMapping
7+
78

89
def recursion_lock(retval, lock_name = "__recursion_lock__"):
910
def decorator(func):
@@ -40,45 +41,19 @@ def __delitem__(self, name):
4041
def __setitem__(self, name, value):
4142
self.__dict__[name] = value
4243

43-
def keys(self):
44-
return self.__dict__.keys()
44+
def __iter__(self):
45+
return iter(self.__dict__)
4546

4647
def __len__(self):
4748
return len(self.__dict__.keys())
4849

49-
# Extended dictionary interface.
50-
51-
def update(self, other):
52-
self.__dict__.update(other)
53-
54-
__update__ = update
55-
56-
def __contains__(self, value):
57-
return value in self.__dict__
58-
59-
# Rich comparisons.
60-
61-
def __eq__(self, other):
62-
try:
63-
return self.__dict__ == other.__dict__
64-
except AttributeError:
65-
return False
66-
67-
def __ne__(self, other):
68-
return not self == other
69-
7050
# Copy interface.
7151

7252
def copy(self):
7353
return self.__class__(**self.__dict__)
7454

7555
__copy__ = copy
7656

77-
# Iterator interface.
78-
79-
def __iter__(self):
80-
return iter(self.__dict__)
81-
8257
def __repr__(self):
8358
return "%s(%s)" % (self.__class__.__name__, repr(self.__dict__))
8459

elftools/construct/lib/hex.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
from .py3compat import byte2int, int2byte, bytes2str
2-
3-
41
# Map an integer in the inclusive range 0-255 to its string byte representation
52
_printable = dict((i, ".") for i in range(256))
6-
_printable.update((i, bytes2str(int2byte(i))) for i in range(32, 128))
3+
_printable.update((i, chr(i)) for i in range(32, 128))
74

85

96
def hexdump(data, linesize):
@@ -18,8 +15,8 @@ def hexdump(data, linesize):
1815
fmt = fmt % (3 * linesize - 1,)
1916
for i in range(0, len(data), linesize):
2017
line = data[i : i + linesize]
21-
hextext = " ".join('%02x' % byte2int(b) for b in line)
22-
rawtext = "".join(_printable[byte2int(b)] for b in line)
18+
hextext = " ".join('%02x' % b for b in line)
19+
rawtext = "".join(_printable[b] for b in line)
2320
prettylines.append(fmt % (i, str(hextext), str(rawtext)))
2421
return prettylines
2522

elftools/construct/lib/py3compat.py

Lines changed: 0 additions & 74 deletions
This file was deleted.

0 commit comments

Comments
 (0)