Skip to content

Commit 715c34c

Browse files
authored
Merge pull request #213 from abalabin-bamfunds/explicit-scalar-requirements
make requirements to scalars from resolvers and requires explicit
2 parents 03e05f2 + 1d64acf commit 715c34c

45 files changed

Lines changed: 545 additions & 390 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/source/tutorial/operators.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ Here is an example:
2222
def add_(lhs: TIME_SERIES_TYPE_1, rhs: TIME_SERIES_TYPE_2) -> TIME_SERIES_TYPE_1:
2323
...
2424

25-
@compute_node(overloads=add_, requires=lambda m, s: s["__strict__"] == True)
25+
@compute_node(overloads=add_, requires=lambda m, __strict__: __strict__ == True)
2626
def add_strict(lhs: TS[int], rhs: TS[int], __strict__: bool) -> TS[int]:
2727
return lhs.value + rhs.value
2828

29-
@compute_node(overloads=add_, valid=(), requires=lambda m, s: s["__strict__"] == False)
29+
@compute_node(overloads=add_, valid=(), requires=lambda m, __strict__: __strict__ == False)
3030
def add_not_strict(lhs: TS[int], rhs: TS[int], __strict__: bool) -> TS[int]:
3131
if lhs.valid and rhs.valid:
3232
return lhs.value + rhs.value

docs_md/developers_guide/library_writers_guide.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,9 @@ Also notice the resolves is a dictionary of types that are requiring resolution,
162162
that requires resolution it just needs to appear in the resolvers dict and the function to resolve
163163
it provided.
164164

165-
If the resolution is simple, then just use a ``lamda``, you will notice that a lot of the code
166-
in the core libraries follow the convention: ``lambda m, s: ...``.
165+
If the resolution is simple, then just use a ``lambda``, where ``m`` is the mapping of resolved types.
166+
For resolvers and requires functions that need scalar values, extract the specific scalars as
167+
parameters: ``lambda m, scalar_name: ...``.
167168

168169
### requires
169170

@@ -178,17 +179,17 @@ Here is an example:
178179
```python
179180
from hgraph import TS, generator, SCALAR, MIN_ST
180181

181-
def _check_int_convertable(m, s) -> bool:
182+
def _check_int_convertable(m, v) -> bool:
182183
"""
183-
As with resolvers m and s represent the resolved types and the scalar values.
184+
m represents the resolved types mapping, and v is the scalar value parameter.
184185
True implies the requires is successful. False fails the resolution.
185186
"""
186187
try:
187-
int(s['v'])
188+
int(v)
188189
return True
189190
finally:
190191
return False
191-
192+
192193

193194
@generator(requires=_check_int_convertable)
194195
def int_const(v: SCALAR) -> TS[int]:
@@ -200,7 +201,7 @@ Here is another example using the ``GlobalState`` instead:
200201
```python
201202
from hgraph import GlobalState, graph, TS, record
202203

