From cebf8e7274092ec2720c8395c55b67f7b25cf64a Mon Sep 17 00:00:00 2001 From: mr-tz Date: Mon, 21 Oct 2024 14:57:40 +0000 Subject: [PATCH] update minimum Python to 3.10 --- .devcontainer/Dockerfile | 2 +- .devcontainer/devcontainer.json | 2 +- .github/workflows/build.yml | 14 +++++--------- .github/workflows/tests.yml | 26 +++++++++++++------------- CHANGELOG.md | 2 ++ capa/ghidra/README.md | 2 +- capa/ghidra/capa_explorer.py | 8 ++------ capa/ghidra/capa_ghidra.py | 8 ++------ capa/helpers.py | 11 ----------- capa/ida/plugin/README.md | 5 +++-- capa/main.py | 20 ++++++-------------- requirements.txt | 2 +- 12 files changed, 37 insertions(+), 65 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 33398f53b..f7979e7f7 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,6 +1,6 @@ # See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.233.0/containers/python-3/.devcontainer/base.Dockerfile -# [Choice] Python version (use -bullseye variants on local arm64/Apple Silicon): 3, 3.10, 3.9, 3.8, 3.7, 3.6, 3-bullseye, 3.10-bullseye, 3.9-bullseye, 3.8-bullseye, 3.7-bullseye, 3.6-bullseye, 3-buster, 3.10-buster, 3.9-buster, 3.8-buster, 3.7-buster, 3.6-buster +# [Choice] Python version (use -bullseye variants on local arm64/Apple Silicon): 3, 3.10, 3-bullseye, 3.10-bullseye, 3-buster, 3.10-buster, etc. ARG VARIANT="3.10-bullseye" FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT} diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index c8444ed39..cbecb5603 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -6,7 +6,7 @@ "dockerfile": "Dockerfile", "context": "..", "args": { - // Update 'VARIANT' to pick a Python version: 3, 3.10, 3.9, 3.8, 3.7, 3.6 + // Update 'VARIANT' to pick a Python version: 3, 3.10, etc. // Append -bullseye or -buster to pin to an OS version. // Use -bullseye variants on local on arm64/Apple Silicon. "VARIANT": "3.10", diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0084f0993..f434ef0bc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,26 +21,25 @@ jobs: # set to false for debugging fail-fast: true matrix: - # using Python 3.8 to support running across multiple operating systems including Windows 7 include: - os: ubuntu-20.04 # use old linux so that the shared library versioning is more portable artifact_name: capa asset_name: linux - python_version: 3.8 + python_version: '3.10' - os: ubuntu-20.04 artifact_name: capa asset_name: linux-py312 - python_version: 3.12 + python_version: "3.12" - os: windows-2019 artifact_name: capa.exe asset_name: windows - python_version: 3.8 + python_version: '3.10' - os: macos-12 # use older macOS for assumed better portability artifact_name: capa asset_name: macos - python_version: 3.8 + python_version: '3.10' steps: - name: Checkout capa uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 @@ -86,9 +85,6 @@ jobs: - os: ubuntu-22.04 artifact_name: capa asset_name: linux - - os: ubuntu-22.04 - artifact_name: capa - asset_name: linux-py312 - os: windows-2022 artifact_name: capa.exe asset_name: windows @@ -107,7 +103,7 @@ jobs: # upload zipped binaries to Release page if: github.event_name == 'release' name: zip and upload ${{ matrix.asset_name }} - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 needs: [build] strategy: matrix: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9aa826ef0..92f3e35ca 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -26,7 +26,7 @@ env: jobs: changelog_format: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: Checkout capa uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 @@ -37,15 +37,15 @@ jobs: if [ $number != 1 ]; then exit 1; fi code_style: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: Checkout capa uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 # use latest available python to take advantage of best performance - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0 with: - python-version: "3.11" + python-version: "3.12" - name: Install dependencies run: | pip install -r requirements.txt @@ -64,16 +64,16 @@ jobs: run: pre-commit run deptry --hook-stage manual rule_linter: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: Checkout capa with submodules uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: submodules: recursive - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0 with: - python-version: "3.11" + python-version: "3.12" - name: Install capa run: | pip install -r requirements.txt @@ -90,15 +90,15 @@ jobs: matrix: os: [ubuntu-20.04, windows-2019, macos-12] # across all operating systems - python-version: ["3.8", "3.11"] + python-version: ["3.10", "3.11"] include: # on Ubuntu run these as well - os: ubuntu-20.04 - python-version: "3.8" + python-version: "3.10" - os: ubuntu-20.04 - python-version: "3.9" + python-version: "3.11" - os: ubuntu-20.04 - python-version: "3.10" + python-version: "3.12" steps: - name: Checkout capa with submodules uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 @@ -168,12 +168,12 @@ jobs: ghidra-tests: name: Ghidra tests for ${{ matrix.python-version }} - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 needs: [tests] strategy: fail-fast: false matrix: - python-version: ["3.8", "3.11"] + python-version: ["3.10", "3.11"] java-version: ["17"] ghidra-version: ["11.0.1"] public-version: ["PUBLIC_20240130"] # for ghidra releases diff --git a/CHANGELOG.md b/CHANGELOG.md index 54fcd9e1f..14841b60d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ ### Breaking Changes +- remove support for Python 3.8 and use Python 3.10 as minimum now #1966 @mr-tz + ### New Rules (0) - diff --git a/capa/ghidra/README.md b/capa/ghidra/README.md index 30a5695b7..b6596c577 100644 --- a/capa/ghidra/README.md +++ b/capa/ghidra/README.md @@ -55,7 +55,7 @@ You can also execute [capa_ghidra.py](https://raw.githubusercontent.com/mandiant | capa | `>= 7.0.0` | https://github.com/mandiant/capa/releases | | Ghidrathon | `>= 3.0.0` | https://github.com/mandiant/Ghidrathon/releases | | Ghidra | `>= 10.3.2` | https://github.com/NationalSecurityAgency/ghidra/releases | -| Python | `>= 3.8.0` | https://www.python.org/downloads | +| Python | `>= 3.10.0` | https://www.python.org/downloads | ## Installation diff --git a/capa/ghidra/capa_explorer.py b/capa/ghidra/capa_explorer.py index 4628b6752..efbfd0e3e 100644 --- a/capa/ghidra/capa_explorer.py +++ b/capa/ghidra/capa_explorer.py @@ -368,14 +368,10 @@ def main(): if __name__ == "__main__": - if sys.version_info < (3, 8): + if sys.version_info < (3, 10): from capa.exceptions import UnsupportedRuntimeError - raise UnsupportedRuntimeError("This version of capa can only be used with Python 3.8+") - elif sys.version_info < (3, 10): - from warnings import warn - - warn("This is the last capa version supporting Python 3.8 and 3.9.", DeprecationWarning, stacklevel=2) + raise UnsupportedRuntimeError("This version of capa can only be used with Python 3.10+") exit_code = main() if exit_code != 0: popup("capa explorer encountered errors during analysis. Please check the console output for more information.") # type: ignore [name-defined] # noqa: F821 diff --git a/capa/ghidra/capa_ghidra.py b/capa/ghidra/capa_ghidra.py index 817924930..db43ecfac 100644 --- a/capa/ghidra/capa_ghidra.py +++ b/capa/ghidra/capa_ghidra.py @@ -160,12 +160,8 @@ def main(): if __name__ == "__main__": - if sys.version_info < (3, 8): + if sys.version_info < (3, 10): from capa.exceptions import UnsupportedRuntimeError - raise UnsupportedRuntimeError("This version of capa can only be used with Python 3.8+") - elif sys.version_info < (3, 10): - from warnings import warn - - warn("This is the last capa version supporting Python 3.8 and 3.9.", DeprecationWarning, stacklevel=2) + raise UnsupportedRuntimeError("This version of capa can only be used with Python 3.10+") sys.exit(main()) diff --git a/capa/helpers.py b/capa/helpers.py index 4505647c4..70f1358c3 100644 --- a/capa/helpers.py +++ b/capa/helpers.py @@ -331,17 +331,6 @@ def log_unsupported_arch_error(): logger.error("-" * 80) -def log_unsupported_runtime_error(): - logger.error("-" * 80) - logger.error(" Unsupported runtime or Python interpreter.") - logger.error(" ") - logger.error(" capa supports running under Python 3.8 and higher.") - logger.error(" ") - logger.error(" If you're seeing this message on the command line,") - logger.error(" please ensure you're running a supported Python version.") - logger.error("-" * 80) - - def is_running_standalone() -> bool: """ are we running from a PyInstaller'd executable? diff --git a/capa/ida/plugin/README.md b/capa/ida/plugin/README.md index 0af39a4ad..e904b7adf 100644 --- a/capa/ida/plugin/README.md +++ b/capa/ida/plugin/README.md @@ -96,7 +96,7 @@ can update using the `Settings` button. ### Requirements -capa explorer supports Python versions >= 3.8.x and IDA Pro versions >= 7.4. The following IDA Pro versions have been tested: +capa explorer supports Python versions >= 3.10 and IDA Pro versions >= 7.4. The following IDA Pro versions have been tested: * IDA 7.4 * IDA 7.5 @@ -105,8 +105,9 @@ capa explorer supports Python versions >= 3.8.x and IDA Pro versions >= 7.4. The * IDA 8.0 * IDA 8.1 * IDA 8.2 +* IDA 9.0 -capa explorer is however limited to the Python versions supported by your IDA installation (which may not include all Python versions >= 3.8.x). +capa explorer is however limited to the Python versions supported by your IDA installation (which may not include all Python versions >= 3.10). If you encounter issues with your specific setup, please open a new [Issue](https://github.com/mandiant/capa/issues). diff --git a/capa/main.py b/capa/main.py index 60c5d638a..ca1434d50 100644 --- a/capa/main.py +++ b/capa/main.py @@ -185,15 +185,11 @@ def get_default_signatures() -> List[Path]: return ret -def simple_message_exception_handler(exctype, value: BaseException, traceback: TracebackType): +def simple_message_exception_handler( + exctype: type[BaseException], value: BaseException, traceback: TracebackType | None +): """ prints friendly message on unexpected exceptions to regular users (debug mode shows regular stack trace) - - args: - # TODO(aaronatp): Once capa drops support for Python 3.8, move the exctype type annotation to - # the function parameters and remove the "# type: ignore[assignment]" from the relevant place - # in the main function, see (https://github.com/mandiant/capa/issues/1896) - exctype (type[BaseException]): exception class """ if exctype is KeyboardInterrupt: @@ -455,7 +451,7 @@ def handle_common_args(args): raise RuntimeError("unexpected --color value: " + args.color) if not args.debug: - sys.excepthook = simple_message_exception_handler # type: ignore[assignment] + sys.excepthook = simple_message_exception_handler if hasattr(args, "input_file"): args.input_file = Path(args.input_file) @@ -901,12 +897,8 @@ def apply_extractor_filters(extractor: FeatureExtractor, extractor_filters: Filt def main(argv: Optional[List[str]] = None): - if sys.version_info < (3, 8): - raise UnsupportedRuntimeError("This version of capa can only be used with Python 3.8+") - elif sys.version_info < (3, 10): - from warnings import warn - - warn("This is the last capa version supporting Python 3.8 and 3.9.", DeprecationWarning, stacklevel=2) + if sys.version_info < (3, 10): + raise UnsupportedRuntimeError("This version of capa can only be used with Python 3.10+") if argv is None: argv = sys.argv[1:] diff --git a/requirements.txt b/requirements.txt index 7d7f10cca..7e6354282 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,7 +19,7 @@ intervaltree==3.1.0 markdown-it-py==3.0.0 mdurl==0.1.2 msgpack==1.0.8 -networkx==3.1 +networkx==3.4.2 pefile==2024.8.26 pip==24.2 protobuf==5.28.2