diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c22e648..3dd808b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,29 +19,30 @@ # See https://pre-commit.com for more information # See https://pre-commit.com/hooks.html for more hooks repos: -- repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 - hooks: - - id: check-yaml - - id: end-of-file-fixer - - id: forbid-submodules - - id: trailing-whitespace -- repo: https://github.com/pre-commit/mirrors-clang-format - rev: v18.1.2 - hooks: - - id: clang-format - types_or: [c++, c] -- repo: https://github.com/pryorda/dockerfilelint-precommit-hooks - rev: v0.1.0 - hooks: - - id: dockerfilelint - stages: [commit] -- repo: https://github.com/psf/black - rev: 24.3.0 - hooks: - - id: black - - id: black-jupyter -- repo: https://github.com/kynan/nbstripout - rev: 0.7.1 - hooks: - - id: nbstripout + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: check-yaml + - id: end-of-file-fixer + - id: forbid-submodules + - id: trailing-whitespace + - repo: https://github.com/pre-commit/mirrors-clang-format + rev: v18.1.2 + hooks: + - id: clang-format + types_or: [c++, c] + - repo: https://github.com/pryorda/dockerfilelint-precommit-hooks + rev: v0.1.0 + hooks: + - id: dockerfilelint + stages: [pre-commit] + - repo: https://github.com/kynan/nbstripout + rev: 0.7.1 + hooks: + - id: nbstripout + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.11.2 + hooks: + - id: ruff + args: [--fix] + - id: ruff-format diff --git a/Sandbox.ipynb b/Sandbox.ipynb index 56f0ffb..8b0daf4 100644 --- a/Sandbox.ipynb +++ b/Sandbox.ipynb @@ -56,9 +56,7 @@ "int foo(int a, int b) { return a + b; }\n", "\"\"\"\n", "\n", - "tu = clang.cindex.TranslationUnit.from_source(\n", - " \"tmp.cc\", COMPILER_ARGS, unsaved_files=[(\"tmp.cc\", source)]\n", - ")\n", + "tu = clang.cindex.TranslationUnit.from_source(\"tmp.cc\", COMPILER_ARGS, unsaved_files=[(\"tmp.cc\", source)])\n", "model = py_cppmodel.Model(tu)\n", "model" ] diff --git a/py_cppmodel.py b/py_cppmodel.py index 711cfea..0c47ca1 100644 --- a/py_cppmodel.py +++ b/py_cppmodel.py @@ -1,4 +1,6 @@ -from typing import Any, List, Optional +from typing import Any +from typing import List +from typing import Optional from clang.cindex import AccessSpecifier from clang.cindex import Cursor @@ -11,11 +13,7 @@ def _get_annotations(cursor: Cursor) -> List[str]: - return [ - c.displayname - for c in cursor.get_children() - if c.kind == CursorKind.ANNOTATE_ATTR - ] + return [c.displayname for c in cursor.get_children() if c.kind == CursorKind.ANNOTATE_ATTR] class Unmodelled: @@ -66,19 +64,14 @@ def __repr__(self) -> str: class _Function: def __init__(self, cursor): self.name: str = cursor.spelling - arguments: List[Optional[str]] = [ - str(x.spelling) or None for x in cursor.get_arguments() - ] + arguments: List[Optional[str]] = [str(x.spelling) or None for x in cursor.get_arguments()] argument_types: List[Type] = [Type(x) for x in cursor.type.argument_types()] - self.is_noexcept: bool = ( - cursor.exception_specification_kind - == ExceptionSpecificationKind.BASIC_NOEXCEPT - ) + self.is_noexcept: bool = cursor.exception_specification_kind == ExceptionSpecificationKind.BASIC_NOEXCEPT self.return_type: Type = Type(cursor.type.get_result()) self.arguments: List[FunctionArgument] = [] self.annotations: List[str] = _get_annotations(cursor) - for t, n in zip(argument_types, arguments): + for t, n in zip(argument_types, arguments, strict=False): self.arguments.append(FunctionArgument(t, n)) def __repr__(self) -> str: @@ -111,9 +104,7 @@ def __eq__(self, f) -> bool: return False if len(self.arguments) != len(f.arguments): return False - for x, fx in zip( - [arg.type for arg in self.arguments], [arg.type for arg in f.arguments] - ): + for x, fx in zip([arg.type for arg in self.arguments], [arg.type for arg in f.arguments], strict=False): if x.name != fx.name: return False return True @@ -156,15 +147,9 @@ def __init__(self, cursor: Cursor, namespaces: List[str]): self.source_column = int(cursor.location.column) for c in cursor.get_children(): - if ( - c.kind == CursorKind.CXX_METHOD - and c.type.kind == TypeKind.FUNCTIONPROTO - ): + if c.kind == CursorKind.CXX_METHOD and c.type.kind == TypeKind.FUNCTIONPROTO: self.methods.append(Method(c)) - elif ( - c.kind == CursorKind.CONSTRUCTOR - and c.type.kind == TypeKind.FUNCTIONPROTO - ): + elif c.kind == CursorKind.CONSTRUCTOR and c.type.kind == TypeKind.FUNCTIONPROTO: self.constructors.append(Method(c)) elif c.kind == CursorKind.FIELD_DECL: self.members.append(Member(c)) @@ -194,9 +179,7 @@ def is_error_in_current_file(diagnostic: Diagnostic) -> bool: return True return False - errors: List[Diagnostic] = [ - d for d in translation_unit.diagnostics if is_error_in_current_file(d) - ] + errors: List[Diagnostic] = [d for d in translation_unit.diagnostics if is_error_in_current_file(d)] if errors: joined_errors = "\n".join(str(e) for e in errors) raise ValueError(f"Errors in source file:{joined_errors}") @@ -254,10 +237,7 @@ def _add_child_nodes(self, cursor: Any, namespaces: List[str] = []): if c.kind == CursorKind.CLASS_DECL or c.kind == CursorKind.STRUCT_DECL: if c.location.file.name == self.filename: self.classes.append(Class(c, namespaces)) - elif ( - c.kind == CursorKind.FUNCTION_DECL - and c.type.kind == TypeKind.FUNCTIONPROTO - ): + elif c.kind == CursorKind.FUNCTION_DECL and c.type.kind == TypeKind.FUNCTIONPROTO: if c.location.file.name == self.filename: self.functions.append(Function(c, namespaces)) elif c.kind == CursorKind.NAMESPACE: diff --git a/pyproject.toml b/pyproject.toml index 4bc20cd..f88ce48 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,3 +36,29 @@ include = [ [tool.hatch.build.targets.wheel] include = ["py_cppmodel.py"] + +[tool.ruff] +line-length = 120 +indent-width = 4 + +[tool.ruff.lint] +# https://docs.astral.sh/ruff/rules/ +select = [ + "B", # Bugbear + "E", # Pycodestyle + "F", # Pyflakes + "I", # Isort + "W", # Pycodestyle +] +ignore = [ + "B006", # Do not use mutable data structures for argument defaults TODO: Fix this. + "B018", # Found useless expression. Either assign it to a variable or remove it. TODO: Fix this. +] +fixable = ["ALL"] +unfixable = [] + +[tool.ruff.lint.isort] +force-single-line = true + +[tool.ruff.format] +quote-style = "double" diff --git a/test_parse_standard_library_includes.py b/test_parse_standard_library_includes.py index 6faad31..218af70 100644 --- a/test_parse_standard_library_includes.py +++ b/test_parse_standard_library_includes.py @@ -1,12 +1,9 @@ -import clang -import os -import py_cppmodel import unittest -from parameterized import parameterized - -from ctypes.util import find_library from clang.cindex import TranslationUnit +from parameterized import parameterized + +import py_cppmodel COMPILER_ARGS = [ "-x", diff --git a/test_py_cppmodel.py b/test_py_cppmodel.py index d623353..2f3066e 100644 --- a/test_py_cppmodel.py +++ b/test_py_cppmodel.py @@ -1,10 +1,9 @@ -import clang -import os -import py_cppmodel import unittest from clang.cindex import TranslationUnit +import py_cppmodel + COMPILER_ARGS = [ "-x", "c++", @@ -27,12 +26,8 @@ def test_filename(self): def test_functions(self): self.assertEqual(len(self.model.functions), 2) - self.assertEqual( - str(self.model.functions[0]), "" - ) - self.assertEqual( - str(self.model.functions[1]), "" - ) + self.assertEqual(str(self.model.functions[0]), "") + self.assertEqual(str(self.model.functions[1]), "") def test_classes(self): self.assertEqual(len(self.model.classes), 1) @@ -56,9 +51,7 @@ def test_classes(self): ) self.assertEqual(len(self.model.classes[0].methods), 1) - self.assertEqual( - str(self.model.classes[0].methods[0]), "" - ) + self.assertEqual(str(self.model.classes[0].methods[0]), "") self.assertEqual(len(self.model.classes[0].methods[0].annotations), 1) self.assertEqual(self.model.classes[0].methods[0].annotations[0], "foo")