nebius/SWE-bench-extra huggingface dataset:
Repository: simonsobs/ocs

Issue:
Add boolean support to OCS feeds
Once Bool support is added to so3g (https://github.com/simonsobs/so3g/issues/116)  `Feed.verify_message_data_type` should be updated to support bools.

Comments:

Patch:
diff --git a/Dockerfile b/Dockerfile
index 49d1f0d..6b7bc59 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -2,7 +2,7 @@
 # A container setup with an installation of ocs.
 
 # Use ubuntu base image
-FROM simonsobs/so3g:v0.1.0-117-g75c1d8d
+FROM simonsobs/so3g:v0.1.3-13-g5471f0d
 
 # Set locale
 ENV LANG C.UTF-8
diff --git a/ocs/ocs_feed.py b/ocs/ocs_feed.py
index 0e59b49..934e727 100644
--- a/ocs/ocs_feed.py
+++ b/ocs/ocs_feed.py
@@ -248,17 +248,15 @@ class Feed:
         supported types.
 
         Args:
-            value (list, float, int):
+            value (list, float, int, bool):
                 'data' dictionary value published (see Feed.publish_message for details).
 
         """
-        valid_types = (float, int, str)
+        valid_types = (float, int, str, bool)
 
-        # separate bool checks since bool is a subclass of int
         # multi-sample check
         if isinstance(value, list):
-            if (any(isinstance(x, bool) for x in value)
-                    or not all(isinstance(x, valid_types) for x in value)):
+            if not all(isinstance(x, valid_types) for x in value):
                 type_set = set([type(x) for x in value])
                 invalid_types = type_set.difference(valid_types)
                 raise TypeError("message 'data' block contains invalid data" +
@@ -266,7 +264,7 @@ class Feed:
 
         # single sample check
         else:
-            if isinstance(value, bool) or not isinstance(value, valid_types):
+            if not isinstance(value, valid_types):
                 invalid_type = type(value)
                 raise TypeError("message 'data' block contains invalid " +
                                 f"data type: {invalid_type}")


Test patch:
diff --git a/tests/test_ocs_feed.py b/tests/test_ocs_feed.py
index b6ec529..d5869ca 100644
--- a/tests/test_ocs_feed.py
+++ b/tests/test_ocs_feed.py
@@ -76,8 +76,7 @@ class TestPublishMessage:
             }
         }
 
-        with pytest.raises(TypeError):
-            test_feed.publish_message(test_message)
+        test_feed.publish_message(test_message)
 
     def test_bool_multi_sample_input(self):
         mock_agent = MagicMock()
@@ -91,6 +90,21 @@ class TestPublishMessage:
             }
         }
 
+        test_feed.publish_message(test_message)
+
+    def test_invalid_single_sample_input(self):
+        mock_agent = MagicMock()
+        test_feed = ocs_feed.Feed(mock_agent, 'test_feed', record=True)
+
+        test_message = {
+            'block_name': 'test',
+            'timestamps': time.time(),
+            'data': {
+                'key1': 1.,
+                'key2': None,
+            }
+        }
+
         with pytest.raises(TypeError):
             test_feed.publish_message(test_message)
Repository: simonsobs/ocs

Issue:
param decorator doen't support type check on tuples
For context, this came up in socs on the ACU Agent.

When using the param decorator, if trying to type check a tuple, i.e.:
```
@ocs_agent.param('azpts', type=tuple)
```

Before the check occurs the input parameter value is converted to and from json, effectively casting it to a list. This results in a failed type check, for example:
```
>>> resp = client.constant_velocity_scan(azpts=(20., 120.), el=35., azvel=2., acc=2., ntimes=8, azonly=False, simulator=True)
>>> print(resp)
OCSReply: ERROR : Param 'azpts'=[20.0, 120.0] is not of required type (<class 'tuple'>)
```

We should check if the type is `tuple` and cast before the check within this if block: https://github.com/simonsobs/ocs/blob/076105e9613ef78745d37df3d9bf8a38ce1e28bd/ocs/ocs_agent.py#L1221

Comments:

Patch:
diff --git a/ocs/ocs_agent.py b/ocs/ocs_agent.py
index fc06a6e..8238a4f 100644
--- a/ocs/ocs_agent.py
+++ b/ocs/ocs_agent.py
@@ -1389,6 +1389,9 @@ class ParamHandler:
                 # Free cast from int to float.
                 if type is float and isinstance(value, int):
                     value = float(value)
+                # Fix type after json conversion
+                if type is tuple and isinstance(value, list) and cast in [tuple, None]:
+                    value = tuple(value)
                 if not isinstance(value, type):
                     raise ParamError(f"Param '{key}'={value} is not of required type ({type})")
             if choices is not None:


Test patch:
diff --git a/tests/test_ocs_agent.py b/tests/test_ocs_agent.py
index e6c1a83..be213ce 100644
--- a/tests/test_ocs_agent.py
+++ b/tests/test_ocs_agent.py
@@ -503,12 +503,14 @@ def test_params_get():
         'float_param': 1e8,
         'numerical_string_param': '145.12',
         'none_param': None,
+        'tuple_param': [20., 120.],  # gets cast to list by json conversion
     })
 
     # Basic successes
     params.get('int_param', type=int)
     params.get('string_param', type=str)
     params.get('float_param', type=float)
+    params.get('tuple_param', type=tuple)
 
     # Tricky successes
     params.get('int_param', type=float)