|
1 | 1 | from abc import ABC |
2 | 2 | from typing import Any, Literal |
3 | 3 |
|
4 | | -from .util.assertions import assert_is_instance_of |
5 | | -from .util.assertions import assert_is_none |
6 | | -from .util.assertions import assert_is_one_of |
| 4 | +from .util.assertions import ( |
| 5 | + assert_is_given, |
| 6 | + assert_is_instance_of, |
| 7 | + assert_is_none, |
| 8 | + assert_is_one_of, |
| 9 | +) |
7 | 10 |
|
8 | 11 |
|
9 | 12 | Link = Literal["component"] | Literal["container"] | Literal["app"] |
10 | 13 |
|
| 14 | +COMPONENT = "" |
| 15 | +"""Special property value that can be used |
| 16 | +to refer to the entire component. |
| 17 | +""" |
| 18 | + |
11 | 19 |
|
12 | 20 | class Channel(ABC): |
13 | 21 | """Base class for `Input`, `State`, and `Output`. |
@@ -53,7 +61,8 @@ class Input(Channel): |
53 | 61 | Args: |
54 | 62 | id: |
55 | 63 | Value of a component's "id" property. |
56 | | - Used only if `source` is `"component"`. |
| 64 | + Required, if `source` is `"component"` (the default). |
| 65 | + Otherwise, it must not be passed. |
57 | 66 | property: |
58 | 67 | Name of the property of a component or state. |
59 | 68 | To address properties in nested objects or arrays |
@@ -82,7 +91,7 @@ class State(Input): |
82 | 91 |
|
83 | 92 | Just like an `Input`, a `State` describes from which property in which state |
84 | 93 | a parameter value is read, but according state changes |
85 | | - will **not*Ü* trigger callback invocation. |
| 94 | + will **not* trigger callback invocation. |
86 | 95 |
|
87 | 96 | Args: |
88 | 97 | id: |
@@ -125,6 +134,8 @@ class Output(Channel): |
125 | 134 | To address properties in nested objects or arrays |
126 | 135 | use a dot (`.`) to separate property names and array |
127 | 136 | indexes. |
| 137 | + If `target` is `"component"` the empty string can be used |
| 138 | + to refer to entire components. |
128 | 139 | target: One of `"component"` (the default), `"container"`, |
129 | 140 | or `"app"`. |
130 | 141 | """ |
@@ -154,22 +165,37 @@ def _validate_input_params( |
154 | 165 | def _validate_output_params( |
155 | 166 | target: Link | None, id: str | None, property: str | None |
156 | 167 | ) -> tuple[Link, str | None, str | None]: |
157 | | - return _validate_params("target", target, id, property) |
| 168 | + return _validate_params("target", target, id, property, output=True) |
158 | 169 |
|
159 | 170 |
|
160 | 171 | # noinspection PyShadowingBuiltins |
161 | 172 | def _validate_params( |
162 | | - link_name: str, link: Link | None, id: str | None, property: str | None |
| 173 | + link_name: str, |
| 174 | + link: Link | None, |
| 175 | + id: str | None, |
| 176 | + property: str | None, |
| 177 | + output: bool = False, |
163 | 178 | ) -> tuple[Link, str | None, str | None]: |
164 | | - assert_is_one_of(link_name, link, ("component", "container", "app", None)) |
165 | | - if not link or link == "component": |
166 | | - assert_is_instance_of("id", id, (str, NoneType)) |
| 179 | + if link is None or link == "component": |
| 180 | + # Component states require an id |
| 181 | + # and property which defaults to "value" |
| 182 | + link = "component" |
| 183 | + assert_is_given("id", id) |
| 184 | + assert_is_instance_of("id", id, str) |
167 | 185 | assert_is_instance_of("property", id, (str, NoneType)) |
168 | | - link = link or "component" |
169 | | - if property is None and id is not None: |
| 186 | + if property is None: |
| 187 | + # property, if not provided, defaults to "value" |
170 | 188 | property = "value" |
| 189 | + elif not output: |
| 190 | + # outputs are allowed to have an empty property value |
| 191 | + assert_is_given("property", property) |
171 | 192 | else: |
172 | | - assert_is_none("id", id) |
| 193 | + # Other states require a link and property |
| 194 | + # and should have no id |
| 195 | + assert_is_given(link_name, link) |
| 196 | + assert_is_one_of(link_name, link, ("container", "app")) |
| 197 | + assert_is_given("property", property) |
173 | 198 | assert_is_instance_of("property", property, str) |
| 199 | + assert_is_none("id", id) |
174 | 200 | # noinspection PyTypeChecker |
175 | 201 | return link, id, property |
0 commit comments