From 7008a9ce0f26c9a60274545bed9e6144b532924f Mon Sep 17 00:00:00 2001 From: Ryan Kurtz Date: Fri, 10 Jul 2026 05:13:30 -0400 Subject: [PATCH] GP-7053: Adding Python typing_extensions module and using it in PyGhidra for deprecation --- Ghidra/Features/PyGhidra/Module.manifest | 1 + Ghidra/Features/PyGhidra/build.gradle | 1 + Ghidra/Features/PyGhidra/src/main/py/README.md | 2 ++ .../Features/PyGhidra/src/main/py/pyproject.toml | 1 + .../PyGhidra/src/main/py/src/pyghidra/core.py | 14 +++----------- gradle/support/fetchDependencies.gradle | 6 ++++++ 6 files changed, 14 insertions(+), 11 deletions(-) diff --git a/Ghidra/Features/PyGhidra/Module.manifest b/Ghidra/Features/PyGhidra/Module.manifest index a666b2e9ce..de34777963 100644 --- a/Ghidra/Features/PyGhidra/Module.manifest +++ b/Ghidra/Features/PyGhidra/Module.manifest @@ -23,3 +23,4 @@ MODULE FILE LICENSE: pypkg/dist/jpype1-1.5.2.tar.gz Apache License 2.0 MODULE FILE LICENSE: pypkg/dist/packaging-25.0-py3-none-any.whl Apache License 2.0 MODULE FILE LICENSE: pypkg/dist/setuptools-80.9.0-py3-none-any.whl MIT MODULE FILE LICENSE: pypkg/dist/wheel-0.45.1-py3-none-any.whl MIT +MODULE FILE LICENSE: pypkg/dist/typing_extensions-4.16.0-py3-none-any.whl Python Software Foundation License diff --git a/Ghidra/Features/PyGhidra/build.gradle b/Ghidra/Features/PyGhidra/build.gradle index 4b4fcfde10..41dd72e2c0 100644 --- a/Ghidra/Features/PyGhidra/build.gradle +++ b/Ghidra/Features/PyGhidra/build.gradle @@ -58,6 +58,7 @@ distributePyDep("jpype1-1.5.2.tar.gz") distributePyDep("packaging-25.0-py3-none-any.whl") distributePyDep("setuptools-80.9.0-py3-none-any.whl") distributePyDep("wheel-0.45.1-py3-none-any.whl") +distributePyDep("typing_extensions-4.16.0-py3-none-any.whl") // Install JPype into the development virtual environment task installJPype(type: Exec) { diff --git a/Ghidra/Features/PyGhidra/src/main/py/README.md b/Ghidra/Features/PyGhidra/src/main/py/README.md index 80ef3dee69..4c6f173e53 100644 --- a/Ghidra/Features/PyGhidra/src/main/py/README.md +++ b/Ghidra/Features/PyGhidra/src/main/py/README.md @@ -573,6 +573,8 @@ __3.2.0__ * When an uncaught `JException` occurs, PyGhidra will now output the full Java stack trace. * PyGhidra no longer swallows the original exception object generated by GhidraScripts. * PyGhidra now depends on `JPype >=1.5.2, != 1.6.0, != 1.7.0`. +* Using `typing_extensions` to properly deprecate [`pyghidra.open_program()`](#pyghidraopen_program) + and [`pyghidra.run_script()`](#pyghidrarun_script). __3.1.0__ * PyGhidra will now, by default, restore `sys.modules` to its prior state after a PyGhidra script is diff --git a/Ghidra/Features/PyGhidra/src/main/py/pyproject.toml b/Ghidra/Features/PyGhidra/src/main/py/pyproject.toml index 482967bbaf..0ac11bbf00 100644 --- a/Ghidra/Features/PyGhidra/src/main/py/pyproject.toml +++ b/Ghidra/Features/PyGhidra/src/main/py/pyproject.toml @@ -31,6 +31,7 @@ classifiers = [ ] dependencies = [ "Jpype1 >=1.5.2, !=1.6.0, !=1.7.0", + "typing_extensions ~=4.16", "packaging" ] diff --git a/Ghidra/Features/PyGhidra/src/main/py/src/pyghidra/core.py b/Ghidra/Features/PyGhidra/src/main/py/src/pyghidra/core.py index 81858670cc..44ac28f4bd 100644 --- a/Ghidra/Features/PyGhidra/src/main/py/src/pyghidra/core.py +++ b/Ghidra/Features/PyGhidra/src/main/py/src/pyghidra/core.py @@ -14,7 +14,7 @@ # limitations under the License. ## import contextlib -import warnings +from typing_extensions import deprecated from typing import Union, TYPE_CHECKING, Tuple, Generator, List, Optional from pyghidra.converters import * # pylint: disable=wildcard-import, unused-wildcard-import @@ -169,6 +169,7 @@ def _analyze_program(flat_api, program): @contextlib.contextmanager +@deprecated("open_program() is deprecated, use open_project() and program_context() or program_loader() instead.", stacklevel=3) def open_program( binary_path: Union[str, Path], project_location: Union[str, Path] = None, @@ -206,11 +207,6 @@ def open_program( :raises ValueError: If the provided language, compiler or loader is invalid. :raises TypeError: If the provided loader does not implement `ghidra.app.util.opinion.Loader`. """ - warnings.warn( - "open_program() is deprecated, use open_project() and program_context() or program_loader() instead.", - DeprecationWarning, - stacklevel=3 - ) from pyghidra.launcher import PyGhidraLauncher, HeadlessPyGhidraLauncher @@ -320,6 +316,7 @@ def _flat_api( # pylint: disable=too-many-arguments +@deprecated("run_script() is deprecated, use open_project() and ghidra_script() instead.", stacklevel=3) def run_script( binary_path: Optional[Union[str, Path]], script_path: Union[str, Path], @@ -367,11 +364,6 @@ def run_script( :raises ValueError: If the provided language, compiler or loader is invalid. :raises TypeError: If the provided loader does not implement `ghidra.app.util.opinion.Loader`. """ - warnings.warn( - "run_script() is deprecated, use open_project() and ghidra_script() instead.", - DeprecationWarning, - stacklevel=3 - ) script_path = str(script_path) args = binary_path, project_location, project_name, verbose, analyze, lang, compiler, loader, program_name, nested_project_location diff --git a/gradle/support/fetchDependencies.gradle b/gradle/support/fetchDependencies.gradle index ce3516ed6f..3b3dc94260 100644 --- a/gradle/support/fetchDependencies.gradle +++ b/gradle/support/fetchDependencies.gradle @@ -345,6 +345,12 @@ ext.deps = [ url: "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", sha256: "29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", destination: file("${DEPS_DIR}/PyGhidra/") + ], + [ + name: "typing_extensions-4.16.0-py3-none-any.whl", + url: "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", + sha256: "481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", + destination: file("${DEPS_DIR}/PyGhidra/") ], [ name: "jpype1-1.5.2-cp313-cp313-macosx_10_13_universal2.whl",