Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions csp/impl/wiring/signature.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,15 +195,20 @@ def parse_inputs(self, forced_tvars, *args, allow_none_ts=False, **kwargs):
if declared_type.__args__[0].typ is float:
from csp.baselib import cast_int_to_float

resolved_input[j] = cast_int_to_float(resolved_input[j])
# Copy once before casting a basket that may alias the caller's input.
if resolved_ts_inputs[i] is resolved_input:
resolved_ts_inputs[i] = resolved_input.copy()
resolved_ts_inputs[i][j] = cast_int_to_float(edge)
elif isinstance(resolved_input, dict):
declared_type = GenericValuesResolver.resolve_generic_values(input.typ, tvars)
for k, edge in resolved_input.items():
if edge.tstype.typ is int:
if declared_type.__args__[1].typ is float:
from csp.baselib import cast_int_to_float

resolved_input[k] = cast_int_to_float(resolved_input[k])
if resolved_ts_inputs[i] is resolved_input:
resolved_ts_inputs[i] = resolved_input.copy()
resolved_ts_inputs[i][k] = cast_int_to_float(edge)

return tuple(type_resolver.ts_inputs), tuple(type_resolver.scalar_inputs), type_resolver.tvars

Expand Down
42 changes: 42 additions & 0 deletions csp/tests/test_type_checking.py
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,48 @@ def graph():

build_graph(graph)

def test_graph_basket_cast_preserves_inputs(self):
@csp.graph
def accepts_float(x: Dict[str, ts[float]], y: List[ts[float]]) -> ts[bool]:
return csp.const(True)

def graph():
edge = csp.const(1)
x, y = {"a": edge}, [edge]
accepts_float(x, y)
self.assertIs(x["a"], edge)
self.assertIs(y[0], edge)
csp.cast_int_to_float(x["a"])
csp.cast_int_to_float(y[0])

build_graph(graph)

def test_node_basket_cast_preserves_inputs(self):
@csp.node
def accepts_float(x: Dict[str, ts[float]], y: List[ts[float]]) -> ts[float]:
if csp.ticked(x, y):
self.assertIs(type(x["a"]), float)
self.assertIs(type(x["b"]), float)
self.assertIs(type(y[0]), float)
self.assertIs(type(y[1]), float)
return x["a"] + x["b"] + x["c"] + y[0] + y[1] + y[2]

def graph():
integer, other_integer, floating = csp.const(1), csp.const(2), csp.const(2.5)
x, y = {"a": integer, "b": other_integer, "c": floating}, [integer, other_integer, floating]
result = accepts_float(x, y)
self.assertIs(x["a"], integer)
self.assertIs(x["b"], other_integer)
self.assertIs(x["c"], floating)
self.assertIs(y[0], integer)
self.assertIs(y[1], other_integer)
self.assertIs(y[2], floating)
return result

result = csp.run(graph, starttime=datetime(2020, 1, 1), endtime=timedelta())
self.assertEqual(result[0][0][1], 11.0)
self.assertIs(type(result[0][0][1]), float)

def test_basket_type_check_bug(self):
# Tests a bug that wasn't covered in the initial implementation. The code below was crashing on _ForwardRef before the fix
@csp.node
Expand Down