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

Don't attempt to use npe1 readers in napari.plugins._npe2.read #5739

Merged
merged 11 commits into from May 2, 2023

Conversation

p-j-smith
Copy link
Contributor

@p-j-smith p-j-smith commented Apr 17, 2023

Fixes/Closes

Closes #5738

Description

npe2 0.7.0 raises two different error messages if a reader fails to return data.

This pr ensures both messages are caught and swallowed to prevent the ValueError from being raised in the gui.

References

Type of change

  • Bug-fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How has this been tested?

  • added tests that cover changes
  • all tests pass with my change

Final checklist:

  • My PR is the minimum possible work for the desired functionality
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works
  • If I included new strings, I have used trans. to make them localizable.
    For more information see our translations guide.

@codecov
Copy link

codecov bot commented Apr 17, 2023

Codecov Report

Merging #5739 (ccfcc88) into main (49fee1d) will increase coverage by 0.03%.
The diff coverage is 100.00%.

@@            Coverage Diff             @@
##             main    #5739      +/-   ##
==========================================
+ Coverage   89.82%   89.85%   +0.03%     
==========================================
  Files         610      610              
  Lines       52131    52142      +11     
==========================================
+ Hits        46825    46851      +26     
+ Misses       5306     5291      -15     
Impacted Files Coverage Δ
napari/plugins/_npe2.py 91.83% <100.00%> (+0.11%) ⬆️
napari/plugins/_tests/test_npe2.py 100.00% <100.00%> (ø)

... and 10 files with indirect coverage changes

@brisvag
Copy link
Contributor

brisvag commented Apr 18, 2023

I know there's been past discussion on this, but I haven't been following, so sorry if this has been discussed already: why do we want to suppress those errors? They seem useful info to me.

@DragaDoncila
Copy link
Contributor

DragaDoncila commented Apr 18, 2023

@brisvag I commented in #5738 but I'll mention here too. In general we don't want to catch reading errors, and we've made changes on the npe2 side and in napari to make sure reader errors get surfaced sooner.

The original error we were catching here - the No readers returned data error is actually an indicator that no plugin was tried at all. We catch this so that we can continue looking for the correct plugin among npe1 plugins. We'd remove this behaviour alongside all other npe1 code.

As I mentioned on the issue, I played around with the opening behaviour this morning and it all behaved as expected so I'm waiting to hear back about the particular use case we've broken, and then we'll know more about what the best fix is.

@github-actions github-actions bot added the tests Something related to our tests label Apr 19, 2023
Copy link
Contributor

@DragaDoncila DragaDoncila left a comment

Choose a reason for hiding this comment

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

@p-j-smith I've left comments with what I think the approach should be. Let me know if this addresses the original behavior you were seeing! This is unfortunately somewhat of a bandaid fix, but the current state essentially breaks all npe1 readers, I think it's a better approach than the bigger refactor we really need.

# Catch both messages raised by npe2
# https://github.com/napari/npe2/blob/main/src/npe2/io_utils.py#L168-L173
plugin_name_msg = f"Plugin {plugin!r} was selected to open"
no_plugin_name_msg = "No readers returned data"
Copy link
Contributor

Choose a reason for hiding this comment

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

As I mentioned, I think we want to make sure we do raise the Plugin was selected to open error here - it's meant to indicate that the user selected a specific plugin, this plugin was tried, and it failed. Definitely we want to alert the user to this.

What I was missing before is that (because of the npe1 compatibility code) this function may be passed a non-npe2 plugin, and in that case, we don't want to raise an error because we still have npe1 plugins to try.

As such, I think we should instead add the following check to the top of this function (maybe below the stack assertion):

# plugin was passed but is not an npe2 reader
if plugin and plugin not in get_readers():
    return None

I would also add a comment above the "No readers returned data" check:

# plugin wasn't passed and no reader was found
if 'No readers returned data' not in str(e):
    raise

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the explanation - that makes a lot more sense that what I thought was happening. I assumed that the suppressed errors would somehow be raised here

