diff options
| author | Peter LaFosse <peter@vector35.com> | 2025-11-20 09:58:28 -0500 |
|---|---|---|
| committer | Peter LaFosse <peter@vector35.com> | 2025-11-21 10:02:50 -0500 |
| commit | 5880769cbac1362aad46a34faec4c553fa9fcac6 (patch) | |
| tree | 02db205b7aa915900cbfc10384940b3750eb7d69 /python | |
| parent | f52693d50de6a5c97afa0274277edca18cfa00ea (diff) | |
Add get and __contains__ methods to all *MetaClass
Fixes: https://github.com/Vector35/binaryninja-api/issues/7588
Diffstat (limited to 'python')
| -rw-r--r-- | python/architecture.py | 19 | ||||
| -rw-r--r-- | python/binaryview.py | 17 | ||||
| -rw-r--r-- | python/constantrenderer.py | 19 | ||||
| -rw-r--r-- | python/debuginfo.py | 19 | ||||
| -rw-r--r-- | python/demangle.py | 19 | ||||
| -rw-r--r-- | python/downloadprovider.py | 18 | ||||
| -rw-r--r-- | python/languagerepresentation.py | 19 | ||||
| -rw-r--r-- | python/lineformatter.py | 19 | ||||
| -rw-r--r-- | python/platform.py | 19 | ||||
| -rw-r--r-- | python/renderlayer.py | 19 | ||||
| -rw-r--r-- | python/scriptingprovider.py | 17 | ||||
| -rw-r--r-- | python/secretsprovider.py | 18 | ||||
| -rw-r--r-- | python/stringrecognizer.py | 36 | ||||
| -rw-r--r-- | python/transform.py | 19 | ||||
| -rw-r--r-- | python/typeparser.py | 19 | ||||
| -rw-r--r-- | python/typeprinter.py | 19 | ||||
| -rw-r--r-- | python/update.py | 18 | ||||
| -rw-r--r-- | python/websocketprovider.py | 18 | ||||
| -rw-r--r-- | python/workflow.py | 17 |
19 files changed, 356 insertions, 12 deletions
diff --git a/python/architecture.py b/python/architecture.py index 278b3317..734864a4 100644 --- a/python/architecture.py +++ b/python/architecture.py @@ -20,7 +20,7 @@ import traceback import ctypes -from typing import Generator, Union, List, Optional, Mapping, Tuple, NewType, Dict, Set +from typing import Generator, Union, List, Optional, Mapping, Tuple, NewType, Dict, Set, Any from dataclasses import dataclass, field # Binary Ninja components @@ -514,6 +514,23 @@ class _ArchitectureMetaClass(type): raise KeyError(f"'{name}' is not a valid architecture") return CoreArchitecture._from_cache(arch) + def __contains__(cls: '_ArchitectureMetaClass', name: object) -> bool: + if not isinstance(name, str): + return False + try: + cls[name] + return True + except KeyError: + return False + + def get(cls: '_ArchitectureMetaClass', name: str, default: Any = None) -> Optional['Architecture']: + try: + return cls[name] + except KeyError: + if default is not None: + return default + return None + class Architecture(metaclass=_ArchitectureMetaClass): """ diff --git a/python/binaryview.py b/python/binaryview.py index 5c49a697..d0d20405 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -1448,6 +1448,23 @@ class _BinaryViewTypeMetaclass(type): raise KeyError(f"'{value}' is not a valid view type") return BinaryViewType(view_type) + def __contains__(cls: '_BinaryViewTypeMetaclass', name: object) -> bool: + if not isinstance(name, str): + return False + try: + cls[name] + return True + except KeyError: + return False + + def get(cls: '_BinaryViewTypeMetaclass', name: str, default: Any = None) -> Optional['BinaryViewType']: + try: + return cls[name] + except KeyError: + if default is not None: + return default + return None + class BinaryViewType(metaclass=_BinaryViewTypeMetaclass): """ diff --git a/python/constantrenderer.py b/python/constantrenderer.py index 7f4c251c..a0c2c98c 100644 --- a/python/constantrenderer.py +++ b/python/constantrenderer.py @@ -20,7 +20,7 @@ import traceback import ctypes -from typing import Optional +from typing import Optional, Any import binaryninja from . import _binaryninjacore as core @@ -51,6 +51,23 @@ class _ConstantRendererMetaClass(type): raise KeyError("'%s' is not a valid renderer" % str(value)) return CoreConstantRenderer(handle=renderer) + def __contains__(cls: '_ConstantRendererMetaClass', name: object) -> bool: + if not isinstance(name, str): + return False + try: + cls[name] + return True + except KeyError: + return False + + def get(cls: '_ConstantRendererMetaClass', name: str, default: Any = None) -> Optional['ConstantRenderer']: + try: + return cls[name] + except KeyError: + if default is not None: + return default + return None + class ConstantRenderer(metaclass=_ConstantRendererMetaClass): """ diff --git a/python/debuginfo.py b/python/debuginfo.py index a76a8a6c..0b20ad69 100644 --- a/python/debuginfo.py +++ b/python/debuginfo.py @@ -19,7 +19,7 @@ # IN THE SOFTWARE. import ctypes -from typing import Optional, List, Iterator, Callable, Tuple +from typing import Optional, List, Iterator, Callable, Tuple, Any import traceback from dataclasses import dataclass, field @@ -78,6 +78,23 @@ class _DebugInfoParserMetaClass(type): assert parser_ref is not None, "core.BNNewDebugInfoParserReference returned None" return DebugInfoParser(parser_ref) + def __contains__(cls: '_DebugInfoParserMetaClass', name: object) -> bool: + if not isinstance(name, str): + return False + try: + cls[name] + return True + except KeyError: + return False + + def get(cls: '_DebugInfoParserMetaClass', name: str, default: Any = None) -> Optional['DebugInfoParser']: + try: + return cls[name] + except KeyError: + if default is not None: + return default + return None + @staticmethod def get_parsers_for_view(view: 'binaryview.BinaryView') -> List['DebugInfoParser']: """Returns a list of debug-info parsers that are valid for the provided binary view""" diff --git a/python/demangle.py b/python/demangle.py index e4f81678..3bceeb7a 100644 --- a/python/demangle.py +++ b/python/demangle.py @@ -29,7 +29,7 @@ from . import types from .log import log_error_for_exception from .architecture import Architecture, CoreArchitecture from .platform import Platform -from typing import Iterable, List, Optional, Union, Tuple +from typing import Iterable, List, Optional, Union, Tuple, Any def get_qualified_name(names: Iterable[str]): @@ -300,6 +300,23 @@ class _DemanglerMetaclass(type): raise KeyError(f"'{value}' is not a valid Demangler") return CoreDemangler(handle) + def __contains__(cls: '_DemanglerMetaclass', name: object) -> bool: + if not isinstance(name, str): + return False + try: + cls[name] + return True + except KeyError: + return False + + def get(cls: '_DemanglerMetaclass', name: str, default: Any = None) -> Optional['Demangler']: + try: + return cls[name] + except KeyError: + if default is not None: + return default + return None + class Demangler(metaclass=_DemanglerMetaclass): """ diff --git a/python/downloadprovider.py b/python/downloadprovider.py index 2fd94ac3..a1ff94bf 100644 --- a/python/downloadprovider.py +++ b/python/downloadprovider.py @@ -23,6 +23,7 @@ import ctypes from json import dumps import sys import traceback +from typing import Any, Optional from urllib.parse import urlencode # Binary Ninja Components @@ -269,6 +270,23 @@ class _DownloadProviderMetaclass(type): raise KeyError(f"'{value}' is not a valid download provider") return DownloadProvider(provider) + def __contains__(cls: '_DownloadProviderMetaclass', name: object) -> bool: + if not isinstance(name, str): + return False + try: + cls[name] + return True + except KeyError: + return False + + def get(cls: '_DownloadProviderMetaclass', name: str, default: Any = None) -> Optional['DownloadProvider']: + try: + return cls[name] + except KeyError: + if default is not None: + return default + return None + class DownloadProvider(metaclass=_DownloadProviderMetaclass): name = None diff --git a/python/languagerepresentation.py b/python/languagerepresentation.py index b7dc840d..ba5c44d0 100644 --- a/python/languagerepresentation.py +++ b/python/languagerepresentation.py @@ -20,7 +20,7 @@ import ctypes import traceback -from typing import List, Optional, Union +from typing import List, Optional, Union, Any # Binary Ninja components import binaryninja @@ -664,6 +664,23 @@ class _LanguageRepresentationFunctionTypeMetaClass(type): raise KeyError("'%s' is not a valid language" % str(value)) return CoreLanguageRepresentationFunctionType(handle=lang) + def __contains__(cls: '_LanguageRepresentationFunctionTypeMetaClass', name: object) -> bool: + if not isinstance(name, str): + return False + try: + cls[name] + return True + except KeyError: + return False + + def get(cls: '_LanguageRepresentationFunctionTypeMetaClass', name: str, default: Any = None) -> Optional['LanguageRepresentationFunctionType']: + try: + return cls[name] + except KeyError: + if default is not None: + return default + return None + class LanguageRepresentationFunctionType(metaclass=_LanguageRepresentationFunctionTypeMetaClass): """ diff --git a/python/lineformatter.py b/python/lineformatter.py index 7f74572b..f63526f1 100644 --- a/python/lineformatter.py +++ b/python/lineformatter.py @@ -21,7 +21,7 @@ import ctypes import traceback from dataclasses import dataclass -from typing import List, Optional, Union +from typing import List, Optional, Union, Any # Binary Ninja components import binaryninja @@ -118,6 +118,23 @@ class _LineFormatterMetaClass(type): raise KeyError("'%s' is not a valid formatter" % str(value)) return CoreLineFormatter(handle=lang) + def __contains__(cls: '_LineFormatterMetaClass', name: object) -> bool: + if not isinstance(name, str): + return False + try: + cls[name] + return True + except KeyError: + return False + + def get(cls: '_LineFormatterMetaClass', name: str, default: Any = None) -> Optional['LineFormatter']: + try: + return cls[name] + except KeyError: + if default is not None: + return default + return None + class LineFormatter(metaclass=_LineFormatterMetaClass): """ diff --git a/python/platform.py b/python/platform.py index 98f3109a..4ecd57af 100644 --- a/python/platform.py +++ b/python/platform.py @@ -22,7 +22,7 @@ import os import ctypes import traceback import warnings -from typing import List, Dict, Optional, Tuple +from typing import List, Dict, Optional, Tuple, Any # Binary Ninja components import binaryninja @@ -56,6 +56,23 @@ class _PlatformMetaClass(type): raise KeyError("'%s' is not a valid platform" % str(value)) return CorePlatform(handle=platform) + def __contains__(cls: '_PlatformMetaClass', name: object) -> bool: + if not isinstance(name, str): + return False + try: + cls[name] + return True + except KeyError: + return False + + def get(cls: '_PlatformMetaClass', name: str, default: Any = None) -> Optional['Platform']: + try: + return cls[name] + except KeyError: + if default is not None: + return default + return None + class Platform(metaclass=_PlatformMetaClass): """ diff --git a/python/renderlayer.py b/python/renderlayer.py index 0570ac3f..3731684d 100644 --- a/python/renderlayer.py +++ b/python/renderlayer.py @@ -28,7 +28,7 @@ from .enums import LinearDisassemblyLineType, RenderLayerDefaultEnableState from . import binaryview from . import types from .log import log_error_for_exception -from typing import Iterable, List, Optional, Union, Tuple +from typing import Iterable, List, Optional, Union, Tuple, Any class _RenderLayerMetaclass(type): @@ -49,6 +49,23 @@ class _RenderLayerMetaclass(type): raise KeyError(f"'{value}' is not a valid RenderLayer") return self._handle_to_instance(handle) + def __contains__(cls: '_RenderLayerMetaclass', name: object) -> bool: + if not isinstance(name, str): + return False + try: + cls[name] + return True + except KeyError: + return False + + def get(cls: '_RenderLayerMetaclass', name: str, default: Any = None) -> Optional['RenderLayer']: + try: + return cls[name] + except KeyError: + if default is not None: + return default + return None + def _handle_to_instance(self, handle): handle_ptr = ctypes.cast(handle, ctypes.c_void_p) if handle_ptr.value in RenderLayer._registered_instances: diff --git a/python/scriptingprovider.py b/python/scriptingprovider.py index 41b7d8d7..a3a01ce7 100644 --- a/python/scriptingprovider.py +++ b/python/scriptingprovider.py @@ -399,6 +399,23 @@ class _ScriptingProviderMetaclass(type): raise KeyError("'%s' is not a valid scripting provider" % str(value)) return ScriptingProvider(provider) + def __contains__(cls: '_ScriptingProviderMetaclass', name: object) -> bool: + if not isinstance(name, str): + return False + try: + cls[name] + return True + except KeyError: + return False + + def get(cls: '_ScriptingProviderMetaclass', name: str, default: Any = None) -> Optional['ScriptingProvider']: + try: + return cls[name] + except KeyError: + if default is not None: + return default + return None + class ScriptingProvider(metaclass=_ScriptingProviderMetaclass): _registered_providers = [] diff --git a/python/secretsprovider.py b/python/secretsprovider.py index d6815ae6..779b04fa 100644 --- a/python/secretsprovider.py +++ b/python/secretsprovider.py @@ -23,6 +23,7 @@ import ctypes from json import dumps import sys import traceback +from typing import Any, Optional from urllib.parse import urlencode # Binary Ninja Components @@ -58,6 +59,23 @@ class _SecretsProviderMetaclass(type): raise KeyError(f"'{value}' is not a valid secrets provider") return SecretsProvider(provider) + def __contains__(cls: '_SecretsProviderMetaclass', name: object) -> bool: + if not isinstance(name, str): + return False + try: + cls[name] + return True + except KeyError: + return False + + def get(cls: '_SecretsProviderMetaclass', name: str, default: Any = None) -> Optional['SecretsProvider']: + try: + return cls[name] + except KeyError: + if default is not None: + return default + return None + class SecretsProvider(metaclass=_SecretsProviderMetaclass): name = None diff --git a/python/stringrecognizer.py b/python/stringrecognizer.py index 004a58c4..3e6167a0 100644 --- a/python/stringrecognizer.py +++ b/python/stringrecognizer.py @@ -18,7 +18,7 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. -from typing import Optional, Union +from typing import Optional, Union, Any from dataclasses import dataclass import ctypes @@ -49,6 +49,23 @@ class _CustomStringTypeMetaClass(type): raise KeyError("'%s' is not a valid type" % str(value)) return CustomStringType(handle=string_type) + def __contains__(cls: '_CustomStringTypeMetaClass', name: object) -> bool: + if not isinstance(name, str): + return False + try: + cls[name] + return True + except KeyError: + return False + + def get(cls: '_CustomStringTypeMetaClass', name: str, default: Any = None) -> Optional['CustomStringType']: + try: + return cls[name] + except KeyError: + if default is not None: + return default + return None + class CustomStringType(metaclass=_CustomStringTypeMetaClass): """ @@ -125,6 +142,23 @@ class _StringRecognizerMetaClass(type): raise KeyError("'%s' is not a valid recognizer" % str(value)) return CoreStringRecognizer(handle=recognizer) + def __contains__(cls: '_StringRecognizerMetaClass', name: object) -> bool: + if not isinstance(name, str): + return False + try: + cls[name] + return True + except KeyError: + return False + + def get(cls: '_StringRecognizerMetaClass', name: str, default: Any = None) -> Optional['StringRecognizer']: + try: + return cls[name] + except KeyError: + if default is not None: + return default + return None + class StringRecognizer(metaclass=_StringRecognizerMetaClass): """ diff --git a/python/transform.py b/python/transform.py index 9512b24b..b647a8a9 100644 --- a/python/transform.py +++ b/python/transform.py @@ -23,7 +23,7 @@ import ctypes import abc import io import zipfile -from typing import List, Optional, Union +from typing import List, Optional, Union, Any # Binary Ninja components import binaryninja @@ -58,6 +58,23 @@ class _TransformMetaClass(type): raise KeyError("'%s' is not a valid transform" % str(name)) return Transform(xform) + def __contains__(cls: '_TransformMetaClass', name: object) -> bool: + if not isinstance(name, str): + return False + try: + cls[name] + return True + except KeyError: + return False + + def get(cls: '_TransformMetaClass', name: str, default: Any = None) -> Optional['Transform']: + try: + return cls[name] + except KeyError: + if default is not None: + return default + return None + class TransformParameter: def __init__(self, name, long_name=None, fixed_length=0): diff --git a/python/typeparser.py b/python/typeparser.py index e44d13b5..5cbcd53c 100644 --- a/python/typeparser.py +++ b/python/typeparser.py @@ -22,7 +22,7 @@ import abc import ctypes import dataclasses from json import dumps -from typing import List, Tuple, Optional, Dict +from typing import List, Tuple, Optional, Dict, Any import sys import traceback @@ -200,6 +200,23 @@ class _TypeParserMetaclass(type): raise KeyError(f"'{value}' is not a valid TypeParser") return CoreTypeParser(handle) + def __contains__(cls: '_TypeParserMetaclass', name: object) -> bool: + if not isinstance(name, str): + return False + try: + cls[name] + return True + except KeyError: + return False + + def get(cls: '_TypeParserMetaclass', name: str, default: Any = None) -> Optional['TypeParser']: + try: + return cls[name] + except KeyError: + if default is not None: + return default + return None + @property def default(self): """ diff --git a/python/typeprinter.py b/python/typeprinter.py index be885c07..091cd803 100644 --- a/python/typeprinter.py +++ b/python/typeprinter.py @@ -21,7 +21,7 @@ import abc import ctypes import dataclasses from json import dumps -from typing import List, Tuple, Optional +from typing import List, Tuple, Optional, Any import sys import traceback @@ -66,6 +66,23 @@ class _TypePrinterMetaclass(type): raise KeyError(f"'{value}' is not a valid TypePrinter") return CoreTypePrinter(handle) + def __contains__(cls: '_TypePrinterMetaclass', name: object) -> bool: + if not isinstance(name, str): + return False + try: + cls[name] + return True + except KeyError: + return False + + def get(cls: '_TypePrinterMetaclass', name: str, default: Any = None) -> Optional['TypePrinter']: + try: + return cls[name] + except KeyError: + if default is not None: + return default + return None + @property def default(self): name = binaryninja.Settings().get_string("analysis.types.printerName") diff --git a/python/update.py b/python/update.py index 308094f7..f88770fd 100644 --- a/python/update.py +++ b/python/update.py @@ -20,6 +20,7 @@ import traceback import ctypes +from typing import Any, Optional # Binary Ninja components import binaryninja @@ -65,6 +66,23 @@ class _UpdateChannelMetaClass(type): raise KeyError("'%s' is not a valid channel" % str(name)) return result + def __contains__(cls: '_UpdateChannelMetaClass', name: object) -> bool: + if not isinstance(name, str): + return False + try: + cls[name] + return True + except KeyError: + return False + + def get(cls: '_UpdateChannelMetaClass', name: str, default: Any = None) -> Optional['UpdateChannel']: + try: + return cls[name] + except KeyError: + if default is not None: + return default + return None + class UpdateProgressCallback: def __init__(self, func): diff --git a/python/websocketprovider.py b/python/websocketprovider.py index 0d77ae0b..f990d859 100644 --- a/python/websocketprovider.py +++ b/python/websocketprovider.py @@ -22,6 +22,7 @@ import abc import ctypes import sys import traceback +from typing import Any, Optional # Binary Ninja Components import binaryninja._binaryninjacore as core @@ -249,6 +250,23 @@ class _WebsocketProviderMetaclass(type): raise KeyError("'%s' is not a valid websocket provider" % str(value)) return WebsocketProvider(provider) + def __contains__(cls: '_WebsocketProviderMetaclass', name: object) -> bool: + if not isinstance(name, str): + return False + try: + cls[name] + return True + except KeyError: + return False + + def get(cls: '_WebsocketProviderMetaclass', name: str, default: Any = None) -> Optional['WebsocketProvider']: + try: + return cls[name] + except KeyError: + if default is not None: + return default + return None + def __setattr__(self, name, value): try: type.__setattr__(self, name, value) diff --git a/python/workflow.py b/python/workflow.py index 901a7cf9..6f3b2dd8 100644 --- a/python/workflow.py +++ b/python/workflow.py @@ -291,6 +291,23 @@ class _WorkflowMetaclass(type): workflow = core.BNWorkflowGetOrCreate(str(value)) return Workflow(handle=workflow) + def __contains__(cls: '_WorkflowMetaclass', name: object) -> bool: + if not isinstance(name, str): + return False + try: + cls[name] + return True + except KeyError: + return False + + def get(cls: '_WorkflowMetaclass', name: str, default: Any = None) -> Optional['Workflow']: + try: + return cls[name] + except KeyError: + if default is not None: + return default + return None + class Workflow(metaclass=_WorkflowMetaclass): """ |
