Skip to content

Commit

Permalink
Fix writer order preference (#172)
Browse files Browse the repository at this point in the history
* fixes #129

* remove docstring

* fix test

* use _writer key
  • Loading branch information
tlambert03 authored Jun 12, 2022
1 parent 6b1cd1e commit 5b46570
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 16 deletions.
21 changes: 6 additions & 15 deletions npe2/_plugin_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,32 +153,23 @@ def _get_candidates(lt: LayerType) -> Set[WriterContribution]:
if layer == lt and (min_ <= counts[lt] < max_)
}

candidates = {w for _, _, _, w in self._writers}
# keep ordered without duplicates
candidates = list({w: None for _, _, _, w in self._writers})
for lt in LayerType:
if candidates:
candidates &= _get_candidates(lt)
candidates = [i for i in candidates if i in _get_candidates(lt)]
else:
break

def _writer_key(writer: WriterContribution) -> Tuple[bool, int, int, List[str]]:
def _writer_key(writer: WriterContribution) -> Tuple[bool, int]:
# 1. writers with no file extensions (like directory writers) go last
no_ext = len(writer.filename_extensions) == 0

# 2. more "specific" writers first
nbounds = sum(not c.is_zero() for c in writer.layer_type_constraints())
return (no_ext, nbounds)

# 3. then sort by the number of listed extensions
# (empty set of extensions goes last)
ext_len = len(writer.filename_extensions)

# 4. finally group related extensions together
exts = writer.filename_extensions
return (no_ext, nbounds, ext_len, exts)

yield from sorted(
candidates,
key=_writer_key,
)
yield from sorted(candidates, key=_writer_key)


class PluginManagerEvents(SignalGroup):
Expand Down
19 changes: 18 additions & 1 deletion tests/test_contributions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import pytest

from npe2 import PluginManager, PluginManifest
from npe2 import DynamicPlugin, PluginManager, PluginManifest
from npe2.manifest.contributions import (
CommandContribution,
SampleDataGenerator,
Expand Down Expand Up @@ -41,6 +41,23 @@ def test_writer_ranges(param, uses_sample_plugin, plugin_manager: PluginManager)
assert nwriters == expected_count


def test_writer_priority():
"""Contributions listed earlier in the manifest should be preferred."""
pm = PluginManager()
with DynamicPlugin(name="my_plugin", plugin_manager=pm) as plg:

@plg.contribute.writer(filename_extensions=["*.tif"], layer_types=["image"])
def my_writer1(path, data):
...

@plg.contribute.writer(filename_extensions=["*.abc"], layer_types=["image"])
def my_writer2(path, data):
...

writers = list(pm.iter_compatible_writers(["image"]))
assert writers[0].command == "my_plugin.my_writer1"


@pytest.mark.parametrize(
"expr",
["vectors", "vectors+", "vectors*", "vectors?", "vectors{3}", "vectors{3,8}"],
Expand Down

0 comments on commit 5b46570

Please sign in to comment.