I've added your suggestions and it works nicely!

Copy link
Contributor

Choose a reason for hiding this comment

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

I assumed that the suppressed errors would somehow be raised here

Ahh yes, that's a GUI specific bit of code to allow users to select a different plugin if their saved plugin for a given path failed. The tests above occur without the GUI (or even a napari viewer), so that piece of code doesn't get a chance to handle anything. Even in the GUI scenario that error would've been swallowed, and I think we'd instead get whatever error (if any) was thrown at the end of trying npe1 plugins.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ah I see, thanks for the further info :)

@@ -42,6 +42,12 @@ def test_read(mock_pm: 'TestPluginManager'):
assert _npe2.read(["some.randomext"], stack=True) is None
mock_pm.commands.get.assert_not_called()

mock_pm.commands.get.reset_mock()
assert (
_npe2.read(["some.randomext"], stack=True, plugin=PLUGIN_NAME) is None
Copy link
Contributor

Choose a reason for hiding this comment

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

Here we expect the ValueError to be raised, because the user chose an npe2 plugin but it didn't work. We should also add an additional test for a non npe2 plugin so:

    mock_pm.commands.get.reset_mock()
    assert (
        _npe2.read(["some.randomext"], stack=True, plugin='not-npe2-plugin') is None
    )
    mock_pm.commands.get.assert_not_called()

    with pytest.raises(ValueError, match=f"Plugin '{PLUGIN_NAME}' was selected"):
        _npe2.read(["some.randomext"], stack=True, plugin=PLUGIN_NAME)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added these tests and they're passing, thanks :)

@p-j-smith
Copy link
Contributor Author

as napari.plugins._npe2.read now returns if the plugin name is for an npe1 reader, should the npe1_path variable in this function be renamed?

@p-j-smith p-j-smith changed the title Catch errors raised by npe2 when a plugin reader fails to return data Don't attempt to use npe1 readers in napari.plugins._npe2.read Apr 20, 2023
@DragaDoncila
Copy link
Contributor

should the npe1_path variable in this function be renamed?

I think it's not a very descriptive name to begin with, having tracked down the original PR where it was added, but I don't think it's a worse name now than it was before - in the interest of minimal changes, I would just leave it. I expect this will just be one of the many places we'll need to refactor when we get rid of the npe1 compatibility layer.

@DragaDoncila DragaDoncila added bugfix PR with bugfix and removed tests Something related to our tests labels Apr 21, 2023
@DragaDoncila DragaDoncila added this to the 0.4.18 milestone Apr 21, 2023
)
mock_pm.commands.get.assert_not_called()

