Skip to content

Commit 222ddd5

Browse files
authored
Merge pull request #16 from quarkslab/refactoring_types
Make static typing PEP-585 compliant. NFC.
2 parents eefc6ed + 39a67ad commit 222ddd5

File tree

8 files changed

+74
-60
lines changed

8 files changed

+74
-60
lines changed

src/binexport/basic_block.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1+
from __future__ import annotations
12
import weakref
23
from functools import cached_property
34
from typing import TYPE_CHECKING
45

56
from binexport.utils import instruction_index_range, get_instruction_address
67
from binexport.instruction import InstructionBinExport
7-
from binexport.types import Addr
88

99
if TYPE_CHECKING:
10-
from .program import ProgramBinExport
11-
from .function import FunctionBinExport
12-
from .binexport2_pb2 import BinExport2
10+
from binexport.program import ProgramBinExport
11+
from binexport.function import FunctionBinExport
12+
from binexport.binexport2_pb2 import BinExport2
13+
from binexport.types import Addr
1314

1415

1516
class BasicBlockBinExport:
@@ -19,9 +20,9 @@ class BasicBlockBinExport:
1920

2021
def __init__(
2122
self,
22-
program: weakref.ref["ProgramBinExport"],
23-
function: weakref.ref["FunctionBinExport"],
24-
pb_bb: "BinExport2.BasicBlock",
23+
program: weakref.ref[ProgramBinExport],
24+
function: weakref.ref[FunctionBinExport],
25+
pb_bb: BinExport2.BasicBlock,
2526
):
2627
"""
2728
:param program: Weak reference to the program
@@ -65,7 +66,7 @@ def __repr__(self) -> str:
6566
return "<%s:0x%x>" % (type(self).__name__, self.addr)
6667

6768
@property
68-
def program(self) -> "ProgramBinExport":
69+
def program(self) -> ProgramBinExport:
6970
"""
7071
Wrapper on weak reference on ProgramBinExport
7172
@@ -74,7 +75,7 @@ def program(self) -> "ProgramBinExport":
7475
return self._program()
7576

7677
@property
77-
def function(self) -> "FunctionBinExport":
78+
def function(self) -> FunctionBinExport:
7879
"""
7980
Wrapper on weak reference on FunctionBinExport
8081

src/binexport/expression.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from __future__ import annotations
22
import logging
33
from functools import cached_property
4-
from typing import TYPE_CHECKING, Optional
4+
from typing import TYPE_CHECKING
55

66
from binexport.binexport2_pb2 import BinExport2
77
from binexport.types import ExpressionType
@@ -54,9 +54,9 @@ class ExpressionBinExport:
5454

5555
def __init__(
5656
self,
57-
program: "ProgramBinExport",
58-
function: "FunctionBinExport",
59-
instruction: "InstructionBinExport",
57+
program: ProgramBinExport,
58+
function: FunctionBinExport,
59+
instruction: InstructionBinExport,
6060
exp_idx: int,
6161
parent: ExpressionBinExport | None = None,
6262
):
@@ -70,7 +70,7 @@ def __init__(
7070
"""
7171

7272
self._idx = exp_idx
73-
self.parent: Optional[ExpressionBinExport] = parent #: parent expression if nested
73+
self.parent: ExpressionBinExport | None = parent #: parent expression if nested
7474
self.is_addr: bool = False #: whether the value is referring to an address
7575
self.is_data: bool = False #: whether the value is a reference to data
7676

@@ -110,9 +110,9 @@ def depth(self) -> int:
110110