203-
@graph(overloads=record, requires=lambda m, s: GlobalState.instance().get("record_to_memory", False))
204+
@graph(overloads=record, requires=lambda m: GlobalState.instance().get("record_to_memory", False))
204205
def record_to_memory(ts: TS[float], key: str, record_delta_values: bool = True, suffix: str = None):
205206
...
206207
```

hgraph/_impl/_operators/_conversion_operators/_compound_scalar_conversion_operators.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ def _check_schema(scalar, bundle):
2525

2626
@compute_node(
2727
overloads=combine,
28-
requires=lambda m, s: _check_schema(m[COMPOUND_SCALAR], m[TS_SCHEMA]),
29-
all_valid=lambda m, s: ("bundle",) if s["__strict__"] else None,
28+
requires=lambda m: _check_schema(m[COMPOUND_SCALAR], m[TS_SCHEMA]),
29+
all_valid=lambda m, __strict__: ("bundle",) if __strict__ else None,
3030
)
3131
def combine_cs(
3232
tp_out_: Type[TS[COMPOUND_SCALAR]] = DEFAULT[OUT],
@@ -39,18 +39,18 @@ def combine_cs(
3939

4040
@compute_node(
4141
overloads=convert,
42-
requires=lambda m, s: m[OUT].py_type == TS[CompoundScalar],
43-
resolvers={COMPOUND_SCALAR: lambda m, s: m[TS_SCHEMA].py_type.scalar_type()},
44-
all_valid=lambda m, s: ("bundle",) if s["__strict__"] else None,
42+
requires=lambda m: m[OUT].py_type == TS[CompoundScalar],
43+
resolvers={COMPOUND_SCALAR: lambda m: m[TS_SCHEMA].py_type.scalar_type()},
44+
all_valid=lambda m, __strict__: ("bundle",) if __strict__ else None,
4545
)
4646
def convert_cs_from_tsb(bundle: TSB[TS_SCHEMA], __strict__: bool = True) -> TS[COMPOUND_SCALAR]:
4747
return bundle.value
4848

4949

5050
@compute_node(
5151
overloads=convert,
52-
requires=lambda m, s: m[OUT].py_type != TS[CompoundScalar],
53-
all_valid=lambda m, s: ("bundle",) if s["__strict__"] else None,
52+
requires=lambda m: m[OUT].py_type != TS[CompoundScalar],
53+
all_valid=lambda m, __strict__: ("bundle",) if __strict__ else None,
5454
)
5555
def convert_cs_from_tsb_typed(
5656
bundle: TSB[TS_SCHEMA],

hgraph/_impl/_operators/_conversion_operators/_date_time_conversion_operators.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,39 @@
33
from hgraph import compute_node, TS, OUT, WiringPort, combine, convert
44

55

6-
@compute_node(overloads=convert, requires=lambda m, s: m[OUT].py_type == TS[date])
6+
@compute_node(overloads=convert, requires=lambda m: m[OUT].py_type == TS[date])
77
def convert_str_to_date(ts: TS[str]) -> TS[date]:
88
return date.fromisoformat(ts.value)
99

1010

11-
@compute_node(overloads=convert, requires=lambda m, s: m[OUT].py_type == TS[datetime])
11+
@compute_node(overloads=convert, requires=lambda m: m[OUT].py_type == TS[datetime])
1212
def convert_str_to_datetime(ts: TS[str]) -> TS[datetime]:
1313
return datetime.fromisoformat(ts.value)
1414

1515

16-
@compute_node(overloads=convert, requires=lambda m, s: m[OUT].py_type == TS[datetime])
16+
@compute_node(overloads=convert, requires=lambda m: m[OUT].py_type == TS[datetime])
1717
def convert_date_to_datetime(ts: TS[date]) -> TS[datetime]:
1818
return datetime(ts.value.year, ts.value.month, ts.value.day)
1919

2020

21-
@compute_node(overloads=convert, requires=lambda m, s: m[OUT].py_type == TS[date])
21+
@compute_node(overloads=convert, requires=lambda m: m[OUT].py_type == TS[date])
2222
def convert_datetime_to_date(ts: TS[datetime]) -> TS[date]:
2323
v: datetime = ts.value
2424
return v.date()
2525

2626

27-
@compute_node(overloads=combine, requires=lambda m, s: m[OUT].py_type == TS[date])
27+
@compute_node(overloads=combine, requires=lambda m: m[OUT].py_type == TS[date])
2828
def combine_date(year: TS[int], month: TS[int], day: TS[int]) -> TS[date]:
2929
return date(year.value, month.value, day.value)
3030

3131

3232
@compute_node(
3333
overloads=combine,
34-
requires=lambda m, s: m[OUT].py_type == TS[timedelta],
35-
valid=lambda m, s: (k for k, v in s.items() if isinstance(v, WiringPort)) if s["__strict__"] else (),
34+
requires=lambda m: m[OUT].py_type == TS[timedelta],
35+
valid=lambda m, __strict__, days, seconds, microseconds, milliseconds, minutes, hours, weeks: (
36+
k for k, v in {"days": days, "seconds": seconds, "microseconds": microseconds, "milliseconds": milliseconds,
37+
"minutes": minutes, "hours": hours, "weeks": weeks}.items() if isinstance(v, WiringPort)
38+
) if __strict__ else (),
3639
)
3740
def combine_timedelta(
3841
*,

hgraph/_impl/_operators/_conversion_operators/_general_conversion_operators.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
@graph(
1111
overloads=convert,
12-
requires=lambda m, s: m[TIME_SERIES_TYPE] == m[OUT]
12+
requires=lambda m: m[TIME_SERIES_TYPE] == m[OUT]
1313
or f"OUT: {m[OUT]} is not the same as ts: {m[TIME_SERIES_TYPE]}",
1414
)
1515
def convert_noop(ts: TIME_SERIES_TYPE, to: Type[OUT] = OUT) -> DEFAULT[OUT]:

hgraph/_impl/_operators/_conversion_operators/_mapping_conversion_operators.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
@compute_node(
3333
overloads=convert,
34-
requires=lambda m, s: m[OUT].py_type in (TS[Mapping], TS[dict], TS[frozendict])
34+
requires=lambda m: m[OUT].py_type in (TS[Mapping], TS[dict], TS[frozendict])
3535
or m[OUT].matches_type(TS[Mapping[m[KEYABLE_SCALAR].py_type, m[SCALAR].py_type]]),
3636
)
3737
def convert_ts_to_mapping(
@@ -42,7 +42,7 @@ def convert_ts_to_mapping(
4242

4343
@compute_node(
4444
overloads=convert,
45-
requires=lambda m, s: m[OUT].py_type in (TS[Mapping], TS[dict], TS[frozendict])
45+
requires=lambda m: m[OUT].py_type in (TS[Mapping], TS[dict], TS[frozendict])
4646
or m[OUT].matches_type(TS[Mapping[m[KEYABLE_SCALAR].py_type, m[SCALAR].py_type]]),
4747
)
4848
def convert_tuples_to_mapping(
@@ -56,9 +56,9 @@ def convert_tuples_to_mapping(
5656

5757
@compute_node(
5858
overloads=convert,
59-
requires=lambda m, s: m[OUT].py_type in (TS[Mapping], TS[dict], TS[frozendict])
59+
requires=lambda m: m[OUT].py_type in (TS[Mapping], TS[dict], TS[frozendict])
6060
or m[OUT].matches_type(TS[Mapping[m[KEYABLE_SCALAR].py_type, m[SCALAR].py_type]]),
61-
resolvers={KEYABLE_SCALAR: lambda m, s: int, SCALAR: lambda m, s: m[TIME_SERIES_TYPE].scalar_type()},
61+
resolvers={KEYABLE_SCALAR: lambda m: int, SCALAR: lambda m: m[TIME_SERIES_TYPE].scalar_type()},
6262
)
6363
def convert_tsl_to_mapping(
6464
ts: TSL[TIME_SERIES_TYPE, SIZE], to: Type[OUT] = DEFAULT[OUT]
@@ -68,9 +68,9 @@ def convert_tsl_to_mapping(
6868

6969
@compute_node(
7070
overloads=convert,
71-
requires=lambda m, s: m[OUT].py_type in (TS[Mapping], TS[dict], TS[frozendict])
71+
requires=lambda m: m[OUT].py_type in (TS[Mapping], TS[dict], TS[frozendict])
7272
or m[OUT].matches_type(TS[Mapping[m[KEYABLE_SCALAR].py_type, m[SCALAR].py_type]]),
73-
resolvers={SCALAR: lambda m, s: m[TIME_SERIES_TYPE].scalar_type()},
73+
resolvers={SCALAR: lambda m: m[TIME_SERIES_TYPE].scalar_type()},
7474
)
7575
def convert_tsd_to_mapping(
7676
ts: TSD[KEYABLE_SCALAR, TIME_SERIES_TYPE], to: Type[OUT] = DEFAULT[OUT]
@@ -80,10 +80,10 @@ def convert_tsd_to_mapping(
8080

8181
@compute_node(
8282
overloads=convert,
83-
requires=lambda m, s: m[OUT].matches_type(TS[Mapping[str, m[SCALAR].py_type]])
83+
requires=lambda m: m[OUT].matches_type(TS[Mapping[str, m[SCALAR].py_type]])
8484
and all(m[SCALAR].matches(v.scalar_type()) for v in m[TS_SCHEMA].meta_data_schema.values()),
85-
resolvers={SCALAR: lambda m, s: m[OUT].value_scalar_tp.value_type},
86-
all_valid=lambda m, s: ("ts",) if s["__strict__"] else None,
85+
resolvers={SCALAR: lambda m: m[OUT].value_scalar_tp.value_type},
86+
all_valid=lambda m, __strict__: ("ts",) if __strict__ else None,
8787
)
8888
def convert_tsb_to_mapping(
8989
ts: TSB[TS_SCHEMA], to: Type[OUT] = DEFAULT[OUT], __strict__: bool = False
@@ -95,10 +95,10 @@ def convert_tsb_to_mapping(
9595

9696
@compute_node(
9797
overloads=convert,
98-
requires=lambda m, s: m[OUT].matches_type(TS[Mapping[str, m[SCALAR].py_type]])
98+
requires=lambda m: m[OUT].matches_type(TS[Mapping[str, m[SCALAR].py_type]])
9999
and all(m[SCALAR].matches(v.scalar_type()) for v in m[TS_SCHEMA].meta_data_schema.values()),
100-
resolvers={SCALAR: lambda m, s: m[OUT].value_scalar_tp.value_type},
101-
all_valid=lambda m, s: ("ts",) if s["__strict__"] else None,
100+
resolvers={SCALAR: lambda m: m[OUT].value_scalar_tp.value_type},
101+
all_valid=lambda m, __strict__: ("ts",) if __strict__ else None,
102102
)
103103
def convert_tsb_to_mapping(
104104
to: Type[OUT] = DEFAULT[OUT], __strict__: bool = False, **ts: TSB[TS_SCHEMA]
@@ -108,7 +108,7 @@ def convert_tsb_to_mapping(
108108

109109
@compute_node(
110110
overloads=collect,
111-
requires=lambda m, s: m[OUT].py_type in (TS[Mapping], TS[dict], TS[frozendict])
111+
requires=lambda m: m[OUT].py_type in (TS[Mapping], TS[dict], TS[frozendict])
112112
or m[OUT].matches_type(TS[Mapping[m[KEYABLE_SCALAR].py_type, m[SCALAR].py_type]]),
113113
valid=("key", "ts"),
114114
)
@@ -127,7 +127,7 @@ def collect_mapping(
127127

128128
@compute_node(
129129
overloads=collect,
130-
requires=lambda m, s: m[OUT].py_type in (TS[Mapping], TS[dict], TS[frozendict])
130+
requires=lambda m: m[OUT].py_type in (TS[Mapping], TS[dict], TS[frozendict])
131131
or m[OUT].matches_type(TS[Mapping[m[KEYABLE_SCALAR].py_type, m[SCALAR].py_type]]),
132132
valid=("key", "ts"),
133133
)
@@ -144,7 +144,7 @@ def collect_mapping_from_tuples(
144144
return prev | new
145145

146146

147-
@compute_node(overloads=emit, resolvers={OUT: lambda m, s: TS[m[SCALAR].py_type]})
147+
@compute_node(overloads=emit, resolvers={OUT: lambda m: TS[m[SCALAR].py_type]})
148148
def emit_mapping(
149149
ts: TS[Mapping[KEYABLE_SCALAR, SCALAR]],
150150
v_: Type[V] = DEFAULT[OUT],

hgraph/_impl/_operators/_conversion_operators/_set_conversion_operators.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
@compute_node(
2626
overloads=convert,
27-
requires=lambda m, s: m[OUT].py_type in (TS[Set], TS[set], TS[frozenset])
27+
requires=lambda m: m[OUT].py_type in (TS[Set], TS[set], TS[frozenset])
2828
or m[OUT].matches_type(TS[Set[m[SCALAR].py_type]]),
2929
)
3030
def convert_ts_to_set(ts: TS[SCALAR], to: Type[OUT] = DEFAULT[OUT]) -> TS[Set[SCALAR]]:
@@ -33,7 +33,7 @@ def convert_ts_to_set(ts: TS[SCALAR], to: Type[OUT] = DEFAULT[OUT]) -> TS[Set[SC
3333

3434
@compute_node(
3535
overloads=convert,
36-
requires=lambda m, s: m[OUT].py_type in (TS[Set], TS[set], TS[frozenset])
36+
requires=lambda m: m[OUT].py_type in (TS[Set], TS[set], TS[frozenset])
3737
or m[OUT].matches_type(TS[Set[m[SCALAR].py_type]]),
3838
)
3939
def convert_tuple_to_set(ts: TS[Tuple[SCALAR, ...]], to: Type[OUT] = DEFAULT[OUT]) -> TS[Set[SCALAR]]:
@@ -42,7 +42,7 @@ def convert_tuple_to_set(ts: TS[Tuple[SCALAR, ...]], to: Type[OUT] = DEFAULT[OUT
4242

4343
@compute_node(
4444
overloads=convert,
45-
requires=lambda m, s: m[OUT].py_type in (TS[Set], TS[set], TS[frozenset])
45+
requires=lambda m: m[OUT].py_type in (TS[Set], TS[set], TS[frozenset])
4646
or m[OUT].matches_type(TS[Set[m[SCALAR].py_type]]),
4747
)
4848
def convert_tss_to_set(ts: TSS[SCALAR], to: Type[OUT] = DEFAULT[OUT]) -> TS[Set[SCALAR]]:
@@ -51,7 +51,7 @@ def convert_tss_to_set(ts: TSS[SCALAR], to: Type[OUT] = DEFAULT[OUT]) -> TS[Set[
5151

5252
@compute_node(
5353
overloads=collect,
54-
requires=lambda m, s: m[OUT].py_type in (TS[Set], TS[set], TS[frozenset])
54+
requires=lambda m: m[OUT].py_type in (TS[Set], TS[set], TS[frozenset])
5555
or m[OUT].matches_type(TS[Set[m[SCALAR].py_type]]),
5656
valid=("ts",),
5757
)
@@ -65,7 +65,7 @@ def collect_set(
6565

6666
@compute_node(
6767
overloads=collect,
68-
requires=lambda m, s: m[OUT].py_type in (TS[Set], TS[set], TS[frozenset])
68+
requires=lambda m: m[OUT].py_type in (TS[Set], TS[set], TS[frozenset])
6969
or m[OUT].matches_type(TS[Set[m[SCALAR].py_type]]),
7070
valid=("ts",),
7171
)

0 commit comments

Comments
 (0)