Skip to content

Commit

Permalink
Refactor typechecking, update docs, add tests (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
Viicos authored Apr 17, 2024
1 parent 7030eb3 commit 6da25c1
Show file tree
Hide file tree
Showing 12 changed files with 488 additions and 254 deletions.
22 changes: 18 additions & 4 deletions docs/source/usage/typechecking.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ can be used:
.. code-block:: python
from jsonlogic import JSONLogicExpression, Operator
from jsonlogic.json_schema.types import BooleanType
from jsonlogic.operators import operator_registry
from jsonlogic.typechecking import typecheck
Expand All @@ -35,6 +36,7 @@ can be used:
"diagnostics": {"argument_type": "warning"},
}
)
assert root_type == BooleanType()
This function returns a two-tuple, containing:

Expand Down Expand Up @@ -72,6 +74,18 @@ Compound types are also supported to some extent. This includes:

assert UnionType(NullType(), NullType()) == NullType()

- Array types::

from jsonlogic.json_schema.types import ArrayType, IntegerType

array = ArrayType(IntegerType())

`tuples <https://json-schema.org/understanding-json-schema/reference/array#tupleValidation>`_ are also supported::

from jsonlogic.json_schema.types import BooleanType, IntegerType, TupleType

tup = TupleType((BooleanType(), IntegerType()))

.. _converting types specifier:

Converting types from a ``"format"`` specifier
Expand Down Expand Up @@ -129,7 +143,7 @@ is not applicable on strings. To overcome this issue, we have two solutions:
Inference for literals
^^^^^^^^^^^^^^^^^^^^^^

The :attr:`~jsonlogic.typechecking.SettingsDict.literal_casts` configuration value
The :attr:`~jsonlogic.typechecking.TypecheckSettings.literal_casts` configuration value
can be used to express how inference should work when a string literal is encountered::

from datetime import datetime, date
Expand All @@ -151,7 +165,7 @@ With this configuration, whenever a string literal will be encountered during ty
every function defined in ``"literal_casts"`` will be called, until one of them doesn't raise
any exception (generally a :exc:`ValueError`).

The default value for :attr:`~jsonlogic.typechecking.SettingsDict.literal_casts` is the one
The default value for :attr:`~jsonlogic.typechecking.TypecheckSettings.literal_casts` is the one
given in the example.

.. warning::
Expand All @@ -164,7 +178,7 @@ Inference for JSON Schema data
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Similarly, any JSON Schema with a specific format can be inferred to a specific type.
The :attr:`~jsonlogic.typechecking.SettingsDict.variable_casts` controls this behavior::
The :attr:`~jsonlogic.typechecking.TypecheckSettings.variable_casts` controls this behavior::

from jsonlogic.json_schema.types import DatetimeType, DateType

Expand All @@ -180,7 +194,7 @@ The :attr:`~jsonlogic.typechecking.SettingsDict.variable_casts` controls this be
)

Whenever a JSON Schema attribute with a format present in ``"variable_casts"`` is encountered,
the matching JSON Schema type will be returned.
the matching JSON Schema type will be returned (assuming it is of type ``"string"``).

.. _diagnostics:

Expand Down
3 changes: 0 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,5 @@ ignore = [
[tool.ruff.lint.isort]
known-first-party = ["jsonlogic"]

[tool.pyright]
reportTypedDictNotRequiredAccess = "none" # until partial typeddicts lands

[tool.pytest.ini_options]
pythonpath = "src"
6 changes: 3 additions & 3 deletions src/jsonlogic/operators/operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def typecheck(self, context: TypecheckContext) -> JSONSchemaType:
default_value_type = (
self.default_value.typecheck(context)
if isinstance(self.default_value, Operator)
else from_value(self.default_value, context.settings["literal_casts"])
else from_value(self.default_value, context.settings.literal_casts)
)
else:
default_value_type = None
Expand All @@ -68,7 +68,7 @@ def typecheck(self, context: TypecheckContext) -> JSONSchemaType:
)
return default_value_type # type: ignore
else:
js_type = from_json_schema(schema, context.settings["variable_casts"])
js_type = from_json_schema(schema, context.settings.variable_casts)
if default_value_type is not None:
return js_type | default_value_type
return js_type
Expand Down Expand Up @@ -297,7 +297,7 @@ def typecheck(self, context: TypecheckContext) -> JSONSchemaType:
return AnyType()

vars_type = cast(ArrayType[JSONSchemaType], vars_type)
with context.data_stack.push(as_json_schema(vars_type.elements_type, context.settings["variable_casts"])):
with context.data_stack.push(as_json_schema(vars_type.elements_type, context.settings.variable_casts)):
func_type = get_type(self.func, context)

return ArrayType(func_type)
244 changes: 0 additions & 244 deletions src/jsonlogic/typechecking.py

This file was deleted.

15 changes: 15 additions & 0 deletions src/jsonlogic/typechecking/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from .diagnostics import Diagnostic, DiagnosticCategory, DiagnosticType
from .typecheck_context import TypecheckContext
from .typecheck_settings import DiagnosticsConfig, TypecheckSettings
from .utils import get_type, typecheck

__all__ = (
"Diagnostic",
"DiagnosticCategory",
"DiagnosticType",
"DiagnosticsConfig",
"TypecheckContext",
"TypecheckSettings",
"get_type",
"typecheck",
)
Loading

0 comments on commit 6da25c1

Please sign in to comment.