Skip to content

Commit

Permalink
sketch validation for simple type checks
Browse files Browse the repository at this point in the history
  • Loading branch information
DylanLukes committed Aug 27, 2024
1 parent 183259b commit 3568635
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 19 deletions.
19 changes: 12 additions & 7 deletions scripts/hatch_build.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
from typing import Any

from hatchling.bridge.app import Application
from hatchling.builders.config import BuilderConfigBound

from hatchling.builders.hooks.plugin.interface import BuildHookInterface
from hatchling.metadata.core import ProjectMetadata


class WebAssetsBuildHook(BuildHookInterface):
class WebAssetsBuildHook(BuildHookInterface[BuilderConfigBound]):
PLUGIN_NAME = "web_assets"

def __init__(self, root: str, config: dict[str, Any], build_config: BuilderConfigBound, metadata: ProjectMetadata,
directory: str, target_name: str, app: Application | None = None) -> None:
super().__init__(root, config, build_config, metadata, directory, target_name, app)
# def __init__(
# self,
# root: str,
# config: dict[str, Any],
# build_config: BuilderConfigBound,
# metadata: ProjectMetadata[PluginManagerBound],
# directory: str,
# target_name: str,
# app: Application | None = None
# ) -> None:
# super().__init__(root, config, build_config, metadata, directory, target_name, app)

def initialize(self, version: str, build_data: dict[str, Any]) -> None:
super().initialize(version, build_data)
37 changes: 26 additions & 11 deletions src/renkon/core/model/trait/sketch.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from renkon.core.model.schema import Schema
from renkon.core.model.trait.spec import TraitSpec
from renkon.core.model.type import RenkonType


class TraitSketch(BaseModel):
Expand All @@ -22,8 +23,16 @@ class TraitSketch(BaseModel):
schema: Schema # pyright: ignore [reportIncompatibleMethodOverride]
bindings: dict[str, str]

# Inverted lookup from column name to metavariable
_bindings_inv: dict[str, str] = {}

@model_validator(mode="after")
def _populate_bindings_inv(self) -> Self:
self._bindings_inv = {v: k for (k, v) in self.bindings.items()}
return self

@model_validator(mode="after")
def check_bindings_keys(self) -> Self:
def _check_bindings_keys(self) -> Self:
pattern_mvars = set(self.spec.pattern.metavars)
bound_mvars = set(self.bindings.keys())

Expand All @@ -41,19 +50,25 @@ def check_bindings_keys(self) -> Self:
return self

@model_validator(mode="after")
def check_bindings_values(self) -> Self:
def _check_bindings_values(self) -> Self:
for mvar, col in self.bindings.items():
if col not in self.schema.columns:
msg = f"Cannot bind '{mvar}' to '{col} not found in {list(self.schema.columns)}"
raise ValueError(msg)
return self

# @model_validator(mode="after")
# def check_bindings_typings(self) -> Self:
# for mvar, _ in self.bindings.items():
# match self.trait.typings[mvar]:
# case RenkonType():
# pass
# case str():
# pass
# return self
@model_validator(mode="after")
def _check_bindings_typings(self) -> Self:
# Check that the types in the provided schema match typings.
for col, ty in self.schema.items():
metavar = self._bindings_inv[col]
req_ty = self.spec.typings[metavar]
match req_ty:
case RenkonType():
if not ty.is_subtype(req_ty):
msg = f"Column '{col}' has incompatible type '{ty}', expected '{req_ty}'."
raise TypeError(msg)
case str():
raise NotImplementedError

return self
1 change: 0 additions & 1 deletion src/renkon/core/model/type/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,6 @@ def __and__(self, other: UnionType) -> UnionType:
# region



# noinspection PyMethodMayBeStatic
class TreeToTypeTransformer(Transformer[RenkonType]):
@staticmethod
Expand Down
18 changes: 18 additions & 0 deletions tests/renkon/core/model/test_sketch.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# SPDX-FileCopyrightText: 2024-present Dylan Lukes <[email protected]>
#
# SPDX-License-Identifier: BSD-3-Clause
import itertools as it

import pytest

import renkon.api as rk
Expand All @@ -23,3 +25,19 @@ def test_sketch_bindings_extra():
def test_sketch_linear2():
schema = Schema({"time": rk.float_(), "open tabs": rk.float_()})
TraitSketch(spec=Linear2.spec, schema=schema, bindings={"X": "time", "Y": "open tabs"})


def test_sketch_incorrect_typing():
schema = Schema({"x": rk.int_(), "name": rk.str_()})
with pytest.raises(TypeError, match="incompatible type"):
TraitSketch(spec=Linear2.spec, schema=schema, bindings={"X": "x", "Y": "name"})


def test_sketch_typevars():
for ty1, ty2 in it.product(rk.equatable().ts, repeat=2):
schema = Schema({"a": ty1, "b": ty2})
if ty1 == ty2:
TraitSketch(spec=Equal.spec, schema=schema, bindings={"A": "a", "B": "b"})
else:
with pytest.raises(TypeError):
TraitSketch(spec=Equal.spec, schema=schema, bindings={"A": "a", "B": "b"})
4 changes: 4 additions & 0 deletions tests/renkon/core/model/trait/test_instantiate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# SPDX-FileCopyrightText: 2024-present Dylan Lukes <[email protected]>
#
# SPDX-License-Identifier: BSD-3-Clause

3 changes: 3 additions & 0 deletions tests/renkon/core/trait/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# SPDX-FileCopyrightText: 2024-present Dylan Lukes <[email protected]>
#
# SPDX-License-Identifier: BSD-3-Clause

0 comments on commit 3568635

Please sign in to comment.