Skip to content

Commit

Permalink
refactor: remove int inheritance from Version
Browse files Browse the repository at this point in the history
  • Loading branch information
jjaakola-aiven committed Jun 7, 2024
1 parent a189931 commit b4064ed
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 26 deletions.
2 changes: 1 addition & 1 deletion karapace/dependency.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def to_dict(self) -> JsonData:
return {
"name": self.name,
"subject": self.subject,
"version": self.version,
"version": self.version.value,
}

def identifier(self) -> str:
Expand Down
4 changes: 2 additions & 2 deletions karapace/in_memory_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ def _get_from_hash_cache(self, *, typed_schema: TypedSchema) -> TypedSchema:
return self._hash_to_schema.setdefault(typed_schema.fingerprint(), typed_schema)

def get_next_version(self, *, subject: Subject) -> Version:
return Versioner.V(max(self.subjects[subject].schemas) + 1)
return Versioner.V(max(self.subjects[subject].schemas).value + 1)

def insert_schema_version(
self,
Expand Down Expand Up @@ -224,7 +224,7 @@ def find_subject_schemas(self, *, subject: Subject, include_deleted: bool) -> di
return self.subjects[subject].schemas
with self.schema_lock_thread:
return {
Versioner.V(version_id): schema_version
version_id: schema_version
for version_id, schema_version in self.subjects[subject].schemas.items()
if schema_version.deleted is False
}
Expand Down
6 changes: 3 additions & 3 deletions karapace/schema_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -471,15 +471,15 @@ def _handle_msg_delete_subject(self, key: dict, value: dict | None) -> None: #
return

subject = value["subject"]
version = value["version"]
version = Version(value["version"])
if self.database.find_subject(subject=subject) is None:
LOG.warning("Subject: %r did not exist, should have", subject)
else:
LOG.info("Deleting subject: %r, value: %r", subject, value)
self.database.delete_subject(subject=subject, version=version)

def _handle_msg_schema_hard_delete(self, key: dict) -> None:
subject, version = key["subject"], key["version"]
subject, version = key["subject"], Version(key["version"])

if self.database.find_subject(subject=subject) is None:
LOG.warning("Hard delete: Subject %s did not exist, should have", subject)
Expand All @@ -501,7 +501,7 @@ def _handle_msg_schema(self, key: dict, value: dict | None) -> None:
schema_str = value["schema"]
schema_subject = value["subject"]
schema_id = value["id"]
schema_version = value["version"]
schema_version = Version(value["version"])
schema_deleted = value.get("deleted", False)
schema_references = value.get("references", None)
resolved_references: list[Reference] | None = None
Expand Down
2 changes: 1 addition & 1 deletion karapace/schema_references.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def to_dict(self) -> JsonData:
return {
"name": self.name,
"subject": self.subject,
"version": self.version,
"version": self.version.value,
}

@staticmethod
Expand Down
8 changes: 4 additions & 4 deletions karapace/schema_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ def subject_version_get(self, subject: Subject, version: Version, *, include_del

ret: JsonObject = {
"subject": subject,
"version": resolved_version,
"version": resolved_version.value,
"id": schema_id,
"schema": schema.schema_str,
}
Expand Down Expand Up @@ -427,11 +427,11 @@ def send_schema_message(
deleted: bool,
references: Sequence[Reference] | None,
) -> None:
key = {"subject": subject, "version": version, "magic": 1, "keytype": "SCHEMA"}
key = {"subject": subject, "version": version.value, "magic": 1, "keytype": "SCHEMA"}
if schema:
value = {
"subject": subject,
"version": version,
"version": version.value,
"id": schema_id,
"schema": str(schema),
"deleted": deleted,
Expand Down Expand Up @@ -461,5 +461,5 @@ def resolve_references(

def send_delete_subject_message(self, subject: Subject, version: Version) -> None:
key = {"subject": subject, "magic": 0, "keytype": "DELETE_SUBJECT"}
value = {"subject": subject, "version": version}
value = {"subject": subject, "version": version.value}
self.producer.send_message(key=key, value=value)
16 changes: 11 additions & 5 deletions karapace/schema_registry_apis.py
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ async def schemas_list(self, content_type: str, *, request: HTTPRequest, user: U
for schema_version in schema_versions:
response_schema = {
"subject": schema_version.subject,
"version": schema_version.version,
"version": schema_version.version.value,
"id": schema_version.schema_id,
"schemaType": schema_version.schema.schema_type,
}
Expand Down Expand Up @@ -571,7 +571,12 @@ async def schemas_get_versions(
subject = subject_version["subject"]
if self._auth and not self._auth.check_authorization(user, Operation.Read, f"Subject:{subject}"):
continue
subject_versions.append(subject_version)
subject_versions.append(
{
"subject": subject_version["subject"],
"version": subject_version["version"].value,
}
)
self.r(subject_versions, content_type)

async def schemas_types(self, content_type: str) -> None:
Expand Down Expand Up @@ -733,7 +738,7 @@ async def subject_delete(
if are_we_master:
try:
version_list = await self.schema_registry.subject_delete_local(subject=subject, permanent=permanent)
self.r(version_list, content_type, status=HTTPStatus.OK)
self.r([version.value for version in version_list], content_type, status=HTTPStatus.OK)
except (SubjectNotFoundException, SchemasNotFoundException):
self.r(
body={
Expand Down Expand Up @@ -951,7 +956,8 @@ async def subject_versions_list(
deleted = request.query.get("deleted", "false").lower() == "true"
try:
schema_versions = self.schema_registry.subject_get(subject, include_deleted=deleted)
self.r(list(schema_versions), content_type, status=HTTPStatus.OK)
version_list = [version.value for version in schema_versions]
self.r(version_list, content_type, status=HTTPStatus.OK)
except (SubjectNotFoundException, SchemasNotFoundException):
self.r(
body={
Expand Down Expand Up @@ -1170,7 +1176,7 @@ async def subjects_schema_post(
if parsed_typed_schema.schema_type == new_schema.schema_type and schema_valid:
ret = {
"subject": subject,
"version": schema_version.version,
"version": schema_version.version.value,
"id": schema_version.schema_id,
"schema": parsed_typed_schema.schema_str,
}
Expand Down
34 changes: 27 additions & 7 deletions karapace/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
from typing import ClassVar, Dict, List, Mapping, NewType, Sequence, Union
from typing_extensions import TypeAlias

import functools

JsonArray: TypeAlias = List["JsonData"]
JsonObject: TypeAlias = Dict[str, "JsonData"]
JsonScalar: TypeAlias = Union[str, int, float, None]
Expand Down Expand Up @@ -59,23 +61,41 @@ class Mode(StrEnum):
readwrite = "READWRITE"


class Version(int):
@functools.total_ordering
class Version:
LATEST_VERSION_TAG: ClassVar[str] = "latest"
MINUS_1_VERSION_TAG: ClassVar[int] = -1

def __new__(cls, version: int) -> Version:
def __init__(self, version: int) -> None:
if not isinstance(version, int):
raise InvalidVersion(f"Invalid version {version}")
if (version < cls.MINUS_1_VERSION_TAG) or (version == 0):
if (version < Version.MINUS_1_VERSION_TAG) or (version == 0):
raise InvalidVersion(f"Invalid version {version}")
return super().__new__(cls, version)
self._value = version

def __str__(self) -> str:
return f"{int(self)}"
return f"{int(self._value)}"

def __repr__(self) -> str:
return f"Version={int(self)}"
return f"Version({int(self._value)})"

def __lt__(self, other: object) -> bool:
if isinstance(other, Version):
return self._value < other.value
return NotImplemented

def __eq__(self, other: object) -> bool:
if isinstance(other, Version):
return self._value == other.value
return NotImplemented

def __hash__(self) -> int:
return hash(self._value)

@property
def value(self) -> int:
return self._value

@property
def is_latest(self) -> bool:
return self == self.MINUS_1_VERSION_TAG
return self.value == self.MINUS_1_VERSION_TAG
6 changes: 3 additions & 3 deletions tests/unit/test_schema_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ def version(self):
return Versioner.V(1)

def test_version(self, version: Version):
assert version == 1
assert version == Version(1)
assert isinstance(version, Version)
assert issubclass(Version, int)
assert isinstance(version.value, int)

def test_tags(self, version: Version):
assert version.LATEST_VERSION_TAG == "latest"
Expand All @@ -47,7 +47,7 @@ def test_is_latest(self, version: Version, is_latest: bool):

def test_text_formating(self, version: Version):
assert f"{version}" == "1"
assert f"{version!r}" == "Version=1"
assert f"{version!r}" == "Version(1)"

@pytest.mark.parametrize(
"version, to_compare, comparer, valid",
Expand Down

0 comments on commit b4064ed

Please sign in to comment.