Repository: aeye-lab/pymovements
Pull request #669 (2024-01-30 15:49:53)

feat!: enforce list of strings for GazeDataFrame.trial_columns attribute
## Description

Although GazeDataFrame accepts a single string for passing `trial_columns`, enforcing a list of strings as the resulting attribute `GazeDataFrame.trial_columns` simplifies internal usage in #655

As a side effect, this could also get rid of the depraction warning in #667

## Implemented changes

- [x] create list of string in case `trial_columns` is of type string

## Type of change

- [x] New feature (non-breaking change which adds functionality)
- [x] Breaking change (fix or feature that would cause existing functionality to not work as expected)

## How Has This Been Tested?

- [x] add test for str
- [x] add test for list of single str
- [x] add test for list of two strings

## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my feature works
- [x] New and existing unit tests pass locally with my changes
- [x] Any dependent changes have been merged and published in downstream modules
- [x] I have checked my code and corrected any misspellings


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/aeye-lab/pymovements/pull/669?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aeye-lab) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Comparison is base [(`250c0f5`)](https://app.codecov.io/gh/aeye-lab/pymovements/commit/250c0f5fef5f4ec3aeebba86ff52076ad136c034?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aeye-lab) 100.00% compared to head [(`2da0287`)](https://app.codecov.io/gh/aeye-lab/pymovements/pull/669?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aeye-lab) 100.00%.


<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff            @@
##              main      #669   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           54        54           
  Lines         2357      2357           
  Branches       588       588           
=========================================
  Hits          2357      2357           
```



</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/aeye-lab/pymovements/pull/669?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aeye-lab).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aeye-lab).


Patch:
diff --git a/src/pymovements/gaze/gaze_dataframe.py b/src/pymovements/gaze/gaze_dataframe.py
index 19ed593..b012cb4 100644
--- a/src/pymovements/gaze/gaze_dataframe.py
+++ b/src/pymovements/gaze/gaze_dataframe.py
@@ -238,7 +238,7 @@ class GazeDataFrame:
             data = data.clone()
         self.frame = data
 
-        self.trial_columns = trial_columns
+        self.trial_columns = [trial_columns] if isinstance(trial_columns, str) else trial_columns
 
         # In case the 'time' column is already present we don't need to do anything.
         # Otherwise, create a new time column starting with zero.


Test patch:
diff --git a/tests/unit/gaze/gaze_init_test.py b/tests/unit/gaze/gaze_init_test.py
index 0aef889..016e397 100644
--- a/tests/unit/gaze/gaze_init_test.py
+++ b/tests/unit/gaze/gaze_init_test.py
@@ -776,7 +776,53 @@ def test_init_gaze_dataframe_has_expected_attrs(init_kwargs, expected_frame, exp
     assert gaze.n_components == expected_n_components
 
 
-@ pytest.mark.parametrize(
+@pytest.mark.parametrize(
+    ('init_kwargs', 'expected_trial_columns'),
+    [
+        pytest.param(
+            {
+                'data': pl.from_dict(
+                    data={'trial': [1]},
+                    schema={'trial': pl.Int64},
+                ),
+                'trial_columns': 'trial',
+            },
+            ['trial'],
+            id='df_single_trial_column_str',
+        ),
+
+        pytest.param(
+            {
+                'data': pl.from_dict(
+                    data={'trial': [1]},
+                    schema={'trial': pl.Int64},
+                ),
+                'trial_columns': ['trial'],
+            },
+            ['trial'],
+            id='df_single_trial_column_list',
+        ),
+
+        pytest.param(
+            {
+                'data': pl.from_dict(
+                    {'group': [2], 'trial': [1]},
+                    schema={'group': pl.Int64, 'trial': pl.Int64},
+                ),
+                'trial_columns': ['group', 'trial'],
+            },
+            ['group', 'trial'],
+            id='df_two_trial_columns',
+        ),
+
+    ],
+)
+def test_init_gaze_dataframe_has_expected_trial_columns(init_kwargs, expected_trial_columns):
+    gaze = pm.GazeDataFrame(**init_kwargs)
+    assert gaze.trial_columns == expected_trial_columns
+
+
+@pytest.mark.parametrize(
     ('init_kwargs', 'exception', 'exception_msg'),
     [
         pytest.param(
@@ -1262,7 +1308,7 @@ def test_gaze_copy_init_has_same_n_components():
     assert gaze.n_components == gaze_copy.n_components
 
 
-@ pytest.mark.parametrize(
+@pytest.mark.parametrize(
     ('events', 'init_kwargs'),
     [
         pytest.param(
diff --git a/tests/unit/gaze/integration_numpy_test.py b/tests/unit/gaze/integration_numpy_test.py
index fac979e..ca3f2de 100644
--- a/tests/unit/gaze/integration_numpy_test.py
+++ b/tests/unit/gaze/integration_numpy_test.py
@@ -169,7 +169,7 @@ def test_from_numpy_with_trial_id():
 
     assert_frame_equal(gaze.frame, expected)
     assert gaze.n_components == 2
-    assert gaze.trial_columns == 'trial_id'
+    assert gaze.trial_columns == ['trial_id']
 
 
 def test_from_numpy_explicit_columns():
@@ -249,7 +249,7 @@ def test_from_numpy_explicit_columns_with_trial():
 
     assert_frame_equal(gaze.frame, expected)
     assert gaze.n_components == 2
-    assert gaze.trial_columns == 'trial'
+    assert gaze.trial_columns == ['trial']
 
 
 def test_from_numpy_all_none():
diff --git a/tests/unit/gaze/integration_pandas_test.py b/tests/unit/gaze/integration_pandas_test.py
index 506a77c..9a1ed03 100644
--- a/tests/unit/gaze/integration_pandas_test.py
+++ b/tests/unit/gaze/integration_pandas_test.py
@@ -107,7 +107,7 @@ def test_from_pandas_with_trial_columnms():
     })
 
     assert_frame_equal(gaze.frame, expected)
-    assert gaze.trial_columns == 'trial_id'
+    assert gaze.trial_columns == ['trial_id']
 
 
 @pytest.mark.parametrize(