From a6cc0cd75ed511091294a3850b36a1533dab6c50 Mon Sep 17 00:00:00 2001 From: romintomasetti Date: Tue, 24 Mar 2026 21:11:21 +0100 Subject: [PATCH] enabling mypyc Signed-off-by: romintomasetti --- .github/workflows/ci.yml | 23 ++++++++++++++++++-- cmake_file_api/kinds/api.py | 6 ++++-- cmake_file_api/kinds/cache/api.py | 2 +- cmake_file_api/kinds/cache/v2.py | 23 +++++++------------- cmake_file_api/kinds/cmakeFiles/api.py | 2 +- cmake_file_api/kinds/cmakeFiles/v1.py | 23 +++++++------------- cmake_file_api/kinds/codemodel/api.py | 2 +- cmake_file_api/kinds/codemodel/v2.py | 27 +++++++++--------------- cmake_file_api/kinds/common.py | 17 +++++---------- cmake_file_api/kinds/configureLog/api.py | 2 +- cmake_file_api/kinds/configureLog/v1.py | 27 +++++++++--------------- cmake_file_api/kinds/kind.py | 8 +++++-- cmake_file_api/kinds/toolchains/api.py | 2 +- cmake_file_api/kinds/toolchains/v1.py | 6 ++++-- cmake_file_api/reply/v1/api.py | 2 +- requirements-dev.txt | 5 ++++- setup.cfg | 2 ++ setup.py | 6 +++++- 18 files changed, 93 insertions(+), 92 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 025d0ba..59f29b2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,7 +33,7 @@ jobs: - uses: actions/setup-python@v6 with: python-version: "3.10" - - run: pip install mypy + - run: python -m pip install -r requirements-dev.txt - run: mypy --install-types --non-interactive --strict pylint: @@ -43,5 +43,24 @@ jobs: - uses: actions/setup-python@v6 with: python-version: "3.12" - - run: pip install pylint + - run: python -m pip install -r requirements-dev.txt - run: pylint --verbose --fail-under=10 --rcfile .pylintrc cmake_file_api + + mypyc: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + py: ['3.10', '3.11', '3.12', '3.13', '3.14'] + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-python@v6 + with: + python-version: ${{ matrix.py }} + - run: python -m pip install -r requirements-dev.txt + - run: python setup.py bdist_wheel --dist-dir wheelhouse + - run: ls -al wheelhouse + - run: python -m pip install --no-deps --no-index --find-links=wheelhouse/ cmake_file_api + - run: python -m pip show --verbose cmake_file_api + - run: rm -rf cmake_file_api/ + - run: python -m pytest --log-cli-level=info -vvv tests/ diff --git a/cmake_file_api/kinds/api.py b/cmake_file_api/kinds/api.py index cd477b0..19c2b92 100644 --- a/cmake_file_api/kinds/api.py +++ b/cmake_file_api/kinds/api.py @@ -10,13 +10,15 @@ class CMakeApiType(Protocol): - KIND: ObjectKind + @staticmethod + def kind() -> ObjectKind: + ... @classmethod def from_path(cls, path: Path, reply_path: Path) -> "CMakeApiType": ... -OBJECT_KINDS_API: dict[ObjectKind, dict[int, CMakeApiType]] = { +OBJECT_KINDS_API: dict[ObjectKind, dict[int, type[CMakeApiType]]] = { ObjectKind.CACHE: CACHE_API, ObjectKind.CMAKEFILES: CMAKEFILES_API, ObjectKind.CONFIGURELOG: CONFIGURELOG_API, diff --git a/cmake_file_api/kinds/cache/api.py b/cmake_file_api/kinds/cache/api.py index 863faac..8d7c50c 100644 --- a/cmake_file_api/kinds/cache/api.py +++ b/cmake_file_api/kinds/cache/api.py @@ -6,6 +6,6 @@ if typing.TYPE_CHECKING: from ..api import CMakeApiType -CACHE_API: dict[int, CMakeApiType] = { +CACHE_API: dict[int, type[CMakeApiType]] = { 2: CacheV2, } diff --git a/cmake_file_api/kinds/cache/v2.py b/cmake_file_api/kinds/cache/v2.py index ac19fd5..1a59853 100644 --- a/cmake_file_api/kinds/cache/v2.py +++ b/cmake_file_api/kinds/cache/v2.py @@ -2,7 +2,7 @@ from enum import Enum import json from pathlib import Path -from typing import Any, ClassVar +from typing import Any from cmake_file_api.kinds.common import VersionMajorMinor from cmake_file_api.kinds.kind import ObjectKind @@ -43,18 +43,18 @@ def from_dict(cls, dikt: dict[str, Any]) -> "CacheEntry": properties = list(CacheEntryProperty.from_dict(cep) for cep in dikt["properties"]) return cls(name, value, type, properties) +@dataclasses.dataclass(frozen=True, slots=True) class CacheV2: - KIND: ClassVar = ObjectKind.CACHE + version: VersionMajorMinor + entries: list[CacheEntry] - __slots__ = ("version", "entries") - - def __init__(self, version: VersionMajorMinor, entries: list[CacheEntry]): - self.version = version - self.entries = entries + @staticmethod + def kind() -> ObjectKind: + return ObjectKind.CACHE @classmethod def from_dict(cls, dikt: dict[str, Any], reply_path: Path) -> "CacheV2": - if dikt["kind"] != cls.KIND.value: + if dikt["kind"] != cls.kind(): raise ValueError version = VersionMajorMinor.from_dict(dikt["version"]) entries = list(CacheEntry.from_dict(ce) for ce in dikt["entries"]) @@ -65,10 +65,3 @@ def from_path(cls, path: Path, reply_path: Path) -> "CacheV2": with path.open() as file: dikt = json.load(file) return cls.from_dict(dikt, reply_path) - - def __repr__(self) -> str: - return "{}(version={}, entries={})".format( - type(self).__name__, - repr(self.version), - repr(self.entries), - ) diff --git a/cmake_file_api/kinds/cmakeFiles/api.py b/cmake_file_api/kinds/cmakeFiles/api.py index 2d2d58e..1689ae9 100644 --- a/cmake_file_api/kinds/cmakeFiles/api.py +++ b/cmake_file_api/kinds/cmakeFiles/api.py @@ -6,6 +6,6 @@ if typing.TYPE_CHECKING: from ..api import CMakeApiType -CMAKEFILES_API: dict[int, CMakeApiType] = { +CMAKEFILES_API: dict[int, type[CMakeApiType]] = { 1: CMakeFilesV1, } diff --git a/cmake_file_api/kinds/cmakeFiles/v1.py b/cmake_file_api/kinds/cmakeFiles/v1.py index 4307a28..c906a41 100644 --- a/cmake_file_api/kinds/cmakeFiles/v1.py +++ b/cmake_file_api/kinds/cmakeFiles/v1.py @@ -1,3 +1,4 @@ +import dataclasses import json from pathlib import Path from typing import Any, Optional @@ -33,15 +34,15 @@ def __repr__(self) -> str: ) +@dataclasses.dataclass(frozen=True, slots=True) class CMakeFilesV1: - KIND = ObjectKind.CMAKEFILES + version: VersionMajorMinor + paths: CMakeSourceBuildPaths + inputs: list[CMakeFilesInput] - __slots__ = ("version", "paths", "inputs") - - def __init__(self, version: VersionMajorMinor, paths: CMakeSourceBuildPaths, inputs: list[CMakeFilesInput]): - self.version = version - self.paths = paths - self.inputs = inputs + @staticmethod + def kind() -> ObjectKind: + return ObjectKind.CMAKEFILES @classmethod def from_dict(cls, dikt: dict[str, Any], reply_path: Path) -> "CMakeFilesV1": @@ -55,11 +56,3 @@ def from_path(cls, path: Path, reply_path: Path) -> "CMakeFilesV1": with path.open() as file: dikt = json.load(file) return cls.from_dict(dikt, reply_path) - - def __repr__(self) -> str: - return "{}(version={}, paths={}, inputs={})".format( - type(self).__name__, - repr(self.version), - self.paths, - repr(self.inputs), - ) diff --git a/cmake_file_api/kinds/codemodel/api.py b/cmake_file_api/kinds/codemodel/api.py index c76998c..e163c18 100644 --- a/cmake_file_api/kinds/codemodel/api.py +++ b/cmake_file_api/kinds/codemodel/api.py @@ -7,6 +7,6 @@ if typing.TYPE_CHECKING: from ..api import CMakeApiType -CODEMODEL_API: dict[int, CMakeApiType] = { +CODEMODEL_API: dict[int, type[CMakeApiType]] = { 2: CodemodelV2, } diff --git a/cmake_file_api/kinds/codemodel/v2.py b/cmake_file_api/kinds/codemodel/v2.py index 7159b72..e09bf76 100644 --- a/cmake_file_api/kinds/codemodel/v2.py +++ b/cmake_file_api/kinds/codemodel/v2.py @@ -1,6 +1,7 @@ +import dataclasses import json from pathlib import Path -from typing import Any, ClassVar, Optional +from typing import Any, Optional from cmake_file_api.kinds.common import CMakeSourceBuildPaths, VersionMajorMinor from cmake_file_api.kinds.kind import ObjectKind @@ -153,19 +154,19 @@ def __repr__(self) -> str: ) +@dataclasses.dataclass(frozen=True, slots=True) class CodemodelV2: - KIND: ClassVar = ObjectKind.CODEMODEL + version: VersionMajorMinor + paths: CMakeSourceBuildPaths + configurations: list[CMakeConfiguration] - __slots__ = ("version", "paths", "configurations") - - def __init__(self, version: VersionMajorMinor, paths: CMakeSourceBuildPaths, configurations: list[CMakeConfiguration]): - self.version = version - self.paths = paths - self.configurations = configurations + @staticmethod + def kind() -> ObjectKind: + return ObjectKind.CODEMODEL @classmethod def from_dict(cls, dikt: dict[str, Any], reply_path: Path) -> "CodemodelV2": - if dikt["kind"] != cls.KIND.value: + if dikt["kind"] != cls.kind(): raise ValueError paths = CMakeSourceBuildPaths.from_dict(dikt["paths"]) version = VersionMajorMinor.from_dict(dikt["version"]) @@ -183,11 +184,3 @@ def get_configuration(self, name: str) -> CMakeConfiguration: return next(c for c in self.configurations if c.name == name) except StopIteration: raise KeyError("Unknown configuration") - - def __repr__(self) -> str: - return "{}(version={}, paths={}, configurations={})".format( - type(self).__name__, - self.version, - self.paths, - self.configurations, - ) diff --git a/cmake_file_api/kinds/common.py b/cmake_file_api/kinds/common.py index 0a4245b..c1825fd 100644 --- a/cmake_file_api/kinds/common.py +++ b/cmake_file_api/kinds/common.py @@ -1,23 +1,16 @@ +import dataclasses from pathlib import Path from typing import Any +@dataclasses.dataclass(frozen=True, slots=True) class VersionMajorMinor: - __slots__ = ("major", "minor") - - def __init__(self, major: int, minor: int): - self.major = major - self.minor = minor + major: int + minor: int @classmethod def from_dict(cls, d: dict[str, int]) -> "VersionMajorMinor": - return cls(int(d["major"]), int(d["minor"])) - - def __repr__(self) -> str: - return "Version({}.{})".format( - self.major, - self.minor, - ) + return cls(d["major"], d["minor"]) class CMakeSourceBuildPaths: diff --git a/cmake_file_api/kinds/configureLog/api.py b/cmake_file_api/kinds/configureLog/api.py index f0b9e45..3a2047e 100644 --- a/cmake_file_api/kinds/configureLog/api.py +++ b/cmake_file_api/kinds/configureLog/api.py @@ -6,6 +6,6 @@ if typing.TYPE_CHECKING: from ..api import CMakeApiType -CONFIGURELOG_API: dict[int, CMakeApiType] = { +CONFIGURELOG_API: dict[int, type[CMakeApiType]] = { 1: ConfigureLogV1, } diff --git a/cmake_file_api/kinds/configureLog/v1.py b/cmake_file_api/kinds/configureLog/v1.py index 93e8c4a..6802b49 100644 --- a/cmake_file_api/kinds/configureLog/v1.py +++ b/cmake_file_api/kinds/configureLog/v1.py @@ -1,24 +1,25 @@ +import dataclasses import json from pathlib import Path -from typing import Any, ClassVar +from typing import Any from cmake_file_api.kinds.common import VersionMajorMinor from cmake_file_api.kinds.kind import ObjectKind +@dataclasses.dataclass(frozen=True, slots=True) class ConfigureLogV1: - KIND: ClassVar = ObjectKind.CONFIGURELOG + version: VersionMajorMinor + path: Path + eventKindNames: list[str] - __slots__ = ("version", "path", "eventKindNames") - - def __init__(self, version: VersionMajorMinor, path: Path, eventKindNames: list[str]): - self.version = version - self.path = path - self.eventKindNames = eventKindNames + @staticmethod + def kind() -> ObjectKind: + return ObjectKind.CONFIGURELOG @classmethod def from_dict(cls, dikt: dict[str, Any], reply_path: Path) -> "ConfigureLogV1": - if dikt["kind"] != cls.KIND.value: + if dikt["kind"] != cls.kind(): raise ValueError path = Path(dikt["path"]) version = VersionMajorMinor.from_dict(dikt["version"]) @@ -30,11 +31,3 @@ def from_path(cls, path: Path, reply_path: Path) -> "ConfigureLogV1": with path.open() as file: dikt = json.load(file) return cls.from_dict(dikt, reply_path) - - def __repr__(self) -> str: - return "{}(version={}, paths={}, configurations={})".format( - type(self).__name__, - self.version, - self.path, - self.eventKindNames, - ) diff --git a/cmake_file_api/kinds/kind.py b/cmake_file_api/kinds/kind.py index 640826b..7383de8 100644 --- a/cmake_file_api/kinds/kind.py +++ b/cmake_file_api/kinds/kind.py @@ -1,7 +1,11 @@ -import enum +import sys +if sys.version_info >= (3, 11): + from enum import StrEnum +else: + from backports.strenum.strenum import StrEnum -class ObjectKind(enum.Enum): +class ObjectKind(StrEnum): CACHE = "cache" CMAKEFILES = "cmakeFiles" CODEMODEL = "codemodel" diff --git a/cmake_file_api/kinds/toolchains/api.py b/cmake_file_api/kinds/toolchains/api.py index d37d362..3aa01f8 100644 --- a/cmake_file_api/kinds/toolchains/api.py +++ b/cmake_file_api/kinds/toolchains/api.py @@ -6,6 +6,6 @@ if typing.TYPE_CHECKING: from ..api import CMakeApiType -TOOLCHAINS_API: dict[int, CMakeApiType] = { +TOOLCHAINS_API: dict[int, type[CMakeApiType]] = { 1: ToolchainsV1, } diff --git a/cmake_file_api/kinds/toolchains/v1.py b/cmake_file_api/kinds/toolchains/v1.py index 88f3f93..5a3d499 100644 --- a/cmake_file_api/kinds/toolchains/v1.py +++ b/cmake_file_api/kinds/toolchains/v1.py @@ -57,11 +57,13 @@ def from_dict(cls, dikt: dict[str, Any]) -> "CMakeToolchain": @dataclasses.dataclass(frozen=True, slots=True) class ToolchainsV1: - KIND = ObjectKind.TOOLCHAINS - version: VersionMajorMinor toolchains: list[CMakeToolchain] + @staticmethod + def kind() -> ObjectKind: + return ObjectKind.TOOLCHAINS + @classmethod def from_dict(cls, dikt: dict[str, Any], reply_path: Path) -> "ToolchainsV1": return cls( diff --git a/cmake_file_api/reply/v1/api.py b/cmake_file_api/reply/v1/api.py index 5ac3745..3ad5534 100644 --- a/cmake_file_api/reply/v1/api.py +++ b/cmake_file_api/reply/v1/api.py @@ -74,7 +74,7 @@ def inspect(self, kind: ObjectKind, kind_version: int) -> Optional[CMakeApiType] data_path = index.reply.stateless.get((kind, kind_version), None) if data_path is None: return None - api: Optional[CMakeApiType] = OBJECT_KINDS_API.get(kind, {}).get(kind_version, None) + api: Optional[type[CMakeApiType]] = OBJECT_KINDS_API.get(kind, {}).get(kind_version, None) if api is None: return None return api.from_path(reply_path / str(data_path.jsonFile), reply_path) diff --git a/requirements-dev.txt b/requirements-dev.txt index ed6c7d4..aa84cb7 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,3 +1,6 @@ +backports.strenum +pylint pytest -mypy +mypy[mypyc] typeguard +vcs-versioning diff --git a/setup.cfg b/setup.cfg index 9add36a..15ec41d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -20,6 +20,8 @@ python_requires = >=3.10 packages=find: setup_requires = setuptools_scm +install_requires = + backports.strenum; python_version < "3.11" [options.packages.find] exclude = diff --git a/setup.py b/setup.py index 0eb5031..bb44346 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,8 @@ from setuptools import setup +from mypyc.build import mypycify -setup(use_scm_version=True) +setup( + use_scm_version=True, + ext_modules=mypycify(paths=['cmake_file_api/'], verbose=True), +)