diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6dca59bac..afead5336 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,7 +26,7 @@ jobs: fail-fast: false matrix: os: ["ubuntu-latest", "windows-2022"] - python: ${{ (github.event_name == 'pull_request' && fromJSON('["3.8", "3.11"]')) || fromJSON('["3.8", "3.9", "3.10", "3.11"]') }} + python: ${{ (github.event_name == 'pull_request' && fromJSON('["3.8", "3.12"]')) || fromJSON('["3.8", "3.9", "3.10", "3.11", "3.12"]') }} type: ["cli", "dapp", "data_dependency", diff --git a/.github/workflows/doctor.yml b/.github/workflows/doctor.yml index 555452871..e6b7a580b 100644 --- a/.github/workflows/doctor.yml +++ b/.github/workflows/doctor.yml @@ -23,7 +23,7 @@ jobs: fail-fast: false matrix: os: ["ubuntu-latest", "windows-2022"] - python: ["3.8", "3.9", "3.10", "3.11"] + python: ["3.8", "3.9", "3.10", "3.11", "3.12"] exclude: # strange failure - os: windows-2022 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 892e20d15..2087bd4d8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,7 +25,7 @@ jobs: matrix: os: ["ubuntu-latest", "windows-2022"] type: ["unit", "integration", "tool"] - python: ${{ (github.event_name == 'pull_request' && fromJSON('["3.8", "3.11"]')) || fromJSON('["3.8", "3.9", "3.10", "3.11"]') }} + python: ${{ (github.event_name == 'pull_request' && fromJSON('["3.8", "3.12"]')) || fromJSON('["3.8", "3.9", "3.10", "3.11", "3.12"]') }} steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python }} diff --git a/slither/__main__.py b/slither/__main__.py index ee1428967..caaef5730 100644 --- a/slither/__main__.py +++ b/slither/__main__.py @@ -10,9 +10,9 @@ import pstats import sys import traceback +from importlib import metadata from typing import Tuple, Optional, List, Dict, Type, Union, Any, Sequence -from pkg_resources import iter_entry_points, require from crytic_compile import cryticparser, CryticCompile from crytic_compile.platform.standard import generate_standard_export @@ -166,19 +166,26 @@ def get_detectors_and_printers() -> Tuple[ printers = [p for p in printers_ if inspect.isclass(p) and issubclass(p, AbstractPrinter)] # Handle plugins! - for entry_point in iter_entry_points(group="slither_analyzer.plugin", name=None): + if sys.version_info >= (3, 10): + entry_points = metadata.entry_points(group="slither_analyzer.plugin") + else: + from pkg_resources import iter_entry_points # pylint: disable=import-outside-toplevel + + entry_points = iter_entry_points(group="slither_analyzer.plugin", name=None) + + for entry_point in entry_points: make_plugin = entry_point.load() plugin_detectors, plugin_printers = make_plugin() detector = None if not all(issubclass(detector, AbstractDetector) for detector in plugin_detectors): - raise Exception( + raise ValueError( f"Error when loading plugin {entry_point}, {detector} is not a detector" ) printer = None if not all(issubclass(printer, AbstractPrinter) for printer in plugin_printers): - raise Exception(f"Error when loading plugin {entry_point}, {printer} is not a printer") + raise ValueError(f"Error when loading plugin {entry_point}, {printer} is not a printer") # We convert those to lists in case someone returns a tuple detectors += list(plugin_detectors) @@ -208,7 +215,7 @@ def choose_detectors( if detector in detectors: detectors_to_run.append(detectors[detector]) else: - raise Exception(f"Error: {detector} is not a detector") + raise ValueError(f"Error: {detector} is not a detector") detectors_to_run = sorted(detectors_to_run, key=lambda x: x.IMPACT) return detectors_to_run @@ -256,7 +263,7 @@ def choose_printers( if printer in printers: printers_to_run.append(printers[printer]) else: - raise Exception(f"Error: {printer} is not a printer") + raise ValueError(f"Error: {printer} is not a printer") return printers_to_run @@ -298,7 +305,7 @@ def parse_args( parser.add_argument( "--version", help="displays the current version", - version=require("slither-analyzer")[0].version, + version=metadata.version("slither-analyzer"), action="version", ) @@ -648,7 +655,7 @@ def parse_args( args.json_types = set(args.json_types.split(",")) # type:ignore for json_type in args.json_types: if json_type not in JSON_OUTPUT_TYPES: - raise Exception(f'Error: "{json_type}" is not a valid JSON result output type.') + raise ValueError(f'Error: "{json_type}" is not a valid JSON result output type.') return args diff --git a/slither/utils/output.py b/slither/utils/output.py index 4a91ca9b9..176b250e3 100644 --- a/slither/utils/output.py +++ b/slither/utils/output.py @@ -4,10 +4,10 @@ import os import zipfile from collections import OrderedDict +from importlib import metadata from typing import Tuple, Optional, Dict, List, Union, Any, TYPE_CHECKING, Type from zipfile import ZipFile -from pkg_resources import require from slither.core.cfg.node import Node from slither.core.declarations import ( @@ -161,7 +161,7 @@ def output_to_sarif( "driver": { "name": "Slither", "informationUri": "https://github.com/crytic/slither", - "version": require("slither-analyzer")[0].version, + "version": metadata.version("slither-analyzer"), "rules": [], } },