Skip to content

Commit

Permalink
add
Browse files Browse the repository at this point in the history
  • Loading branch information
baseplate-admin committed Feb 24, 2024
1 parent 2117f4a commit 24c1516
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 14 deletions.
2 changes: 1 addition & 1 deletion django_ltree/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class DjangoLtreeConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "django_ltree"

def ready(self):
def ready(self) -> None:
from . import checks as checks
from . import lookups as lookups
from . import functions as functions
38 changes: 25 additions & 13 deletions django_ltree/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
from django.forms.widgets import TextInput

from collections.abc import Iterable
from typing import TypeVarTuple, NoReturn, Any, TYPE_CHECKING

if TYPE_CHECKING:
from django_ltree.models import TreeModel

path_label_validator = RegexValidator(
r"^(?P<root>[a-zA-Z][a-zA-Z0-9_]*|\d+)(?:\.[a-zA-Z0-9_]+)*$",
Expand All @@ -13,8 +17,8 @@
)


class PathValue(UserList):
def __init__(self, value):
class PathValue(UserList[str]):
def __init__(self, value: str | int | Iterable[str]):
if isinstance(value, str):
split_by = "/" if "/" in value else "."
value = value.strip().split(split_by) if value else []
Expand All @@ -27,18 +31,20 @@ def __init__(self, value):

super().__init__(initlist=value)

def __repr__(self):
def __repr__(self) -> str:
return str(self)

def __str__(self):
def __str__(self) -> str:
return ".".join(self)


class PathValueProxy:
def __init__(self, field_name):
def __init__(self, field_name: str) -> None:
self.field_name = field_name

def __get__(self, instance, owner):
def __get__(
self, instance: "PathValueProxy" | None, *args: TypeVarTuple
) -> "PathValueProxy" | "PathValue" | None:
if instance is None:
return self

Expand All @@ -49,7 +55,9 @@ def __get__(self, instance, owner):

return PathValue(instance.__dict__[self.field_name])

def __set__(self, instance, value):
def __set__(
self, instance: "PathValueProxy" | None, value: str
) -> NoReturn | "PathValueProxy":
if instance is None:
return self

Expand All @@ -63,15 +71,17 @@ class PathFormField(forms.CharField):
class PathField(TextField):
default_validators = [path_label_validator]

def db_type(self, connection):
def db_type(self, *args: TypeVarTuple) -> str:
return "ltree"

def formfield(self, **kwargs):
def formfield(self, **kwargs: Any) -> Any:
kwargs["form_class"] = PathFormField
kwargs["widget"] = TextInput(attrs={"class": "vTextField"})
return super().formfield(**kwargs)

def contribute_to_class(self, cls, name, private_only=False):
def contribute_to_class(
self, cls: type["TreeModel"], name: str, private_only: bool = False
) -> None:
super().contribute_to_class(cls, name)
setattr(cls, self.name, PathValueProxy(self.name))

Expand All @@ -80,20 +90,22 @@ def from_db_value(self, value, expression, connection, *args):
return value
return PathValue(value)

def get_prep_value(self, value):
def get_prep_value(self, value: str | None) -> str | None:
if value is None:
return value
return str(PathValue(value))

def to_python(self, value):
def to_python(self, value: str | None | PathValue) -> PathValue | None:
if value is None:
return value
elif isinstance(value, PathValue):
return value

return PathValue(value)

def get_db_prep_value(self, value, connection, prepared=False):
def get_db_prep_value(
self, value: str | None | PathValue, connection: str, prepared: bool = False
) -> str | None:
if value is None:
return value
elif isinstance(value, PathValue):
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ build-backend = "poetry.core.masonry.api"
[tool.mypy]
mypy_path = "./django_ltree/"
namespace_packages = false
ignore_missing_imports = true
show_error_codes = true
strict = true
warn_unreachable = true

0 comments on commit 24c1516

Please sign in to comment.