From 185e68f809b8ec1ff1d92f38272b872704cd2d1a Mon Sep 17 00:00:00 2001 From: Yoel Bassin Date: Sat, 26 Apr 2025 21:51:32 +0300 Subject: [PATCH] main - feat: Add pre-commit and fix all files --- .gitignore | 2 +- .pre-commit-config.yaml | 33 +++++++++++++++++++++++ .vscode/settings.json | 2 +- README.md | 6 ++--- main.py | 13 ++++----- pyproject.toml | 1 + src/gnuradio_mcp/middlewares/block.py | 9 ++++--- src/gnuradio_mcp/middlewares/flowgraph.py | 6 +++-- src/gnuradio_mcp/middlewares/platform.py | 14 ++++++---- src/gnuradio_mcp/models.py | 26 +++++++++++------- tests/conftest.py | 16 ++++++++--- tests/test_block.py | 10 +++---- tests/test_flowgraph.py | 24 ++++++++++------- tests/test_platform.py | 7 ++--- tests/utils.py | 18 ------------- tox.ini | 2 ++ 16 files changed, 116 insertions(+), 73 deletions(-) create mode 100644 .pre-commit-config.yaml delete mode 100644 tests/utils.py create mode 100644 tox.ini diff --git a/.gitignore b/.gitignore index 1800114..0a19790 100644 --- a/.gitignore +++ b/.gitignore @@ -171,4 +171,4 @@ cython_debug/ .ruff_cache/ # PyPI configuration file -.pypirc \ No newline at end of file +.pypirc diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..4ef6bef --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,33 @@ +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v5.0.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: debug-statements + - id: name-tests-test + args: [--pytest-test-first] + - id: requirements-txt-fixer +- repo: https://github.com/asottile/setup-cfg-fmt + rev: v2.8.0 + hooks: + - id: setup-cfg-fmt +- repo: https://github.com/pycqa/isort + rev: 6.0.1 + hooks: + - id: isort + name: isort (python) +- repo: https://github.com/psf/black + rev: 22.10.0 + hooks: + - id: black +- repo: https://github.com/PyCQA/flake8 + rev: 7.2.0 + hooks: + - id: flake8 + args: [--max-line-length=88] +- repo: https://github.com/pre-commit/mirrors-mypy + rev: v1.15.0 + hooks: + - id: mypy diff --git a/.vscode/settings.json b/.vscode/settings.json index af7446d..930aaf4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,4 +2,4 @@ "python.analysis.extraPaths": [ "./src" ] -} \ No newline at end of file +} diff --git a/README.md b/README.md index 09c54c9..9f49d0a 100644 --- a/README.md +++ b/README.md @@ -7,15 +7,15 @@ Install GNURadio, follow the installation process in [InstallingGR](https://wiki ```bash brew install gnuradio ``` -Now create a virtual environment to run the project. +Now create a virtual environment to run the project. ```bash python3.13 -m venv --system-site-packages venv source venv/bin/activate pip install -e . ``` -we use the `--system-site-packages` flag since GNURadio installs the `gnuradio` python package globally. +we use the `--system-site-packages` flag since GNURadio installs the `gnuradio` python package globally. -Run using +Run using ```bash python -m grc ``` diff --git a/main.py b/main.py index e02528a..027fe43 100644 --- a/main.py +++ b/main.py @@ -1,14 +1,13 @@ -import logging -import logging.handlers -import platform -import sys -from pathlib import Path +from __future__ import annotations +import sys + +from gnuradio_mcp.middlewares.platform import PlatformMiddleware # Load GNU Radio try: from gnuradio import gr -except ImportError as ex: +except ImportError: # Throw a new exception with more information print( "Cannot find GNU Radio! (Have you sourced the environment file?)", @@ -18,7 +17,6 @@ except ImportError as ex: raise Exception("Cannot find GNU Radio!") from None from gnuradio.grc.core.platform import Platform -from gnuradio.grc.core.FlowGraph import FlowGraph platform = Platform( version=gr.version(), @@ -28,7 +26,6 @@ platform = Platform( ) platform.build_library() -from gnuradio_mcp.middlewares.platform import PlatformMiddleware platform_middleware = PlatformMiddleware(platform) diff --git a/pyproject.toml b/pyproject.toml index 82ef52c..0f3e413 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,6 +18,7 @@ dependencies = [ [project.optional-dependencies] dev = [ "pytest >= 7.0", + "pre-commit" ] [tool.ruff] diff --git a/src/gnuradio_mcp/middlewares/block.py b/src/gnuradio_mcp/middlewares/block.py index 058bbec..cc6ed61 100644 --- a/src/gnuradio_mcp/middlewares/block.py +++ b/src/gnuradio_mcp/middlewares/block.py @@ -1,4 +1,5 @@ -from typing import List +from __future__ import annotations + from gnuradio.grc.core.blocks.block import Block from gnuradio_mcp.models import SINK, SOURCE, ParamModel, PortModel @@ -9,13 +10,13 @@ class BlockMiddleware: self._block = block @property - def params(self) -> List[ParamModel]: + def params(self) -> list[ParamModel]: return [ParamModel.from_param(param) for param in self._block.params.values()] @property - def sinks(self) -> List[PortModel]: + def sinks(self) -> list[PortModel]: return [PortModel.from_port(port, SINK) for port in self._block.sinks] @property - def sources(self) -> List[PortModel]: + def sources(self) -> list[PortModel]: return [PortModel.from_port(port, SOURCE) for port in self._block.sources] diff --git a/src/gnuradio_mcp/middlewares/flowgraph.py b/src/gnuradio_mcp/middlewares/flowgraph.py index 6776cd3..405ca31 100644 --- a/src/gnuradio_mcp/middlewares/flowgraph.py +++ b/src/gnuradio_mcp/middlewares/flowgraph.py @@ -1,5 +1,7 @@ -from typing import List, Optional +from __future__ import annotations + from gnuradio.grc.core.FlowGraph import FlowGraph + from gnuradio_mcp.middlewares.block import BlockMiddleware from gnuradio_mcp.models import BlockModel @@ -9,7 +11,7 @@ class FlowGraphMiddleware: self._flowgraph = flowgraph @property - def blocks(self) -> List[BlockModel]: + def blocks(self) -> list[BlockModel]: return [ BlockModel(key=block.key, label=block.label) for block in self._flowgraph.blocks diff --git a/src/gnuradio_mcp/middlewares/platform.py b/src/gnuradio_mcp/middlewares/platform.py index 523e866..325b191 100644 --- a/src/gnuradio_mcp/middlewares/platform.py +++ b/src/gnuradio_mcp/middlewares/platform.py @@ -1,9 +1,11 @@ -from typing import List, Optional +from __future__ import annotations + from gnuradio.grc.core.platform import Platform -from gnuradio.grc.core.FlowGraph import FlowGraph + from gnuradio_mcp.middlewares.flowgraph import FlowGraphMiddleware from gnuradio_mcp.models import BlockModel + class PlatformMiddleware: def __init__(self, platform: Platform): self._platform = platform @@ -11,9 +13,11 @@ class PlatformMiddleware: self._flowgraph_mw = FlowGraphMiddleware(flowgraph) @property - def blocks(self) -> List[BlockModel]: - return [BlockModel.from_block(block) for block in self._platform.blocks.values()] - + def blocks(self) -> list[BlockModel]: + return [ + BlockModel.from_block(block) for block in self._platform.blocks.values() + ] + @property def flowgraph(self) -> FlowGraphMiddleware: return self._flowgraph_mw diff --git a/src/gnuradio_mcp/models.py b/src/gnuradio_mcp/models.py index 4649d69..b32b81d 100644 --- a/src/gnuradio_mcp/models.py +++ b/src/gnuradio_mcp/models.py @@ -1,17 +1,21 @@ -from typing import Any, Literal, Optional, get_args -from pydantic import BaseModel +from __future__ import annotations + +from typing import Any, Literal, get_args + from gnuradio.grc.core.blocks.block import Block -from gnuradio.grc.core.ports.port import Port from gnuradio.grc.core.params.param import Param +from gnuradio.grc.core.ports.port import Port +from pydantic import BaseModel + class BlockModel(BaseModel): label: str key: str @classmethod - def from_block(cls, block: Block) -> "BlockModel": + def from_block(cls, block: Block) -> BlockModel: return cls(label=block.label, key=block.key) - + class ParamModel(BaseModel): parent: str @@ -21,7 +25,7 @@ class ParamModel(BaseModel): value: Any @classmethod - def from_param(cls, param: Param) -> "ParamModel": + def from_param(cls, param: Param) -> ParamModel: return cls( parent=param.parent.name, key=param.key, @@ -29,12 +33,12 @@ class ParamModel(BaseModel): dtype=param.dtype, value=param.get_value(), ) - DirectionType = Literal["sink", "source"] SINK, SOURCE = get_args(DirectionType) + class PortModel(BaseModel): parent: str key: str @@ -45,8 +49,10 @@ class PortModel(BaseModel): @classmethod def from_port( - cls, port: Port, direction: Optional[DirectionType] = None - ) -> "PortModel": + cls, + port: Port, + direction: DirectionType | None = None, + ) -> PortModel: direction = direction or port._dir return cls( parent=port.parent.name, @@ -55,4 +61,4 @@ class PortModel(BaseModel): dtype=port.dtype, direction=direction, optional=port.optional, - ) \ No newline at end of file + ) diff --git a/tests/conftest.py b/tests/conftest.py index f377ce2..fa3989d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,22 +1,30 @@ +from __future__ import annotations + import pytest -from gnuradio.grc.core.platform import Platform from gnuradio import gr +from gnuradio.grc.core.platform import Platform + @pytest.fixture(scope="module") def platform() -> Platform: platform = Platform( version=gr.version(), - version_parts=(gr.major_version(), gr.api_version(), gr.minor_version()), + version_parts=( + gr.major_version(), + gr.api_version(), + gr.minor_version(), + ), prefs=gr.prefs(), ) platform.build_library() return platform -@pytest.fixture(params=[1, 2, 10]) # Arbitrary number of blocks to test + +@pytest.fixture(params=[1, 2, 10]) # Arbitrary number of blocks to test def block_key(platform, request): block_keys = list(platform.blocks.keys()) assert block_keys, "No blocks available in platform library." idx = request.param if idx < len(block_keys): return block_keys[idx] - return block_keys[0] \ No newline at end of file + return block_keys[0] diff --git a/tests/test_block.py b/tests/test_block.py index 1b9a697..5ea9d8b 100644 --- a/tests/test_block.py +++ b/tests/test_block.py @@ -1,9 +1,9 @@ -from typing import List +from __future__ import annotations + import pytest -from gnuradio.grc.core.platform import Platform from gnuradio.grc.core.blocks.block import Block -from gnuradio.grc.core.FlowGraph import FlowGraph -from gnuradio import gr +from gnuradio.grc.core.platform import Platform + from gnuradio_mcp.middlewares.block import BlockMiddleware from gnuradio_mcp.middlewares.flowgraph import FlowGraphMiddleware from gnuradio_mcp.models import SINK, SOURCE, ParamModel @@ -36,7 +36,7 @@ def test_block_middleware_sources(block: Block): check_port_models(middleware.sources, block.sources, SOURCE) -def check_param_models(block: Block, params: List[ParamModel]): +def check_param_models(block: Block, params: list[ParamModel]): assert params assert len(params) == len(block.params) for param in params: diff --git a/tests/test_flowgraph.py b/tests/test_flowgraph.py index 6375503..bb00b37 100644 --- a/tests/test_flowgraph.py +++ b/tests/test_flowgraph.py @@ -1,10 +1,10 @@ -from typing import List +from __future__ import annotations + import pytest from gnuradio.grc.core.platform import Platform + from gnuradio_mcp.middlewares.flowgraph import FlowGraphMiddleware -from gnuradio import gr from gnuradio_mcp.models import BlockModel -from .utils import get_block_keys, add_block, remove_block, get_current_blocks @pytest.fixture @@ -24,23 +24,29 @@ def initial_blocks(flowgraph_middleware: FlowGraphMiddleware): def test_flowgraph_block_addition_and_removal( flowgraph_middleware: FlowGraphMiddleware, platform: Platform, - initial_blocks: List[BlockModel], + initial_blocks: list[BlockModel], block_key: str, ): - block_keys = get_block_keys(platform) + block_keys = platform.blocks.keys() assert block_keys, "No blocks available in platform library." block_name = f"test_block_{block_key}" - add_block(flowgraph_middleware, block_key, block_name) + flowgraph_middleware.add_block(block_key, block_name) blocks = flowgraph_middleware.blocks assert all(b in blocks for b in initial_blocks) assert any(b.key == block_key for b in blocks) - remove_block(flowgraph_middleware, block_name) - current_blocks = get_current_blocks(flowgraph_middleware) + flowgraph_middleware._flowgraph.remove_element( + flowgraph_middleware._flowgraph.get_block(block_name), + ) + current_blocks = [ + BlockModel(key=block.key, label=block.label) + for block in flowgraph_middleware._flowgraph.blocks + ] assert current_blocks == initial_blocks def test_flowgraph_initial_state( - flowgraph_middleware: FlowGraphMiddleware, initial_blocks: List[BlockModel] + flowgraph_middleware: FlowGraphMiddleware, + initial_blocks: list[BlockModel], ): assert flowgraph_middleware.blocks == initial_blocks diff --git a/tests/test_platform.py b/tests/test_platform.py index d0d4ee8..4ccf029 100644 --- a/tests/test_platform.py +++ b/tests/test_platform.py @@ -1,8 +1,9 @@ -import pytest -from gnuradio_mcp.middlewares.platform import BlockModel, PlatformMiddleware +from __future__ import annotations + from gnuradio.grc.core.blocks.block import Block from gnuradio.grc.core.platform import Platform -from gnuradio import gr + +from gnuradio_mcp.middlewares.platform import BlockModel, PlatformMiddleware def test_block_model_from_block(platform: Platform): diff --git a/tests/utils.py b/tests/utils.py deleted file mode 100644 index fe03ede..0000000 --- a/tests/utils.py +++ /dev/null @@ -1,18 +0,0 @@ -from gnuradio_mcp.models import BlockModel - -def get_block_keys(platform): - return list(platform.blocks.keys()) - -def add_block(flowgraph_middleware, block_key, block_name): - flowgraph_middleware.add_block(block_key, block_name) - -def remove_block(flowgraph_middleware, block_name): - flowgraph_middleware._flowgraph.remove_element( - flowgraph_middleware._flowgraph.get_block(block_name) - ) - -def get_current_blocks(flowgraph_middleware): - return [ - BlockModel(key=block.key, label=block.label) - for block in flowgraph_middleware._flowgraph.blocks - ] \ No newline at end of file diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..0cd64bc --- /dev/null +++ b/tox.ini @@ -0,0 +1,2 @@ +[pep8] +ignore = E265,E501,W504