diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 4d90fd3df..d029ff9f2 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -23,7 +23,7 @@ jobs: - uses: actions/setup-python@v5 with: cache: pip - python-version: '3.11' + python-version: '3.12' - name: Install libsnappy-dev run: sudo apt install libsnappy-dev # required for pylint @@ -42,7 +42,7 @@ jobs: - uses: actions/setup-python@v5 with: cache: pip - python-version: '3.11' + python-version: '3.12' - name: Install libsnappy-dev run: sudo apt install libsnappy-dev - run: pip install -r requirements/requirements.txt -r requirements/requirements-typing.txt diff --git a/.github/workflows/schema.yml b/.github/workflows/schema.yml index fed313a5f..1ee9a8049 100644 --- a/.github/workflows/schema.yml +++ b/.github/workflows/schema.yml @@ -15,7 +15,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" cache: pip cache-dependency-path: requirements.txt diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index da2839a3d..fd9a63c2b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [ '3.8', '3.9', '3.10', '3.11' ] + python-version: [ '3.8', '3.9', '3.10', '3.11', '3.12' ] env: PYTEST_ADDOPTS: >- --log-dir=/tmp/ci-logs diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8af01f93a..a975b52ec 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -21,7 +21,7 @@ repos: entry: ./copyright.sh - repo: https://github.com/shellcheck-py/shellcheck-py - rev: v0.9.0.2 + rev: v0.10.0.1 hooks: - id: shellcheck @@ -56,7 +56,7 @@ repos: - id: black - repo: https://github.com/PyCQA/flake8 - rev: 6.0.0 + rev: 7.1.0 hooks: - id: flake8 @@ -73,6 +73,6 @@ repos: - repo: https://github.com/PyCQA/pylint # Note: pre-commit autoupdate changes to an alpha version. Instead, manually find the # latest stable version here: https://github.com/pylint-dev/pylint/releases - rev: v2.17.4 + rev: v3.2.6 hooks: - id: pylint diff --git a/.pylintrc b/.pylintrc index 414336499..e2c2f6242 100644 --- a/.pylintrc +++ b/.pylintrc @@ -10,6 +10,7 @@ disable= duplicate-code, fixme, import-outside-toplevel, + invalid-field-call, invalid-name, missing-docstring, too-few-public-methods, diff --git a/karapace/backup/api.py b/karapace/backup/api.py index 8f2b09f14..7b243586b 100644 --- a/karapace/backup/api.py +++ b/karapace/backup/api.py @@ -22,6 +22,7 @@ from .poll_timeout import PollTimeout from .topic_configurations import ConfigSource, get_topic_configurations from aiokafka.errors import KafkaError, TopicAlreadyExistsError +from collections.abc import Sized from concurrent.futures import Future from confluent_kafka import Message, TopicPartition from enum import Enum @@ -41,7 +42,7 @@ from pathlib import Path from rich.console import Console from tenacity import retry, retry_if_exception_type, RetryCallState, stop_after_delay, wait_fixed -from typing import Callable, Iterator, Literal, Mapping, NewType, Sized, TypeVar +from typing import Callable, Iterator, Literal, Mapping, NewType, TypeVar import contextlib import datetime diff --git a/karapace/backup/backends/v2.py b/karapace/backup/backends/v2.py index 7a7386ded..7472e9b2f 100644 --- a/karapace/backup/backends/v2.py +++ b/karapace/backup/backends/v2.py @@ -33,7 +33,10 @@ def safe_writer( ) -> Generator[IO[str], None, None]: with super().safe_writer(target, allow_overwrite) as buffer: buffer.write(V2_MARKER.decode()) - yield buffer + try: + yield buffer + finally: + pass class SchemaBackupV2Writer(_BaseV2Writer): diff --git a/karapace/backup/safe_writer.py b/karapace/backup/safe_writer.py index 45181a7d7..57970b950 100644 --- a/karapace/backup/safe_writer.py +++ b/karapace/backup/safe_writer.py @@ -109,9 +109,12 @@ def str_writer( safe_context = _safe_temporary_descriptor(target.absolute(), allow_overwrite) with safe_context as fd, open(fd, "w") as buffer: - yield buffer - buffer.flush() - os.fsync(fd) + try: + yield buffer + buffer.flush() + os.fsync(fd) + finally: + pass def _check_destination_directory(destination: Path) -> None: diff --git a/karapace/protobuf/known_dependency.py b/karapace/protobuf/known_dependency.py index 31c4a8b33..5b322929b 100644 --- a/karapace/protobuf/known_dependency.py +++ b/karapace/protobuf/known_dependency.py @@ -16,7 +16,7 @@ def static_init(cls: Any) -> object: return cls -@static_init +@static_init # pylint: disable=used-before-assignment class KnownDependency: index: Dict = dict() index_simple: Dict = dict() diff --git a/karapace/protobuf/message_element.py b/karapace/protobuf/message_element.py index 57eb03fa6..c7f2ddb10 100644 --- a/karapace/protobuf/message_element.py +++ b/karapace/protobuf/message_element.py @@ -91,7 +91,7 @@ def to_schema(self) -> str: return "".join(result) def compare(self, other: TypeElement, result: CompareResult, types: CompareTypes) -> None: - from karapace.protobuf.compare_type_lists import compare_type_lists + from karapace.protobuf.compare_type_lists import compare_type_lists # pylint: disable=cyclic-import if not isinstance(other, MessageElement): result.add_modification(Modification.TYPE_ALTER) diff --git a/karapace/protobuf/proto_type.py b/karapace/protobuf/proto_type.py index 94a278044..9dad49163 100644 --- a/karapace/protobuf/proto_type.py +++ b/karapace/protobuf/proto_type.py @@ -19,7 +19,7 @@ def static_init(cls) -> object: return cls -@static_init +@static_init # pylint: disable=used-before-assignment class ProtoType: @property def simple_name(self) -> str: diff --git a/karapace/protobuf/syntax_reader.py b/karapace/protobuf/syntax_reader.py index 560e63b85..13c3238e9 100644 --- a/karapace/protobuf/syntax_reader.py +++ b/karapace/protobuf/syntax_reader.py @@ -103,7 +103,6 @@ def read_quoted_string(self) -> str: self.newline() self.unexpected("unterminated string") - return "" def read_numeric_escape(self, radix: int, length: int) -> str: value = -1 @@ -180,7 +179,7 @@ def read_word(self) -> str: self.expect(start < self.pos, "expected a word") return self.data[start : self.pos] - def read_int(self) -> int: # pylint: disable=inconsistent-return-statements + def read_int(self) -> int: """Reads an integer and returns it.""" tag: str = self.read_word() try: diff --git a/karapace/schema_registry.py b/karapace/schema_registry.py index e4d24db2e..6594663ad 100644 --- a/karapace/schema_registry.py +++ b/karapace/schema_registry.py @@ -179,6 +179,8 @@ async def subject_delete_local(self, subject: Subject, permanent: bool) -> list[ version_list = list(schema_versions_live) if version_list: latest_version_id = version_list[-1] + else: + return [] referenced_by = self.schema_reader.get_referenced_by(subject, latest_version_id) if referenced_by and len(referenced_by) > 0: diff --git a/karapace/utils.py b/karapace/utils.py index 8066c5565..96f87da8c 100644 --- a/karapace/utils.py +++ b/karapace/utils.py @@ -203,7 +203,7 @@ def convert_to_int(object_: dict, key: str, content_type: str) -> None: try: object_[key] = int(object_[key]) except ValueError: - from karapace.rapu import http_error + from karapace.rapu import http_error # pylint: disable=cyclic-import http_error( message=f"{key} is not a valid int: {object_[key]}",