From 0ed5665e20a7167cbab8a2931848e9dd6436b20b Mon Sep 17 00:00:00 2001 From: kugesan1105 Date: Wed, 2 Oct 2024 11:44:17 +0530 Subject: [PATCH 1/3] Initial commit --- jac/jaclang/runtimelib/architype.py | 21 +++++++++++++-- jac/jaclang/tests/fixtures/entry_exit.jac | 33 +++++++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 jac/jaclang/tests/fixtures/entry_exit.jac diff --git a/jac/jaclang/runtimelib/architype.py b/jac/jaclang/runtimelib/architype.py index d8f469d774..21a1cb4a7d 100644 --- a/jac/jaclang/runtimelib/architype.py +++ b/jac/jaclang/runtimelib/architype.py @@ -528,6 +528,12 @@ def spawn_call(self, node: Anchor) -> WalkerArchitype: self.next = [node] while len(self.next): if current_node := self.next.pop(0).architype: + for i in walker._jac_entry_funcs_: + if not i.trigger or isinstance(current_node, i.trigger): + if i.func: + i.func(walker, current_node) + else: + raise ValueError(f"No function {i.name} to call.") for i in current_node._jac_entry_funcs_: if not i.trigger or isinstance(walker, i.trigger): if i.func: @@ -538,20 +544,31 @@ def spawn_call(self, node: Anchor) -> WalkerArchitype: return walker for i in walker._jac_entry_funcs_: if not i.trigger or isinstance(current_node, i.trigger): - if i.func: + if i.func and i.trigger: i.func(walker, current_node) + elif not i.trigger: + continue else: raise ValueError(f"No function {i.name} to call.") if self.disengaged: return walker for i in walker._jac_exit_funcs_: if not i.trigger or isinstance(current_node, i.trigger): - if i.func: + if i.func and i.trigger: i.func(walker, current_node) + elif not i.trigger: + continue else: raise ValueError(f"No function {i.name} to call.") if self.disengaged: return walker + for i in walker._jac_exit_funcs_: + if not i.trigger or isinstance(current_node, i.trigger): + if i.func: + i.func(walker, current_node) + else: + raise ValueError(f"No function {i.name} to call.") + for i in current_node._jac_exit_funcs_: if not i.trigger or isinstance(walker, i.trigger): if i.func: diff --git a/jac/jaclang/tests/fixtures/entry_exit.jac b/jac/jaclang/tests/fixtures/entry_exit.jac new file mode 100644 index 0000000000..5a811aa656 --- /dev/null +++ b/jac/jaclang/tests/fixtures/entry_exit.jac @@ -0,0 +1,33 @@ +node test_node { + has value: int; +} + +walker test_walker { + has visited_nodes: list = []; + has entry_count: int = 0; + has exit_count: int = 0; + + can traverse with `root entry { + visit [-->](`?test_node); + } + + can log_entry with entry { + self.entry_count += 1; + } + + can log_exit with exit { + self.exit_count += 1; + } + + can log_visit with test_node exit { + self.visited_nodes.append(here); + } +} + +with entry { + for i in range(2) { + root ++> (next:=test_node(value=i)); + } + wlk_obj = root spawn test_walker(); + print(wlk_obj); +} \ No newline at end of file From a37a2d7521c1a74eef36fc0f996297e8f82a9655 Mon Sep 17 00:00:00 2001 From: kugesan1105 Date: Wed, 2 Oct 2024 17:03:02 +0530 Subject: [PATCH 2/3] test added and now we entry and exit will be executed at beginig and at end respectively --- jac/jaclang/runtimelib/architype.py | 27 ++++++++++++----------- jac/jaclang/tests/fixtures/entry_exit.jac | 13 ++++++----- jac/jaclang/tests/test_language.py | 13 +++++++++++ 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/jac/jaclang/runtimelib/architype.py b/jac/jaclang/runtimelib/architype.py index 21a1cb4a7d..c7979fa557 100644 --- a/jac/jaclang/runtimelib/architype.py +++ b/jac/jaclang/runtimelib/architype.py @@ -526,14 +526,16 @@ def spawn_call(self, node: Anchor) -> WalkerArchitype: if walker := self.architype: self.path = [] self.next = [node] + if self.next: + current_node = self.next[-1].architype + for i in walker._jac_entry_funcs_: + if not i.trigger: + if i.func: + i.func(walker, current_node) + else: + raise ValueError(f"No function {i.name} to call.") while len(self.next): if current_node := self.next.pop(0).architype: - for i in walker._jac_entry_funcs_: - if not i.trigger or isinstance(current_node, i.trigger): - if i.func: - i.func(walker, current_node) - else: - raise ValueError(f"No function {i.name} to call.") for i in current_node._jac_entry_funcs_: if not i.trigger or isinstance(walker, i.trigger): if i.func: @@ -562,13 +564,6 @@ def spawn_call(self, node: Anchor) -> WalkerArchitype: raise ValueError(f"No function {i.name} to call.") if self.disengaged: return walker - for i in walker._jac_exit_funcs_: - if not i.trigger or isinstance(current_node, i.trigger): - if i.func: - i.func(walker, current_node) - else: - raise ValueError(f"No function {i.name} to call.") - for i in current_node._jac_exit_funcs_: if not i.trigger or isinstance(walker, i.trigger): if i.func: @@ -577,6 +572,12 @@ def spawn_call(self, node: Anchor) -> WalkerArchitype: raise ValueError(f"No function {i.name} to call.") if self.disengaged: return walker + for i in walker._jac_exit_funcs_: + if not i.trigger: + if i.func: + i.func(walker, current_node) + else: + raise ValueError(f"No function {i.name} to call.") self.ignores = [] return walker raise Exception(f"Invalid Reference {self.id}") diff --git a/jac/jaclang/tests/fixtures/entry_exit.jac b/jac/jaclang/tests/fixtures/entry_exit.jac index 5a811aa656..839b419161 100644 --- a/jac/jaclang/tests/fixtures/entry_exit.jac +++ b/jac/jaclang/tests/fixtures/entry_exit.jac @@ -12,20 +12,23 @@ walker test_walker { } can log_entry with entry { + print("Entering at the beginning of walker: ",here); self.entry_count += 1; } - can log_exit with exit { - self.exit_count += 1; - } - can log_visit with test_node exit { + print("Visiting node : ", here); self.visited_nodes.append(here); } + + can log_exit with exit { + print("Exiting at the end of walker: ",here); + self.exit_count += 1; + } } with entry { - for i in range(2) { + for i in range(10) { root ++> (next:=test_node(value=i)); } wlk_obj = root spawn test_walker(); diff --git a/jac/jaclang/tests/test_language.py b/jac/jaclang/tests/test_language.py index a5ff68c211..5bcb1fab6a 100644 --- a/jac/jaclang/tests/test_language.py +++ b/jac/jaclang/tests/test_language.py @@ -1042,3 +1042,16 @@ def test_match_multi_ex(self) -> None: stdout_value = captured_output.getvalue().split("\n") self.assertEqual("Ten", stdout_value[0]) self.assertEqual("ten", stdout_value[1]) + + def test_entry_exit(self) -> None: + """Test entry and exit behavior of walker.""" + captured_output = io.StringIO() + sys.stdout = captured_output + jac_import("entry_exit", base_path=self.fixture_abs_path("./")) + sys.stdout = sys.__stdout__ + stdout_value = captured_output.getvalue().split("\n") + self.assertIn("Entering at the beginning of walker: Root()", stdout_value[0]) + self.assertIn("entry_count=1, exit_count=1", str(stdout_value[12])) + self.assertIn( + "Exiting at the end of walker: test_node(value=", stdout_value[11] + ) From c9c0b304e0bafb0f31e56a8f1eb3fbd64a11e81d Mon Sep 17 00:00:00 2001 From: Alexie Madolid <74129725+amadolid@users.noreply.github.com> Date: Wed, 2 Oct 2024 23:46:53 +0800 Subject: [PATCH 3/3] [MINOR]: Dynamic return types (#1292) --- jac-cloud/jac_cloud/core/context.py | 31 +- jac-cloud/jac_cloud/plugin/jaseci.py | 18 +- jac-cloud/jac_cloud/tests/openapi_specs.json | 380 +++++++++++++++---- jac-cloud/jac_cloud/tests/simple_graph.jac | 25 ++ 4 files changed, 361 insertions(+), 93 deletions(-) diff --git a/jac-cloud/jac_cloud/core/context.py b/jac-cloud/jac_cloud/core/context.py index 5c87d63bd7..092975966e 100644 --- a/jac-cloud/jac_cloud/core/context.py +++ b/jac-cloud/jac_cloud/core/context.py @@ -1,9 +1,9 @@ """Core constructs for Jac Language.""" from contextvars import ContextVar -from dataclasses import is_dataclass +from dataclasses import dataclass, is_dataclass from os import getenv -from typing import Any, NotRequired, TypedDict, cast +from typing import Any, Generic, TypeVar, cast from bson import ObjectId @@ -33,13 +33,24 @@ SUPER_ROOT = NodeAnchor.ref(f"n::{SUPER_ROOT_ID}") PUBLIC_ROOT = NodeAnchor.ref(f"n::{PUBLIC_ROOT_ID}") +RT = TypeVar("RT") -class ContextResponse(TypedDict): + +@dataclass +class ContextResponse(Generic[RT]): """Default Context Response.""" status: int - reports: NotRequired[list[Any]] - returns: NotRequired[list[Any]] + reports: list[Any] | None = None + returns: list[RT] | None = None + + def __serialize__(self) -> dict[str, Any]: + """Serialize response.""" + return { + key: value + for key, value in self.__dict__.items() + if value is not None and not key.startswith("_") + } class JaseciContext(ExecutionContext): @@ -135,20 +146,20 @@ def get_root() -> Root: # type: ignore[override] def response(self, returns: list[Any]) -> ORJSONResponse: """Return serialized version of reports.""" - resp: ContextResponse = {"status": self.status, "returns": returns} + resp = ContextResponse[Any](status=self.status) if self.reports: for key, val in enumerate(self.reports): self.clean_response(key, val, self.reports) - resp["reports"] = self.reports + resp.reports = self.reports for key, val in enumerate(returns): self.clean_response(key, val, returns) - if not SHOW_ENDPOINT_RETURNS: - resp.pop("returns") + if SHOW_ENDPOINT_RETURNS: + resp.returns = returns - return ORJSONResponse(resp, status_code=self.status) + return ORJSONResponse(resp.__serialize__(), status_code=self.status) def clean_response( self, key: str | int, val: Any, obj: list | dict # noqa: ANN401 diff --git a/jac-cloud/jac_cloud/plugin/jaseci.py b/jac-cloud/jac_cloud/plugin/jaseci.py index 12588428c7..d199ffb2e5 100644 --- a/jac-cloud/jac_cloud/plugin/jaseci.py +++ b/jac-cloud/jac_cloud/plugin/jaseci.py @@ -6,7 +6,8 @@ from functools import wraps from os import getenv from re import compile -from typing import Any, Callable, Type, TypeVar, cast, get_type_hints +from types import NoneType +from typing import Any, Callable, Type, TypeAlias, TypeVar, Union, cast, get_type_hints from asyncer import syncify @@ -182,9 +183,22 @@ def api_root( walker_method = getattr(walker_router, method) + raw_types: list[Type] = [ + get_type_hints(jef.func).get("return", NoneType) + for jef in (*cls._jac_entry_funcs_, *cls._jac_exit_funcs_) + ] + + if raw_types: + if len(raw_types) > 1: + ret_types: TypeAlias = Union[*raw_types] # type: ignore[valid-type] + else: + ret_types = raw_types[0] # type: ignore[misc] + else: + ret_types = NoneType # type: ignore[misc] + settings: dict[str, Any] = { "tags": ["walker"], - "response_model": ContextResponse, + "response_model": ContextResponse[ret_types], } if auth: settings["dependencies"] = cast(list, authenticator) diff --git a/jac-cloud/jac_cloud/tests/openapi_specs.json b/jac-cloud/jac_cloud/tests/openapi_specs.json index 6873e9cebd..c0c50f61b2 100644 --- a/jac-cloud/jac_cloud/tests/openapi_specs.json +++ b/jac-cloud/jac_cloud/tests/openapi_specs.json @@ -547,7 +547,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -597,7 +597,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -629,7 +629,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -679,7 +679,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -711,7 +711,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -761,7 +761,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -793,7 +793,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -843,7 +843,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -875,7 +875,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -925,7 +925,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -957,7 +957,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -1007,7 +1007,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -1039,7 +1039,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -1089,7 +1089,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -1121,7 +1121,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -1171,7 +1171,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -1203,7 +1203,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -1253,7 +1253,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -1285,7 +1285,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -1335,7 +1335,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -1367,7 +1367,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -1417,7 +1417,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -1449,7 +1449,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -1499,7 +1499,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -1531,7 +1531,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -1581,7 +1581,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -1613,7 +1613,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -1663,7 +1663,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -1695,7 +1695,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -1745,7 +1745,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -1787,7 +1787,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -1857,7 +1857,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -1899,7 +1899,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -1969,7 +1969,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -2001,7 +2001,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -2051,7 +2051,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -2093,7 +2093,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -2163,7 +2163,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -2195,7 +2195,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -2245,7 +2245,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -2293,7 +2293,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -2357,7 +2357,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -2409,7 +2409,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -2477,7 +2477,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -2525,7 +2525,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -2571,7 +2571,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -2635,7 +2635,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -2697,7 +2697,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -2764,7 +2764,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -2829,7 +2829,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -2912,7 +2912,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -2993,7 +2993,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -3060,7 +3060,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -3125,7 +3125,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -3190,7 +3190,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -3255,7 +3255,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -3320,7 +3320,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -3385,7 +3385,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -3440,7 +3440,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -3495,7 +3495,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -3578,7 +3578,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -3659,7 +3659,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -3740,7 +3740,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -3821,7 +3821,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -3902,7 +3902,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -3983,7 +3983,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -4054,7 +4054,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -4125,7 +4125,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -4167,7 +4167,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -4237,7 +4237,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -4279,7 +4279,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -4339,7 +4339,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -4381,7 +4381,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" } } } @@ -4451,7 +4451,79 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContextResponse" + "$ref": "#/components/schemas/ContextResponse_NoneType_" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/walker/different_return": { + "post": { + "tags": [ + "walker", + "walker" + ], + "summary": "/different_return", + "operationId": "api_root_walker_different_return_post", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ContextResponse_Union_NoneType__int__str__bool__Parent__list__dict__" + } + } + } + } + } + } + }, + "/walker/different_return/{node}": { + "post": { + "tags": [ + "walker", + "walker" + ], + "summary": "/different_return/{node}", + "operationId": "api_entry_walker_different_return__node__post", + "parameters": [ + { + "name": "node", + "in": "path", + "required": true, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Node" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ContextResponse_Union_NoneType__int__str__bool__Parent__list__dict__" } } } @@ -4624,20 +4696,128 @@ ], "title": "Body_api_root_walker_post_with_file_post" }, - "ContextResponse": { + "Child": { + "properties": { + "val": { + "type": "integer", + "title": "Val" + }, + "arr": { + "items": {}, + "type": "array", + "title": "Arr" + }, + "json": { + "type": "object", + "title": "Json" + }, + "enum_field": { + "enum": [], + "title": "Enum", + "description": "Create a collection of name/value pairs.\n\nExample enumeration:\n\n>>> class Color(Enum):\n... RED = 1\n... BLUE = 2\n... GREEN = 3\n\nAccess them by:\n\n- attribute access:\n\n >>> Color.RED\n \n\n- value lookup:\n\n >>> Color(1)\n \n\n- name lookup:\n\n >>> Color['RED']\n \n\nEnumerations can be iterated over, and know how many members they have:\n\n>>> len(Color)\n3\n\n>>> list(Color)\n[, , ]\n\nMethods can be added to enumerations, and members can have their own\nattributes -- see the documentation for details." + } + }, + "type": "object", + "required": [ + "val", + "arr", + "json", + "enum_field" + ], + "title": "Child" + }, + "ContextResponse_NoneType_": { "properties": { "status": { "type": "integer", "title": "Status" }, "reports": { - "items": {}, - "type": "array", + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "null" + } + ], "title": "Reports" }, "returns": { - "items": {}, - "type": "array", + "anyOf": [ + { + "items": { + "type": "null" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Returns" + } + }, + "type": "object", + "required": [ + "status" + ], + "title": "ContextResponse" + }, + "ContextResponse_Union_NoneType__int__str__bool__Parent__list__dict__": { + "properties": { + "status": { + "type": "integer", + "title": "Status" + }, + "reports": { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Reports" + }, + "returns": { + "anyOf": [ + { + "items": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + }, + { + "type": "boolean" + }, + { + "$ref": "#/components/schemas/Parent" + }, + { + "items": {}, + "type": "array" + }, + { + "type": "object" + }, + { + "type": "null" + } + ] + }, + "type": "array" + }, + { + "type": "null" + } + ], "title": "Returns" } }, @@ -4645,8 +4825,7 @@ "required": [ "status" ], - "title": "ContextResponse", - "description": "Default Context Response." + "title": "ContextResponse" }, "DetachSSO": { "properties": { @@ -4662,6 +4841,11 @@ "title": "DetachSSO", "description": "Attach SSO Request Model." }, + "Enum": { + "enum": [], + "title": "Enum", + "description": "Create a collection of name/value pairs.\n\nExample enumeration:\n\n>>> class Color(Enum):\n... RED = 1\n... BLUE = 2\n... GREEN = 3\n\nAccess them by:\n\n- attribute access:\n\n >>> Color.RED\n \n\n- value lookup:\n\n >>> Color(1)\n \n\n- name lookup:\n\n >>> Color['RED']\n \n\nEnumerations can be iterated over, and know how many members they have:\n\n>>> len(Color)\n3\n\n>>> list(Color)\n[, , ]\n\nMethods can be added to enumerations, and members can have their own\nattributes -- see the documentation for details." + }, "HTTPValidationError": { "properties": { "detail": { @@ -4675,6 +4859,40 @@ "type": "object", "title": "HTTPValidationError" }, + "Parent": { + "properties": { + "val": { + "type": "integer", + "title": "Val" + }, + "arr": { + "items": {}, + "type": "array", + "title": "Arr" + }, + "json": { + "type": "object", + "title": "Json" + }, + "enum_field": { + "enum": [], + "title": "Enum", + "description": "Create a collection of name/value pairs.\n\nExample enumeration:\n\n>>> class Color(Enum):\n... RED = 1\n... BLUE = 2\n... GREEN = 3\n\nAccess them by:\n\n- attribute access:\n\n >>> Color.RED\n \n\n- value lookup:\n\n >>> Color(1)\n \n\n- name lookup:\n\n >>> Color['RED']\n \n\nEnumerations can be iterated over, and know how many members they have:\n\n>>> len(Color)\n3\n\n>>> list(Color)\n[, , ]\n\nMethods can be added to enumerations, and members can have their own\nattributes -- see the documentation for details." + }, + "child": { + "$ref": "#/components/schemas/Child" + } + }, + "type": "object", + "required": [ + "val", + "arr", + "json", + "enum_field", + "child" + ], + "title": "Parent" + }, "UserChangePassword": { "properties": { "old_password": { diff --git a/jac-cloud/jac_cloud/tests/simple_graph.jac b/jac-cloud/jac_cloud/tests/simple_graph.jac index 886bd096d3..009c2f9b71 100644 --- a/jac-cloud/jac_cloud/tests/simple_graph.jac +++ b/jac-cloud/jac_cloud/tests/simple_graph.jac @@ -483,4 +483,29 @@ walker custom_status_code { can enter with `root entry { Jac.get_context().status = self.status; } +} + +walker different_return { + + can enter1 with `root entry { + } + + can enter2 with A entry -> int { + } + + can enter3 with B entry -> str { + } + + can enter4 with C entry -> bool { + } + + can enter5 with Nested entry -> Parent { + } + + can enter6 with `root entry -> list | dict { + } + + class __specs__ { + has auth: bool = False; + } } \ No newline at end of file