111111
def _parse_protobuf(
112112
self,
113-
program: "ProgramBinExport",
114-
function: "FunctionBinExport",
115-
instruction: "InstructionBinExport",
113+
program: ProgramBinExport,
114+
function: FunctionBinExport,
115+
instruction: InstructionBinExport,
116116
) -> None:
117117
"""
118118
Low-level expression parser. It populates self._type and self._value

src/binexport/function.py

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
1+
from __future__ import annotations
12
import logging
23
import weakref
34
import networkx
45
from functools import cached_property
5-
from typing import TYPE_CHECKING, Dict, Set
6+
from typing import TYPE_CHECKING
67

78
from binexport.utils import get_basic_block_addr
89
from binexport.basic_block import BasicBlockBinExport
9-
from binexport.types import FunctionType, Addr
10-
from collections import abc
10+
from binexport.types import FunctionType
1111

1212
if TYPE_CHECKING:
13-
from .program import ProgramBinExport
14-
from .binexport2_pb2 import BinExport2
13+
from collections import abc
14+
from binexport.program import ProgramBinExport
15+
from binexport.binexport2_pb2 import BinExport2
16+
from binexport.types import Addr
1517

1618

1719
class FunctionBinExport:
@@ -22,9 +24,9 @@ class FunctionBinExport:
2224

2325
def __init__(
2426
self,
25-
program: weakref.ref["ProgramBinExport"],
27+
program: weakref.ref[ProgramBinExport],
2628
*,
27-
pb_fun: "BinExport2.FlowGraph | None" = None,
29+
pb_fun: BinExport2.FlowGraph | None = None,
2830
is_import: bool = False,
2931
addr: Addr | None = None,
3032
):
@@ -40,8 +42,8 @@ def __init__(
4042
super(FunctionBinExport, self).__init__()
4143

4244
self.addr: Addr | None = addr #: address, None if imported function
43-
self.parents: Set["FunctionBinExport"] = set() #: set of function call this one
44-
self.children: Set["FunctionBinExport"] = set() #: set of functions called by this one
45+
self.parents: set[FunctionBinExport] = set() #: set of function call this one
46+
self.children: set[FunctionBinExport] = set() #: set of functions called by this one
4547

4648
# Private attributes
4749
self._graph = None # CFG. Loaded inside self.blocks
@@ -95,7 +97,7 @@ def unload(self) -> None:
9597
if self._enable_unloading:
9698
self._basic_blocks = None
9799

98-
def items(self) -> abc.ItemsView[Addr, "BasicBlockBinExport"]:
100+
def items(self) -> abc.ItemsView[Addr, BasicBlockBinExport]:
99101
"""
100102
Each function is associated to a dictionary with key-value
101103
Addr->BasicBlockBinExport. This returns items of the dictionary.
@@ -109,14 +111,14 @@ def keys(self) -> abc.KeysView[Addr]:
109111
"""
110112
return self.blocks.keys()
111113

112-
def values(self) -> abc.ValuesView["BasicBlockBinExport"]:
114+
def values(self) -> abc.ValuesView[BasicBlockBinExport]:
113115
"""
114116
Each function is associated to a dictionary with key-value : Addr, BasicBlockBinExport. This returns items
115117
of the dictionary.
116118
"""
117119
return self.blocks.values()
118120

119-
def __getitem__(self, item: Addr) -> "BasicBlockBinExport":
121+
def __getitem__(self, item: Addr) -> BasicBlockBinExport:
120122
"""
121123
Get a basic block object from its address.
122124
@@ -135,14 +137,14 @@ def __contains__(self, item: Addr) -> bool:
135137
return item in self.blocks
136138

137139
@property
138-
def program(self) -> "ProgramBinExport":
140+
def program(self) -> ProgramBinExport:
139141
"""
140142
:py:class:`ProgramBinExport` in which this function belongs to.
141143
"""
142144
return self._program()
143145

144146
@property
145-
def blocks(self) -> Dict[Addr, BasicBlockBinExport]:
147+
def blocks(self) -> dict[Addr, BasicBlockBinExport]:
146148
"""
147149
Returns a dict which is used to reference all basic blocks by their address.
148150
Calling this function will also load the CFG.

src/binexport/instruction.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1+
from __future__ import annotations
12
import weakref
23
from functools import cached_property
3-
from typing import TYPE_CHECKING, List, Set
4+
from typing import TYPE_CHECKING
45

56
from binexport.operand import OperandBinExport
6-
from binexport.types import Addr
77

88
if TYPE_CHECKING:
99
from .program import ProgramBinExport
1010
from .function import FunctionBinExport
1111
from .binexport2_pb2 import BinExport2
12+
from binexport.types import Addr
1213

1314

1415
class InstructionBinExport:
@@ -18,8 +19,8 @@ class InstructionBinExport:
1819

1920
def __init__(
2021
self,
21-
program: weakref.ref["ProgramBinExport"],
22-
function: weakref.ref["FunctionBinExport"],
22+
program: weakref.ref[ProgramBinExport],
23+
function: weakref.ref[FunctionBinExport],
2324
addr: Addr,
2425
i_idx: int,
2526
):
@@ -33,7 +34,7 @@ def __init__(
3334
self._program = program
3435
self._function = function
3536
self._idx = i_idx
36-
self.data_refs: Set[Addr] = self.program.data_refs[self._idx] #: Data references address
37+
self.data_refs: set[Addr] = self.program.data_refs[self._idx] #: Data references address
3738
self.bytes = self.pb_instr.raw_bytes #: bytes of the instruction (opcodes)
3839

3940
def __hash__(self) -> int:
@@ -46,14 +47,14 @@ def __repr__(self) -> str:
4647
return f"<{type(self).__name__} {self.addr:#08x}: {self.mnemonic} {', '.join(str(x) for x in self.operands)}>"
4748

4849
@property
49-
def program(self) -> "ProgramBinExport":
50+
def program(self) -> ProgramBinExport:
5051
"""
5152
Program associated with this instruction.
5253
"""
5354
return self._program()
5455

5556
@property
56-
def pb_instr(self) -> "BinExport2.Instruction":
57+
def pb_instr(self) -> BinExport2.Instruction:
5758
"""
5859
Protobuf instruction object.
5960
"""
@@ -67,7 +68,7 @@ def mnemonic(self) -> str:
6768
return self.program.proto.mnemonic[self.pb_instr.mnemonic_index].name
6869

6970
@cached_property
70-
def operands(self) -> List[OperandBinExport]:
71+
def operands(self) -> list[OperandBinExport]:
7172
"""
7273
Returns a list of the operands instanciated dynamically on-demand.
7374
The list is cached by default, to erase the cache delete the attribute.

