Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

run conversion: Use context manager only in append mode #1180

Merged
merged 21 commits into from
Jan 24, 2025

Conversation

h-mayorquin
Copy link
Collaborator

@h-mayorquin h-mayorquin commented Jan 17, 2025

This change addresses issues like bug #1114.

This also fixes #1159 by adding proper error messages.

Moreover, this fixes #1183 as the context manager interprets a faulty file on nwbfile_path as intent to use append mode.

To add more description to #1114, the core problem lies in the risk of creating a new interface without adhering to the implicit contract for importing extensions during initialization. This PR eliminates the possibility of unintentionally introducing subtle, hard-to-detect bugs. Furthermore, as highlighted in the discussion of #1143, the logic without a context manager is simpler to understand and covers approximately 95% of use cases.

@h-mayorquin h-mayorquin self-assigned this Jan 17, 2025
@h-mayorquin h-mayorquin marked this pull request as ready for review January 21, 2025 14:34
@@ -131,23 +131,13 @@ def test_run_conversion_with_backend(self, setup_interface, tmp_path, backend):
io.read()

@pytest.mark.parametrize("backend", ["hdf5", "zarr"])
def test_run_conversion_with_backend_configuration(self, setup_interface, tmp_path, backend):
def test_create_backend_configuration(self, setup_interface, tmp_path, backend):
Copy link
Collaborator Author

@h-mayorquin h-mayorquin Jan 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those tests were not doing anything. See the bug described here:

#1159

And if we were to make them work they would be duplicating a test that is already run in two other places.

So I changed the name to reflect what the test was actually doing but I would be fine with removing them entirely.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this test be checking that run_conversion runs properly when you pass a custom backend_configuration? How is this redundant with the other tests? What am I missing here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you are right, it is not redundant especially if I change both converter and interface versions.

Thinking about this I do want to get rid of these tests completely but I will open another PR describing my reasoning as I don't want this to get in the way.

I will revert this to just eliminate the passing of the nwbfile which does not make sense.

Copy link
Member

@pauladkisson pauladkisson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good!

I just suggested a small fix for the ValueError and some clarification about test_run_conversion_with_backend_configuration

Comment on lines 211 to 215
if appending_to_disk_nwbfile:
raise ValueError(
"Cannot append to an existing file while also providing an in-memory NWBFile. "
"Either set overwrite=True to replace the existing file, or remove the nwbfile parameter to append to the existing file on disk."
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to raise this value error right at the beginning for clarity. Also, I think it should be

if appending_to_disk_nwbfile and appending_to_in_memory_nwbfile:
    raise ValueError(...)

right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition was wrong, I fixed it now. Thanks.

I would like the error to be nested in the apend mode branch. I am also coming at this from the clarity angle but with a different reasoning.

People who read the code should not be bothered with the complexities of the apend case unless they get to that branch. In most cases, run_conversion is working as a write_to_nwbfile (which I think should be a method!) and I don't want the first reading of the function to introduce unrelated complexities.

Copy link
Member

@pauladkisson pauladkisson Jan 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really disagree. This is input validation for the function, so it should go right at the top with the inputs. By having in the append branch it's more nested, and to understand the condition you have to combine an else with a not: else(not appending_to_in_disk_nwbfile) + appending_to_in_memory_file. In contrast, I don't think it is hard to understand at all that appending_to_in_memory_nwbfile and appending_to_in_disk_nwbfile can't both be true at the same time --> ValueError, even without understanding anything about the details of those branches.

With all that being said, this is just style, so if you are still adamant about keeping it where it is, I won't insist.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those are good points. I will move it.

I still have the lingering feeling of wanting to push the complexities of appending mode outside of the happy path but maybe I should push for a write_to_nwbfile functionality outside of this PR. I think should be easier to read, use, and document for both developers and users.

run_conversion, like the context manager here, has too many responsibilities which leads to too many arguments an anti-pattern and a code smell.

Copy link
Member

@pauladkisson pauladkisson Jan 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still have the lingering feeling of wanting to push the complexities of appending mode outside of the happy path but maybe I should push for a write_to_nwbfile functionality outside of this PR. I think should be easier to read, use, and document for both developers and users.

run_conversion, like the context manager here, has too many responsibilities which leads to too many arguments an anti-pattern and a code smell.

Yep, isolating the complexity of append mode makes sense to me. I look forward to seeing those changes, and lmk if you need any help.

Comment on lines 274 to 278
if appending_to_disk_nwbfile:
raise ValueError(
"Cannot append to an existing file while also providing an in-memory NWBFile. "
"Either set overwrite=True to replace the existing file, or remove the nwbfile parameter to append to the existing file on disk."
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as with basedatainterface

@@ -131,23 +131,13 @@ def test_run_conversion_with_backend(self, setup_interface, tmp_path, backend):
io.read()

@pytest.mark.parametrize("backend", ["hdf5", "zarr"])
def test_run_conversion_with_backend_configuration(self, setup_interface, tmp_path, backend):
def test_create_backend_configuration(self, setup_interface, tmp_path, backend):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this test be checking that run_conversion runs properly when you pass a custom backend_configuration? How is this redundant with the other tests? What am I missing here?

@h-mayorquin
Copy link
Collaborator Author

This will also fix #1183

@h-mayorquin h-mayorquin changed the title Fix #1143 Use context manager only in append mode Jan 23, 2025
@h-mayorquin h-mayorquin changed the title Use context manager only in append mode run conversion: Use context manager only in append mode Jan 23, 2025
@h-mayorquin h-mayorquin enabled auto-merge (squash) January 23, 2025 18:43
@h-mayorquin h-mayorquin merged commit ce63b7c into main Jan 24, 2025
40 checks passed
@h-mayorquin h-mayorquin deleted the avoid_context_for_plain_writing branch January 24, 2025 02:50
Copy link

codecov bot commented Jan 24, 2025

Codecov Report

Attention: Patch coverage is 62.50000% with 12 lines in your changes missing coverage. Please review.

Project coverage is 89.58%. Comparing base (96dfdff) to head (37740c8).
Report is 26 commits behind head on main.

Files with missing lines Patch % Lines
src/neuroconv/basedatainterface.py 64.70% 6 Missing ⚠️
src/neuroconv/nwbconverter.py 60.00% 6 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1180      +/-   ##
==========================================
- Coverage   90.69%   89.58%   -1.11%     
==========================================
  Files         129      129              
  Lines        8189     8357     +168     
==========================================
+ Hits         7427     7487      +60     
- Misses        762      870     +108     
Flag Coverage Δ
unittests 89.58% <62.50%> (-1.11%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...c/neuroconv/tools/testing/data_interface_mixins.py 95.65% <ø> (+0.09%) ⬆️
src/neuroconv/basedatainterface.py 80.21% <64.70%> (-15.13%) ⬇️
src/neuroconv/nwbconverter.py 81.94% <60.00%> (-13.02%) ⬇️

... and 19 files with indirect coverage changes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants