npe2 0.7.8rc0__py3-none-any.whl → 0.7.9rc0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- npe2/_inspection/_fetch.py +40 -2
- npe2/cli.py +11 -1
- npe2/io_utils.py +1 -1
- npe2/manifest/_npe1_adapter.py +1 -1
- npe2/manifest/contributions/_contributions.py +9 -2
- npe2/manifest/contributions/_sample_data.py +3 -1
- npe2/manifest/contributions/_submenu.py +7 -0
- {npe2-0.7.8rc0.dist-info → npe2-0.7.9rc0.dist-info}/METADATA +2 -2
- {npe2-0.7.8rc0.dist-info → npe2-0.7.9rc0.dist-info}/RECORD +12 -12
- {npe2-0.7.8rc0.dist-info → npe2-0.7.9rc0.dist-info}/WHEEL +0 -0
- {npe2-0.7.8rc0.dist-info → npe2-0.7.9rc0.dist-info}/entry_points.txt +0 -0
- {npe2-0.7.8rc0.dist-info → npe2-0.7.9rc0.dist-info}/licenses/LICENSE +0 -0
npe2/_inspection/_fetch.py
CHANGED
|
@@ -160,9 +160,47 @@ def _get_manifest_from_zip_url(url: str) -> PluginManifest:
|
|
|
160
160
|
--------
|
|
161
161
|
$ npe2 fetch https://github.com/org/project/archive/refs/heads/master.zip
|
|
162
162
|
"""
|
|
163
|
+
from npe2.manifest import PluginManifest
|
|
164
|
+
|
|
165
|
+
def find_manifest_file(root: Path) -> Optional[Path]:
|
|
166
|
+
"""Recursively find a napari manifest file."""
|
|
167
|
+
# Check current directory for manifest files
|
|
168
|
+
for filename in ["napari.yaml", "napari.yml"]:
|
|
169
|
+
manifest_path = root / filename
|
|
170
|
+
if manifest_path.exists():
|
|
171
|
+
return manifest_path
|
|
172
|
+
|
|
173
|
+
# Check for pyproject.toml with napari config
|
|
174
|
+
pyproject_path = root / "pyproject.toml"
|
|
175
|
+
if pyproject_path.exists():
|
|
176
|
+
try:
|
|
177
|
+
import tomllib
|
|
178
|
+
except ImportError:
|
|
179
|
+
import tomli as tomllib # type: ignore
|
|
180
|
+
|
|
181
|
+
with open(pyproject_path, "rb") as f:
|
|
182
|
+
data = tomllib.load(f)
|
|
183
|
+
if "tool" in data and "napari" in data["tool"]:
|
|
184
|
+
return pyproject_path
|
|
185
|
+
|
|
186
|
+
# Recursively search subdirectories for the manifest file
|
|
187
|
+
for item in root.iterdir():
|
|
188
|
+
if item.is_dir() and not item.name.startswith("."):
|
|
189
|
+
result = find_manifest_file(item)
|
|
190
|
+
if result:
|
|
191
|
+
return result
|
|
192
|
+
return None
|
|
193
|
+
|
|
163
194
|
with _tmp_zip_download(url) as zip_path:
|
|
164
|
-
|
|
165
|
-
|
|
195
|
+
# In a zip file, we do not need to build a wheel. We can extract
|
|
196
|
+
# the manifest directly from the extracted files.
|
|
197
|
+
manifest_file = find_manifest_file(Path(zip_path))
|
|
198
|
+
if manifest_file:
|
|
199
|
+
return PluginManifest.from_file(manifest_file)
|
|
200
|
+
else:
|
|
201
|
+
# Keep original behavior to try to build a wheel as a fallback
|
|
202
|
+
src_dir = next(Path(zip_path).iterdir())
|
|
203
|
+
return _build_src_and_extract_manifest(src_dir)
|
|
166
204
|
|
|
167
205
|
|
|
168
206
|
def _get_manifest_from_wheel_url(url: str) -> PluginManifest:
|
npe2/cli.py
CHANGED
|
@@ -11,7 +11,11 @@ from npe2 import PluginManager, PluginManifest, __version__
|
|
|
11
11
|
if TYPE_CHECKING:
|
|
12
12
|
from rich.console import RenderableType
|
|
13
13
|
|
|
14
|
-
app = typer.Typer(
|
|
14
|
+
app = typer.Typer(
|
|
15
|
+
no_args_is_help=True,
|
|
16
|
+
context_settings={"help_option_names": ["-h", "--help"]},
|
|
17
|
+
rich_markup_mode="rich",
|
|
18
|
+
)
|
|
15
19
|
|
|
16
20
|
|
|
17
21
|
def _show_version_and_exit(value: bool) -> None:
|
|
@@ -498,4 +502,10 @@ def compile(
|
|
|
498
502
|
|
|
499
503
|
|
|
500
504
|
def main():
|
|
505
|
+
import sys
|
|
506
|
+
|
|
507
|
+
# If no arguments provided, show help without error box
|
|
508
|
+
if len(sys.argv) == 1:
|
|
509
|
+
sys.argv.append("--help")
|
|
510
|
+
|
|
501
511
|
app()
|
npe2/io_utils.py
CHANGED
|
@@ -319,5 +319,5 @@ def _write(
|
|
|
319
319
|
|
|
320
320
|
# napari_get_writer-style writers don't always return a list
|
|
321
321
|
# though strictly speaking they should?
|
|
322
|
-
result = [res] if isinstance(res, str) else res or []
|
|
322
|
+
result = [res] if isinstance(res, str) else res or []
|
|
323
323
|
return (result, writer) if return_writer else result
|
npe2/manifest/_npe1_adapter.py
CHANGED
|
@@ -8,7 +8,7 @@ from pathlib import Path
|
|
|
8
8
|
from shutil import rmtree
|
|
9
9
|
from typing import List, Sequence
|
|
10
10
|
|
|
11
|
-
from
|
|
11
|
+
from platformdirs import user_cache_dir
|
|
12
12
|
|
|
13
13
|
from npe2._inspection._from_npe1 import manifest_from_npe1
|
|
14
14
|
from npe2.manifest import PackageMetadata
|
|
@@ -36,8 +36,15 @@ class ContributionPoints(BaseModel):
|
|
|
36
36
|
widgets: Optional[List[WidgetContribution]]
|
|
37
37
|
sample_data: Optional[List[SampleDataContribution]]
|
|
38
38
|
themes: Optional[List[ThemeContribution]]
|
|
39
|
-
menus: Dict[str, List[MenuItem]] = Field(
|
|
40
|
-
|
|
39
|
+
menus: Dict[str, List[MenuItem]] = Field(
|
|
40
|
+
default_factory=dict,
|
|
41
|
+
description="Add menu items to existing napari menus."
|
|
42
|
+
"A menu item can be a command, such as open a widget, or a submenu."
|
|
43
|
+
"Using menu items, nested hierarchies can be created within napari menus."
|
|
44
|
+
"This allows you to organize your plugin's contributions within"
|
|
45
|
+
"napari's menu structure.",
|
|
46
|
+
)
|
|
47
|
+
submenus: Optional[List[SubmenuContribution]]
|
|
41
48
|
keybindings: Optional[List[KeyBindingContribution]] = Field(None, hide_docs=True)
|
|
42
49
|
|
|
43
50
|
configuration: List[ConfigurationContribution] = Field(
|
|
@@ -32,7 +32,9 @@ class SampleDataGenerator(_SampleDataContribution, Executable[List[LayerData]]):
|
|
|
32
32
|
"""Contribute a callable command that creates data on demand."""
|
|
33
33
|
|
|
34
34
|
command: str = Field(
|
|
35
|
-
...,
|
|
35
|
+
...,
|
|
36
|
+
description="Identifier of a command that returns layer data tuple. "
|
|
37
|
+
"Note that this command cannot return `[(None,)]`.",
|
|
36
38
|
)
|
|
37
39
|
|
|
38
40
|
def open(
|
|
@@ -6,6 +6,13 @@ from ._icon import Icon
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class SubmenuContribution(BaseModel):
|
|
9
|
+
"""Contributes a submenu that can contain menu items or other submenus.
|
|
10
|
+
|
|
11
|
+
Submenus allow you to organize menu items into hierarchical structures.
|
|
12
|
+
Each submenu defines an id, label, and optional icon that can be
|
|
13
|
+
referenced by menu items to create nested menu structures.
|
|
14
|
+
"""
|
|
15
|
+
|
|
9
16
|
id: str = Field(description="Identifier of the menu to display as a submenu.")
|
|
10
17
|
label: str = Field(
|
|
11
18
|
description="The label of the menu item which leads to this submenu."
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: npe2
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.9rc0
|
|
4
4
|
Summary: napari plugin engine v2
|
|
5
5
|
Project-URL: homepage, https://github.com/napari/npe2
|
|
6
6
|
Project-URL: repository, https://github.com/napari/npe2
|
|
@@ -19,8 +19,8 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
20
|
Classifier: Typing :: Typed
|
|
21
21
|
Requires-Python: >=3.8
|
|
22
|
-
Requires-Dist: appdirs
|
|
23
22
|
Requires-Dist: build>=1
|
|
23
|
+
Requires-Dist: platformdirs
|
|
24
24
|
Requires-Dist: psygnal>=0.3.0
|
|
25
25
|
Requires-Dist: pydantic
|
|
26
26
|
Requires-Dist: pyyaml
|
|
@@ -6,22 +6,22 @@ npe2/_plugin_manager.py,sha256=0sPujjzJqdx03e-BuXlnMv652OtO18-xyPuJAlva320,30694
|
|
|
6
6
|
npe2/_pydantic_compat.py,sha256=S7snBijrnYsIovWmlmiZ91bbQNmbLuftr8CUcDnek20,1152
|
|
7
7
|
npe2/_pytest_plugin.py,sha256=Dw73_eHFoBT_mivmFzr73ZGwBe1wwoSb790Mk1QlKn8,3610
|
|
8
8
|
npe2/_setuptools_plugin.py,sha256=VefF1gMcnRxA0yp8tSYkcoB4mkefaf7NST5f0PWHm-M,6786
|
|
9
|
-
npe2/cli.py,sha256=
|
|
9
|
+
npe2/cli.py,sha256=Q3SsDydPHzxxpGAm23JxBHQnp2yo4ZVYR-ug3hHU3dk,15637
|
|
10
10
|
npe2/implements.py,sha256=RmzTS42dCNPLfCKK29rXlLBQ0Gj7gz7A_ewbxKR_2X0,4023
|
|
11
11
|
npe2/implements.pyi,sha256=KcATek_BMxZGGlpd1yBgwBSFkeeJoJhX8S80GuprYRw,1392
|
|
12
|
-
npe2/io_utils.py,sha256=
|
|
12
|
+
npe2/io_utils.py,sha256=0jnCHWjHSpVeKEXDmsvBXywchxdx2r8JEWIImGB6wBc,10042
|
|
13
13
|
npe2/plugin_manager.py,sha256=e6egPx3H4tlyJ1fMJhske9uKCt1BdupAR6S-EBx1Afg,4466
|
|
14
14
|
npe2/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
15
|
npe2/types.py,sha256=3CCIQ84yTwUbc8rHBfvpMGgv7Fg968MFX-brXbbhk1I,2216
|
|
16
16
|
npe2/_inspection/__init__.py,sha256=Z23w_mB3aHP1AZlLYDB4OMHjgXQMuBAPzOIYEd1HuFk,295
|
|
17
17
|
npe2/_inspection/_compile.py,sha256=sIjcpyfgaETHrdrAB_jPyLHd2HxOuWdnKkDotXuOTk8,3941
|
|
18
|
-
npe2/_inspection/_fetch.py,sha256=
|
|
18
|
+
npe2/_inspection/_fetch.py,sha256=WA1kp8KrUThxXpI4GcKwC8l7jR-1X7bJzIalbB20Vgk,14298
|
|
19
19
|
npe2/_inspection/_from_npe1.py,sha256=WP4mvMouGxRr9KlDmcQNukzS6ScT3izF0WlAN1g91o8,23607
|
|
20
20
|
npe2/_inspection/_setuputils.py,sha256=EUnNq7rAJ4nVnMyaGztCufbT1JDxcJK3G9o3omqmd5U,4575
|
|
21
21
|
npe2/_inspection/_visitors.py,sha256=XqjCR2VqgOlFKBw2SvJJfWhUCEqofSuIxZ8ecLyi7k0,19738
|
|
22
22
|
npe2/manifest/__init__.py,sha256=sfgHfeC2AKoewwRgnAqX84X0U-ThDHxmt0Olidnmalo,159
|
|
23
23
|
npe2/manifest/_bases.py,sha256=Fs_juL_8sS3vR6_FdQ_O5RESiTEUER7BQI0C8ZnKOC0,3649
|
|
24
|
-
npe2/manifest/_npe1_adapter.py,sha256=
|
|
24
|
+
npe2/manifest/_npe1_adapter.py,sha256=6ZLGSSy-U6oEQekXeI2l-GXTJC3DuWTlFownbI5e8mo,5217
|
|
25
25
|
npe2/manifest/_package_metadata.py,sha256=NQpEoq50vPK1ULVZnGQVJ5Ns9TUZEwtctQV0s_kpp78,9241
|
|
26
26
|
npe2/manifest/_validators.py,sha256=v_GaW2DE1A7x3J-VA6mIWMLXO-AijLvZgf4-kcpQfWI,2875
|
|
27
27
|
npe2/manifest/menus.py,sha256=SMJyp1wI45ub8hdZUKqQi9SUZ3GpFlarHsOJ1ZwAMbs,181
|
|
@@ -31,19 +31,19 @@ npe2/manifest/utils.py,sha256=fuHCy573ZyJH4GFi_KdOUnJA0xRDY0qiN1dldP_aTTE,12355
|
|
|
31
31
|
npe2/manifest/contributions/__init__.py,sha256=b5eNqUL5tskS6gVwh_zalBCsPxX6HO1R1tNvG9A3m68,1003
|
|
32
32
|
npe2/manifest/contributions/_commands.py,sha256=f7x1yDoHS2GBAjQaFGqIcsqNC1avqtr6o4w_RZcHexs,4329
|
|
33
33
|
npe2/manifest/contributions/_configuration.py,sha256=i8DPBUfpJZ4Y_Hug1E1FGCsLivd6SpZZmGZ_80WdFeg,6516
|
|
34
|
-
npe2/manifest/contributions/_contributions.py,sha256=
|
|
34
|
+
npe2/manifest/contributions/_contributions.py,sha256=gC9-zMnmLQrObu8YTL_4NF4szD11jsN5ms9nf7K8YD8,2476
|
|
35
35
|
npe2/manifest/contributions/_icon.py,sha256=NXeAPy1qoPLcFBHpQK_7j4pqxHGYbZ0gb3yCXr47CLM,161
|
|
36
36
|
npe2/manifest/contributions/_json_schema.py,sha256=rIERaRMzVJzx5YPkdnGUyQDrfK3PN-eLM-gOOumFyHA,10953
|
|
37
37
|
npe2/manifest/contributions/_keybindings.py,sha256=E_mrSzngXEGuyIfytPLOc0WL7Bb1Zebazdt1Nw6ZhD0,962
|
|
38
38
|
npe2/manifest/contributions/_menus.py,sha256=FAkXdpSGHdDqjA4yr2Oxb62x7POXJY7ETAcs23AJTFY,2233
|
|
39
39
|
npe2/manifest/contributions/_readers.py,sha256=XziSWpJrrbS_CJ6bvPhGH4vwKZq5in8kls07j1TAdXw,2513
|
|
40
|
-
npe2/manifest/contributions/_sample_data.py,sha256=
|
|
41
|
-
npe2/manifest/contributions/_submenu.py,sha256=
|
|
40
|
+
npe2/manifest/contributions/_sample_data.py,sha256=KRZ2vEDhd0Qmv9HOa6e_Db9sTzLrPc2VsTsFeWQbmvw,2400
|
|
41
|
+
npe2/manifest/contributions/_submenu.py,sha256=jRUFdKB1iIgUfADeaHJV9rZ3_u3SfYjwfGgXelhEfXs,960
|
|
42
42
|
npe2/manifest/contributions/_themes.py,sha256=FeHBeqayZOIN4ccyik1xPZ30cE-_3Xr7aozilyoamiY,2683
|
|
43
43
|
npe2/manifest/contributions/_widgets.py,sha256=ung4t6R4EB6Rz9Xmlb4Z46ilOHHmkoWkEMuHQC4kABw,2217
|
|
44
44
|
npe2/manifest/contributions/_writers.py,sha256=i1usy_tR_1XIf93c8HXu0APLJI3QrOJUc0-0nxLrLbI,7867
|
|
45
|
-
npe2-0.7.
|
|
46
|
-
npe2-0.7.
|
|
47
|
-
npe2-0.7.
|
|
48
|
-
npe2-0.7.
|
|
49
|
-
npe2-0.7.
|
|
45
|
+
npe2-0.7.9rc0.dist-info/METADATA,sha256=PSwtqFzgHbvC4UIYP33c4JrMK4-K_0dFL17K9X6l-sc,5973
|
|
46
|
+
npe2-0.7.9rc0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
47
|
+
npe2-0.7.9rc0.dist-info/entry_points.txt,sha256=5zoegMudO8Hkn6589GlAXIW49Ar5HSWZjTRc0TkJu3s,250
|
|
48
|
+
npe2-0.7.9rc0.dist-info/licenses/LICENSE,sha256=uyX2Y2Q7D-WzOUc6EKZVDuadkWenBWSYTR--BsewGpg,1514
|
|
49
|
+
npe2-0.7.9rc0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|