src/binexport/operand.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import weakref
1+
from __future__ import annotations
22
from functools import cached_property
3-
from typing import TYPE_CHECKING, List
3+
from typing import TYPE_CHECKING
44

55
from binexport.expression import ExpressionBinExport
66
from binexport.types import ExpressionType
77

88
if TYPE_CHECKING:
9+
import weakref
910
from .program import ProgramBinExport
1011
from .function import FunctionBinExport
1112
from .instruction import InstructionBinExport
@@ -20,9 +21,9 @@ class OperandBinExport:
2021

2122
def __init__(
2223
self,
23-
program: weakref.ref["ProgramBinExport"],
24-
function: weakref.ref["FunctionBinExport"],
25-
instruction: weakref.ref["InstructionBinExport"],
24+
program: weakref.ref[ProgramBinExport],
25+
function: weakref.ref[FunctionBinExport],
26+
instruction: weakref.ref[InstructionBinExport],
2627
op_idx: int,
2728
):
2829
"""
@@ -86,36 +87,36 @@ def __repr__(self) -> str:
8687
return f"<{type(self).__name__} {str(self)}>"
8788

8889
@property
89-
def program(self) -> "ProgramBinExport":
90+
def program(self) -> ProgramBinExport:
9091
"""
9192
Program object associated to this operand.
9293
"""
9394
return self._program()
9495

9596
@property
96-
def function(self) -> "FunctionBinExport":
97+
def function(self) -> FunctionBinExport:
9798
"""
9899
Function object associated to this operand.
99100
"""
100101

101102
return self._function()
102103

103104
@property
104-
def instruction(self) -> "InstructionBinExport":
105+
def instruction(self) -> InstructionBinExport:
105106
"""
106107
Instruction object associated to this operand.
107108
"""
108109
return self._instruction()
109110

110111
@property
111-
def pb_operand(self) -> "BinExport2.Operand":
112+
def pb_operand(self) -> BinExport2.Operand:
112113
"""
113114
Protobuf operand object in the protobuf structure.
114115
"""
115116
return self.program.proto.operand[self._idx]
116117

117118
@cached_property
118-
def expressions(self) -> List[ExpressionBinExport]:
119+
def expressions(self) -> list[ExpressionBinExport]:
119120
"""
120121
Iterates over all the operand expression in a pre-order manner
121122
(binary operator first).

src/binexport/program.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
1+
from __future__ import annotations
12
import pathlib
23
import logging
34
import networkx
45
import weakref
56
from collections import defaultdict
6-
from typing import Dict, Set
7+
from typing import TYPE_CHECKING
78

89
from binexport.binexport2_pb2 import BinExport2
910
from binexport.function import FunctionBinExport
10-
from binexport.types import FunctionType, Addr
11+
from binexport.types import FunctionType
12+
13+
if TYPE_CHECKING:
14+
from binexport.types import Addr
1115

1216

1317
class ProgramBinExport(dict):
@@ -27,12 +31,12 @@ def __init__(self, file: pathlib.Path | str):
2731
with open(file, "rb") as f:
2832
self._pb.ParseFromString(f.read())
2933
self.mask = 0xFFFFFFFF if self.architecture.endswith("32") else 0xFFFFFFFFFFFFFFFF
30-
self.fun_names: Dict[str, "FunctionBinExport"] = {} #: dictionary function name -> name
34+
self.fun_names: dict[str, FunctionBinExport] = {} #: dictionary function name -> name
3135
self.callgraph: networkx.DiGraph = networkx.DiGraph() #: program callgraph (as Digraph)
3236

3337
# Make the data refs map {instruction index -> address referred}
3438
# dictionary of instruction index to set of refs
35-
self.data_refs: Dict[int, Set[Addr]] = defaultdict(set)
39+
self.data_refs: dict[int, set[Addr]] = defaultdict(set)
3640
for entry in self.proto.data_reference:
3741
self.data_refs[entry.instruction_index].add(entry.address)
3842

@@ -109,7 +113,7 @@ def from_binary_file(
109113
output_file: str | pathlib.Path = "",
110114
open_export: bool = True,
111115
override: bool = False,
112-
) -> "ProgramBinExport | bool":
116+
) -> ProgramBinExport | bool:
113117
"""
114118
Generate the .BinExport file for the given program and return an instance
115119
of ProgramBinExport.

src/binexport/types.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
from __future__ import annotations, absolute_import
1+
from __future__ import annotations
22
import enum
3-
from typing import TypeAlias
43
import enum_tools.documentation
4+
from typing import TypeAlias
55

66
from binexport.binexport2_pb2 import BinExport2
77

0 commit comments

Comments
 (0)