with pytest.raises(
Copy link
Contributor

Choose a reason for hiding this comment

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

oooops, sorry @p-j-smith min_req tests are failing now - we should split out and skip this test if npe2 < 0.7:

@pytest.mark.skipif(npe2.__version__ < '0.7.0', reason='Older versions of npe2 do not throw specific error.')
def test_read_with_plugin_failure(mock_pm: 'TestPluginManager'):
    with pytest.raises(
        ValueError, match=f"Plugin '{PLUGIN_NAME}' was selected"
    ):
        _npe2.read(["some.randomext"], stack=True, plugin=PLUGIN_NAME)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ooo thanks for spotting that and providing the new test

@github-actions github-actions bot added the tests Something related to our tests label Apr 21, 2023
Copy link
Contributor

@DragaDoncila DragaDoncila left a comment

Choose a reason for hiding this comment

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

I've just pulled this down locally and made sure it works, so I think we're good to go! Test failure looks unrelated but will confirm before merge.

@DragaDoncila
Copy link
Contributor

DragaDoncila commented May 2, 2023

Confirmed test failure is unrelated. I'm going to merge this now as I think it's important we get it in - otherwise non-shimmed npe1 readers are broken on main with latest npe2. Thanks for the contribution @p-j-smith 🎉 !

@DragaDoncila DragaDoncila merged commit 6847eee into napari:main May 2, 2023
32 of 33 checks passed
@p-j-smith
Copy link
Contributor Author

thanks for merging @DragaDoncila, and thanks for the review!

Czaki added a commit that referenced this pull request May 7, 2023
# Fixes/Closes

<!-- In general, PRs should fix an existing issue on the repo. -->
<!-- Please link to that issue here as "Closes #(issue-number)". -->
Closes #

# Description
<!-- What does this pull request (PR) do? Why is it necessary? -->
<!-- Tell us about your new feature, improvement, or fix! -->
<!-- If your change includes user interface changes, please add an
image, or an animation "An image is worth a thousand words!" -->
<!-- You can use https://www.cockos.com/licecap/ or similar to create
animations -->

This PR adds a check at the end of `test_worker_may_exceed_total` that
fails in #5739 in an unrelated way to PR topic.

# References
<!-- What resources, documentation, and guides were used in the creation
of this PR? -->

## Type of change
<!-- Please delete options that are not relevant. -->
- [x] Bug-fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- [ ] This change requires a documentation update

# How has this been tested?
<!-- Please describe the tests that you ran to verify your changes. -->
- [ ] example: the test suite for my feature covers cases x, y, and z
- [ ] example: all tests pass with my change
- [ ] example: I check if my changes works with both PySide and PyQt
backends
      as there are small differences between the two Qt bindings.  

## Final checklist:
- [ ] My PR is the minimum possible work for the desired functionality
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] If I included new strings, I have used `trans.` to make them
localizable.
For more information see our [translations
guide](https://napari.org/developers/translations.html).

---------

Co-authored-by: Draga Doncila Pop <17995243+DragaDoncila@users.noreply.github.com>
@Czaki Czaki mentioned this pull request Jun 7, 2023
Czaki pushed a commit that referenced this pull request Jun 19, 2023
# Fixes/Closes 

<!-- In general, PRs should fix an existing issue on the repo. -->
<!-- Please link to that issue here as "Closes #(issue-number)". -->
Closes #5738 

# Description
<!-- What does this pull request (PR) do? Why is it necessary? -->
<!-- Tell us about your new feature, improvement, or fix! -->
<!-- If your change includes user interface changes, please add an
image, or an animation "An image is worth a thousand words!" -->
<!-- You can use https://www.cockos.com/licecap/ or similar to create
animations -->

`npe2` 0.7.0 raises [two different error
messages](https://github.com/napari/npe2/blob/00d2bc227437a37f276c1ba9fad108a263504469/src/npe2/io_utils.py#L168-L173)
if a reader fails to return data.

This pr ensures both messages are caught and swallowed to prevent the
`ValueError` from being raised in the gui.

# References
<!-- What resources, documentation, and guides were used in the creation
of this PR? -->

## Type of change
<!-- Please delete options that are not relevant. -->
- [x] Bug-fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- [ ] This change requires a documentation update

# How has this been tested?
<!-- Please describe the tests that you ran to verify your changes. -->
- [x]  added tests that cover changes
- [x] all tests pass with my change

## Final checklist:
- [x] My PR is the minimum possible work for the desired functionality
- [x] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] If I included new strings, I have used `trans.` to make them
localizable.
For more information see our [translations
guide](https://napari.org/developers/translations.html).

---------

Co-authored-by: Draga Doncila Pop <17995243+DragaDoncila@users.noreply.github.com>
Czaki pushed a commit that referenced this pull request Jun 21, 2023
# Fixes/Closes 

<!-- In general, PRs should fix an existing issue on the repo. -->
<!-- Please link to that issue here as "Closes #(issue-number)". -->
Closes #5738 

# Description
<!-- What does this pull request (PR) do? Why is it necessary? -->
<!-- Tell us about your new feature, improvement, or fix! -->
<!-- If your change includes user interface changes, please add an
image, or an animation "An image is worth a thousand words!" -->
<!-- You can use https://www.cockos.com/licecap/ or similar to create
animations -->

`npe2` 0.7.0 raises [two different error
messages](https://github.com/napari/npe2/blob/00d2bc227437a37f276c1ba9fad108a263504469/src/npe2/io_utils.py#L168-L173)
if a reader fails to return data.

This pr ensures both messages are caught and swallowed to prevent the
`ValueError` from being raised in the gui.

# References
<!-- What resources, documentation, and guides were used in the creation
of this PR? -->

## Type of change
<!-- Please delete options that are not relevant. -->
- [x] Bug-fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- [ ] This change requires a documentation update

# How has this been tested?
<!-- Please describe the tests that you ran to verify your changes. -->
- [x]  added tests that cover changes
- [x] all tests pass with my change

## Final checklist:
- [x] My PR is the minimum possible work for the desired functionality
- [x] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] If I included new strings, I have used `trans.` to make them
localizable.
For more information see our [translations
guide](https://napari.org/developers/translations.html).

---------

Co-authored-by: Draga Doncila Pop <17995243+DragaDoncila@users.noreply.github.com>
Czaki pushed a commit that referenced this pull request Jun 21, 2023
# Fixes/Closes 

<!-- In general, PRs should fix an existing issue on the repo. -->
<!-- Please link to that issue here as "Closes #(issue-number)". -->
Closes #5738 

# Description
<!-- What does this pull request (PR) do? Why is it necessary? -->
<!-- Tell us about your new feature, improvement, or fix! -->
<!-- If your change includes user interface changes, please add an
image, or an animation "An image is worth a thousand words!" -->
<!-- You can use https://www.cockos.com/licecap/ or similar to create
animations -->

`npe2` 0.7.0 raises [two different error
messages](https://github.com/napari/npe2/blob/00d2bc227437a37f276c1ba9fad108a263504469/src/npe2/io_utils.py#L168-L173)
if a reader fails to return data.

This pr ensures both messages are caught and swallowed to prevent the
`ValueError` from being raised in the gui.

# References
<!-- What resources, documentation, and guides were used in the creation
of this PR? -->

## Type of change
<!-- Please delete options that are not relevant. -->
- [x] Bug-fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- [ ] This change requires a documentation update

# How has this been tested?
<!-- Please describe the tests that you ran to verify your changes. -->
- [x]  added tests that cover changes
- [x] all tests pass with my change

## Final checklist:
- [x] My PR is the minimum possible work for the desired functionality
- [x] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] If I included new strings, I have used `trans.` to make them
localizable.
For more information see our [translations
guide](https://napari.org/developers/translations.html).

---------

Co-authored-by: Draga Doncila Pop <17995243+DragaDoncila@users.noreply.github.com>
Czaki pushed a commit that referenced this pull request Jun 21, 2023
# Fixes/Closes 

<!-- In general, PRs should fix an existing issue on the repo. -->
<!-- Please link to that issue here as "Closes #(issue-number)". -->
Closes #5738 

# Description
<!-- What does this pull request (PR) do? Why is it necessary? -->
<!-- Tell us about your new feature, improvement, or fix! -->
<!-- If your change includes user interface changes, please add an
image, or an animation "An image is worth a thousand words!" -->
<!-- You can use https://www.cockos.com/licecap/ or similar to create
animations -->

`npe2` 0.7.0 raises [two different error
messages](https://github.com/napari/npe2/blob/00d2bc227437a37f276c1ba9fad108a263504469/src/npe2/io_utils.py#L168-L173)
if a reader fails to return data.

This pr ensures both messages are caught and swallowed to prevent the
`ValueError` from being raised in the gui.

# References
<!-- What resources, documentation, and guides were used in the creation
of this PR? -->

## Type of change
<!-- Please delete options that are not relevant. -->
- [x] Bug-fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- [ ] This change requires a documentation update

# How has this been tested?
<!-- Please describe the tests that you ran to verify your changes. -->
- [x]  added tests that cover changes
- [x] all tests pass with my change

## Final checklist:
- [x] My PR is the minimum possible work for the desired functionality
- [x] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] If I included new strings, I have used `trans.` to make them
localizable.
For more information see our [translations
guide](https://napari.org/developers/translations.html).

---------

Co-authored-by: Draga Doncila Pop <17995243+DragaDoncila@users.noreply.github.com>
psobolewskiPhD added a commit to psobolewskiPhD/napari that referenced this pull request Jun 27, 2023
jni pushed a commit that referenced this pull request Jun 30, 2023
…plus add test (#6013)

# Fixes/Closes

Issue with 0.4.18rc2 reported on zulip by @adamltyson 

https://napari.zulipchat.com/#narrow/stream/212875-general/topic/reader.20plugin.20issue.20with.200.2E4.2E18

Closes #6012

# Description

In merged commit:
6847eee
the method of checking whether a plugin is npe2 returns None if a reader
is passed in addition to the plugin name, e.g. `my-plugin.some_reader`
vs. `my-plugin`
This is a regression for the case of plugins with multiple readers, as
reported on zulip:

https://napari.zulipchat.com/#narrow/stream/212875-general/topic/reader.20plugin.20issue.20with.200.2E4.2E18

This PR just changes the logic of the comparison so use `startswith` so
just the plugin name is compared, rather than the entire string. This
fixes the regression.
Also, I add a test for this condition that fails on main, but passes
with this fix.

# References
See:
https://napari.zulipchat.com/#narrow/stream/212875-general/topic/reader.20plugin.20issue.20with.200.2E4.2E18
Czaki pushed a commit that referenced this pull request Jun 30, 2023
…plus add test (#6013)

# Fixes/Closes

Issue with 0.4.18rc2 reported on zulip by @adamltyson 

https://napari.zulipchat.com/#narrow/stream/212875-general/topic/reader.20plugin.20issue.20with.200.2E4.2E18

Closes #6012

# Description

In merged commit:
6847eee
the method of checking whether a plugin is npe2 returns None if a reader
is passed in addition to the plugin name, e.g. `my-plugin.some_reader`
vs. `my-plugin`
This is a regression for the case of plugins with multiple readers, as
reported on zulip:

https://napari.zulipchat.com/#narrow/stream/212875-general/topic/reader.20plugin.20issue.20with.200.2E4.2E18

This PR just changes the logic of the comparison so use `startswith` so
just the plugin name is compared, rather than the entire string. This
fixes the regression.
Also, I add a test for this condition that fails on main, but passes
with this fix.

# References
See:
https://napari.zulipchat.com/#narrow/stream/212875-general/topic/reader.20plugin.20issue.20with.200.2E4.2E18
melissawm pushed a commit to melissawm/napari that referenced this pull request Jul 3, 2023
…eader plus add test (napari#6013)

# Fixes/Closes

Issue with 0.4.18rc2 reported on zulip by @adamltyson 

https://napari.zulipchat.com/#narrow/stream/212875-general/topic/reader.20plugin.20issue.20with.200.2E4.2E18

Closes napari#6012

# Description

In merged commit:
napari@6847eee
the method of checking whether a plugin is npe2 returns None if a reader
is passed in addition to the plugin name, e.g. `my-plugin.some_reader`
vs. `my-plugin`
This is a regression for the case of plugins with multiple readers, as
reported on zulip:

https://napari.zulipchat.com/#narrow/stream/212875-general/topic/reader.20plugin.20issue.20with.200.2E4.2E18

This PR just changes the logic of the comparison so use `startswith` so
just the plugin name is compared, rather than the entire string. This
fixes the regression.
Also, I add a test for this condition that fails on main, but passes
with this fix.

# References
See:
https://napari.zulipchat.com/#narrow/stream/212875-general/topic/reader.20plugin.20issue.20with.200.2E4.2E18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugfix PR with bugfix tests Something related to our tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

npe1 plugin readers broken by npe2 0.7.0
3 participants