Skip to content

Commit dae5a01

Browse files
committed
Improve python api type hints
1 parent d4a7ed9 commit dae5a01

File tree

8 files changed

+69
-67
lines changed

8 files changed

+69
-67
lines changed

python/binaryview.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,12 @@
8080
from . import deprecation
8181
from . import typecontainer
8282
from . import externallibrary
83-
from . import project
8483
from . import undo
8584
from . import stringrecognizer
8685

8786

8887
PathType = Union[str, os.PathLike]
8988
InstructionsType = Generator[Tuple[List['_function.InstructionTextToken'], int], None, None]
90-
NotificationType = Mapping['BinaryDataNotification', 'BinaryDataNotificationCallbacks']
9189
ProgressFuncType = Callable[[int, int], bool]
9290
DataMatchCallbackType = Callable[[int, 'databuffer.DataBuffer'], bool]
9391
LineMatchCallbackType = Callable[[int, 'lineardisassembly.LinearDisassemblyLine'], bool]
@@ -127,10 +125,10 @@ def llil(self) -> Optional[lowlevelil.LowLevelILInstruction]:
127125
return self.function.get_low_level_il_at(self.address, self.arch)
128126

129127
@property
130-
def llils(self) -> Iterator[lowlevelil.LowLevelILInstruction]:
128+
def llils(self) -> List[lowlevelil.LowLevelILInstruction]:
131129
"""Returns the low level il instructions at the current location if any exists"""
132130
if self.function is None or self.arch is None:
133-
return
131+
return []
134132
return self.function.get_low_level_ils_at(self.address, self.arch)
135133

