From b965e693a061b13d8cea96f576c81095141ba97b Mon Sep 17 00:00:00 2001 From: Ryan Kurtz Date: Thu, 6 Feb 2025 10:13:42 -0500 Subject: [PATCH] GP-5345: New ghidra-stubs with README.md --- .../Doclets/support/GhidraStubs_README.md | 50 +++++++++++++++++++ GhidraBuild/BuildFiles/certification.manifest | 1 + gradle/root/distribution.gradle | 18 +++++++ 3 files changed, 69 insertions(+) create mode 100644 GhidraBuild/BuildFiles/Doclets/support/GhidraStubs_README.md diff --git a/GhidraBuild/BuildFiles/Doclets/support/GhidraStubs_README.md b/GhidraBuild/BuildFiles/Doclets/support/GhidraStubs_README.md new file mode 100644 index 0000000000..6a52612ef7 --- /dev/null +++ b/GhidraBuild/BuildFiles/Doclets/support/GhidraStubs_README.md @@ -0,0 +1,50 @@ +# Ghidra Type Stubs + +The Ghidra Type Stubs library is a [PEP 561 stubs package][pep-0561] for the +[Ghidra API](https://github.com/NationalSecurityAgency/ghidra). The stub files can be used to +improve your development experience in supported editors like PyCharm and Visual Studio Code. + +## Installation + +The stubs can be installed with `pip install ghidra-stubs*.whl` into the environment in which the +real Ghidra module (i.e., `pyghidra`) is available. Any conformant tool will then use the stubs +package for type analysis purposes. + +## Usage + +Once installed, all you need to do is import the Ghidra modules as usual, and your supported editor +will do the rest. + +```python +import pyghidra +``` + +To get support for the Ghidra builtins, you need to import them as well. The type hints for those +exist in the generated `ghidra_builtins` stub. Since it is not a real Python module, importing it at +runtime will fail. + +```python +try: + from ghidra.ghidra_builtins import * +except: + pass +``` + +If you are using [PyGhidra](https://pypi.org/project/pyghidra/) from a Python 3 environment where no +real `ghidra` module exists you can use a snippet like the following: + +```python +import typing +if typing.TYPE_CHECKING: + from ghidra.ghidra_builtins import * + +# actual code follows here +``` + +`typing.TYPE_CHECKING` is a special value that is always `False` at runtime but `True` during any +kind of type checking or completion. + +Once done, just code & enjoy. + +[pep-0484]: https://www.python.org/dev/peps/pep-0484/ +[pep-0561]: https://www.python.org/dev/peps/pep-0561/#stub-only-packages diff --git a/GhidraBuild/BuildFiles/certification.manifest b/GhidraBuild/BuildFiles/certification.manifest index f6ea90fba1..629e36af07 100644 --- a/GhidraBuild/BuildFiles/certification.manifest +++ b/GhidraBuild/BuildFiles/certification.manifest @@ -1,4 +1,5 @@ ##VERSION: 2.0 Doclets/Module.manifest||GHIDRA||||END| +Doclets/support/GhidraStubs_README.md||GHIDRA||||END| sleighDevBuild.template||GHIDRA||||END| sleighDistBuild.template||GHIDRA||||END| diff --git a/gradle/root/distribution.gradle b/gradle/root/distribution.gradle index 7ddf0673f7..b4ba1fcd49 100644 --- a/gradle/root/distribution.gradle +++ b/gradle/root/distribution.gradle @@ -246,6 +246,12 @@ task createGhidraStubsWheel { from(file("${ROOT_PROJECT_DIR}/LICENSE")) into typestubsDir } + + copy { + from("${ROOT_PROJECT_DIR}/GhidraBuild/BuildFiles/Doclets/support/GhidraStubs_README.md") + into typestubsDir + rename "GhidraStubs_README.md", "README.md" + } def manifest = file("${typestubsDir}/MANIFEST.in") manifest.write("graft src\n") @@ -259,10 +265,22 @@ task createGhidraStubsWheel { [project] name = "ghidra-stubs" version = "${project.version}" + dynamic = ["readme"] + description = "Ghidra Type Stubs" + license = {text = "Apache-2.0"} + maintainers = [ + {name = "Ghidra Development Team"}, + ] + keywords = [ + "ghidra", + ] classifiers = [ "License :: OSI Approved :: Apache Software License", "Typing :: Stubs Only", ] + + [tool.setuptools.dynamic] + readme = {file = ["README.md"], content-type = "text/markdown"} """.stripIndent() ) }