136134
@property
@@ -306,7 +304,7 @@ class BinaryDataNotification:
306304
>>>
307305
"""
308306

309-
def __init__(self, notifications: NotificationType = None):
307+
def __init__(self, notifications: Optional[NotificationType] = None):
310308
self.notifications = notifications
311309

312310
def notification_barrier(self, view: 'BinaryView') -> int:
@@ -826,7 +824,7 @@ def __init__(self, view: 'BinaryView', notify: 'BinaryDataNotification'):
826824
self._notify = notify
827825
self._cb = core.BNBinaryDataNotification()
828826
self._cb.context = 0
829-
if (not hasattr(notify, 'notifications')) or (hasattr(notify, 'notifications') and notify.notifications is None):
827+
if (not hasattr(notify, 'notifications')) or (notify.notifications is None):
830828
self._cb.notificationBarrier = self._cb.notificationBarrier
831829
self._cb.dataWritten = self._cb.dataWritten.__class__(self._data_written)
832830
self._cb.dataInserted = self._cb.dataInserted.__class__(self._data_inserted)
@@ -9369,7 +9367,7 @@ def find_next_constant(
93699367
return result.value
93709368

93719369
class QueueGenerator:
9372-
def __init__(self, t, results):
9370+
def __init__(self, t: threading.Thread, results: queue.Queue):
93739371
self.thread = t
93749372
self.results = results
93759373
t.start()
@@ -9388,7 +9386,7 @@ def __next__(self):
93889386
def find_all_data(
93899387
self, start: int, end: int, data: bytes, flags: FindFlag = FindFlag.FindCaseSensitive,
93909388
progress_func: Optional[ProgressFuncType] = None, match_callback: Optional[DataMatchCallbackType] = None
9391-
) -> QueueGenerator:
9389+
) -> Union[QueueGenerator, bool]:
93929390
"""
93939391
``find_all_data`` searches for the bytes ``data`` starting at the virtual address ``start``
93949392
until the virtual address ``end``. Once a match is found, the ``match_callback`` is called.
@@ -9464,7 +9462,7 @@ def find_all_text(
94649462
self, start: int, end: int, text: str, settings: Optional[_function.DisassemblySettings] = None,
94659463
flags=FindFlag.FindCaseSensitive, graph_type: _function.FunctionViewTypeOrName = FunctionGraphType.NormalFunctionGraph, progress_func=None,
94669464
match_callback=None
9467-
) -> QueueGenerator:
9465+
) -> Union[QueueGenerator, bool]:
94689466
"""
94699467
``find_all_text`` searches for string ``text`` occurring in the linear view output starting
94709468
at the virtual address ``start`` until the virtual address ``end``. Once a match is found,
@@ -9559,7 +9557,7 @@ def find_all_constant(
95599557
self, start: int, end: int, constant: int, settings: Optional[_function.DisassemblySettings] = None,
95609558
graph_type: _function.FunctionViewTypeOrName = FunctionGraphType.NormalFunctionGraph, progress_func: Optional[ProgressFuncType] = None,
95619559
match_callback: Optional[LineMatchCallbackType] = None
9562-
) -> QueueGenerator:
9560+
) -> Union[QueueGenerator, bool]:
95639561
"""
95649562
``find_all_constant`` searches for the integer constant ``constant`` starting at the
95659563
virtual address ``start`` until the virtual address ``end``. Once a match is found,
@@ -9632,8 +9630,8 @@ def find_all_constant(
96329630

96339631
return self.QueueGenerator(t, results)
96349632

9635-
def search(self, pattern: str, start: int = None, end: int = None, raw: bool = False, ignore_case: bool = False, overlap: bool = False, align: int = 1,
9636-
limit: int = None, progress_callback: Optional[ProgressFuncType] = None, match_callback: Optional[DataMatchCallbackType] = None) -> QueueGenerator:
9633+
def search(self, pattern: str, start: Optional[int] = None, end: Optional[int] = None, raw: bool = False, ignore_case: bool = False, overlap: bool = False, align: int = 1,
9634+
limit: Optional[int] = None, progress_callback: Optional[ProgressFuncType] = None, match_callback: Optional[DataMatchCallbackType] = None) -> QueueGenerator:
96379635
r"""
96389636
Searches for matches of the specified ``pattern`` within this BinaryView with an optionally provided address range specified by ``start`` and ``end``.
96399637
This is the API used by the advanced binary search UI option. The search pattern can be interpreted in various ways:
@@ -11355,7 +11353,10 @@ def value(self, data: Union[bytes, int, float]) -> None:
1135511353
if isinstance(self.type, (_types.IntegerType, _types.IntegerBuilder)):
1135611354
signed = bool(self.type.signed)
1135711355
to_write = data.to_bytes(len(self), TypedDataAccessor.byte_order(self.endian), signed=signed) # type: ignore
11358-
elif isinstance(data, float) and isinstance(self.type, (_types.FloatType, _types.FloatBuilder)):
11356+
elif isinstance(data, float):
11357+
if not isinstance(self.type, (_types.FloatType, _types.FloatBuilder)):
11358+
raise TypeError(f"Can't set the value of type {type(self.type)} to float value")
11359+
1135911360
endian = "<" if self.endian == Endianness.LittleEndian else ">"
1136011361
if self.type.width == 2:
1136111362
code = "e"

python/datarender.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import traceback
2222
import ctypes
23+
from typing import List, Optional
2324

2425
import binaryninja
2526
from . import _binaryninjacore as core
@@ -34,7 +35,7 @@
3435

3536

3637
class TypeContext:
37-
def __init__(self, _type, _offset):
38+
def __init__(self, _type: types.Type, _offset: int):
3839
self._type = _type
3940
self._offset = _offset
4041

@@ -85,7 +86,7 @@ def __del__(self):
8586
"""
8687
_registered_renderers = []
8788

88-
def __init__(self, context=None):
89+
def __init__(self, context: Optional[TypeContext] = None):
8990
self._cb = core.BNCustomDataRenderer()
9091
self._cb.context = context
9192
self._cb.freeObject = self._cb.freeObject.__class__(self._free_object)
@@ -137,7 +138,7 @@ def _get_lines_for_data(self, ctxt, view, addr, type, prefix, prefixCount, width
137138
type = types.Type.create(handle=core.BNNewTypeReference(type))
138139

139140
prefixTokens = function.InstructionTextToken._from_core_struct(prefix, prefixCount)
140-
pycontext = []
141+
pycontext: List[TypeContext] = []
141142
for i in range(ctxCount):
142143
pycontext.append(
143144
TypeContext(types.Type.create(core.BNNewTypeReference(typeCtx[i].type)), typeCtx[i].offset)
@@ -184,13 +185,13 @@ def _free_lines(self, ctxt, lines, count):
184185
def perform_free_object(self, ctxt):
185186
pass
186187

187-
def perform_is_valid_for_data(self, ctxt, view, addr, type, context):
188+
def perform_is_valid_for_data(self, ctxt, view: binaryview.BinaryView, addr: int, type: types.Type, context: List[TypeContext]) -> bool:
188189
return False
189190

190-
def perform_get_lines_for_data(self, ctxt, view, addr, type, prefix, width, context):
191+
def perform_get_lines_for_data(self, ctxt, view: binaryview.BinaryView, addr: int, type: types.Type, prefix: List[function.InstructionTextToken], width: int, context: List[TypeContext]) -> List['function.DisassemblyTextLine']:
191192
return []
192193

193-
def perform_get_lines_for_data_with_language(self, ctxt, view, addr, type, prefix, width, context, language):
194+
def perform_get_lines_for_data_with_language(self, ctxt, view: binaryview.BinaryView, addr: int, type: types.Type, prefix: List[function.InstructionTextToken], width: int, context: List[TypeContext], language: str) -> List['function.DisassemblyTextLine']:
194195
return self.perform_get_lines_for_data(ctxt, view, addr, type, prefix, width, context)
195196

196197
def __del__(self):

python/enterprise.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ class LicenseCheckout:
320320
"""
321321
Helper class for scripts to make use of a license checkout in a scope.
322322
323-
:param duration: Duration between refreshes
323+
:param duration: Duration in seconds between refreshes
324324
:param _cache: Deprecated but left in for compatibility
325325
:param release: If the license should be released at the end of scope. If `False`, you
326326
can either manually release it later or it will expire after `duration`.
@@ -334,11 +334,11 @@ class LicenseCheckout:
334334
... print(hex(bv.start))
335335
# License is released at end of scope
336336
"""
337-
def __init__(self, duration=900, _cache=True, release=True):
337+
def __init__(self, duration: int = 900, _cache: bool = True, release: bool = True):
338338
"""
339339
Get a new license checkout
340340
341-
:param duration: Duration between refreshes
341+
:param duration: Duration in seconds between refreshes
342342
:param _cache: Deprecated but left in for compatibility
343343
:param release: If the license should be released at the end of scope. If `False`, you
344344
can either manually release it later or it will expire after `duration`.

python/flowgraph.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import ctypes
2222
import threading
2323
import traceback
24-
from typing import List, Optional, Tuple
24+
from typing import List, Optional, Tuple, Union
2525

2626
# Binary Ninja components
2727
import binaryninja
@@ -41,7 +41,7 @@
4141

4242

4343
class FlowGraphEdge:
44-
def __init__(self, branch_type, source, target, points, back_edge, style):
44+
def __init__(self, branch_type: Union[BranchType, int], source: 'FlowGraphNode', target: 'FlowGraphNode', points: List[Tuple[float, float]], back_edge: bool, style: 'EdgeStyle'):
4545
self.type = BranchType(branch_type)
4646
self.source = source
4747
self.target = target
@@ -85,7 +85,7 @@ def __hash__(self):
8585

8686

8787
class FlowGraphNode:
88-
def __init__(self, graph=None, handle=None):
88+
def __init__(self, graph: Optional['FlowGraph'] = None, handle=None):
8989
_handle = handle
9090
if _handle is None:
9191
if graph is None:
@@ -343,7 +343,7 @@ def set_outgoing_edge_points(self, edge_num: int, points: List[Tuple[float, floa
343343

344344

345345
class FlowGraphLayoutRequest:
346-
def __init__(self, graph, callback=None):
346+
def __init__(self, graph: 'FlowGraph', callback=None):
347347
self.on_complete = callback
348348
self._cb = ctypes.CFUNCTYPE(None, ctypes.c_void_p)(self._complete)
349349
self.handle = core.BNStartFlowGraphLayout(graph.handle, None, self._cb)

0 commit comments

Comments
 (0)