napari-plugin-manager 0.1.5rc1__py3-none-any.whl → 0.1.6__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.
@@ -27,6 +27,7 @@ def test_plugin_summaries():
27
27
  "home_page",
28
28
  "pypi_versions",
29
29
  "conda_versions",
30
+ "project_url",
30
31
  ]
31
32
  try:
32
33
  data = plugin_summaries()
@@ -3,7 +3,7 @@ from unittest.mock import patch
3
3
 
4
4
  import pytest
5
5
 
6
- from napari_plugin_manager.utils import is_conda_package
6
+ from napari_plugin_manager.utils import get_homepage_url, is_conda_package
7
7
 
8
8
 
9
9
  @pytest.mark.parametrize(
@@ -25,3 +25,34 @@ def test_is_conda_package(pkg_name, expected, tmp_path):
25
25
 
26
26
  with patch.object(sys, 'prefix', tmp_path):
27
27
  assert is_conda_package(pkg_name) is expected
28
+
29
+
30
+ def test_get_homepage_url():
31
+ assert get_homepage_url({}) == ''
32
+
33
+ meta = {
34
+ 'Home-page': None,
35
+ }
36
+ assert get_homepage_url(meta) == ''
37
+
38
+ meta['Home-page'] = 'http://example.com'
39
+ assert get_homepage_url(meta) == 'http://example.com'
40
+
41
+ meta['Project-URL'] = ['Home Page, http://projurl.com']
42
+ assert get_homepage_url(meta) == 'http://example.com'
43
+
44
+ meta['home_page'] = meta.pop('Home-page')
45
+ meta['project_url'] = meta.pop('Project-URL')
46
+ assert get_homepage_url(meta) == 'http://example.com'
47
+
48
+ meta['home_page'] = None
49
+ assert get_homepage_url(meta) == 'http://projurl.com'
50
+
51
+ meta['project_url'] = ['Source Code, http://projurl.com']
52
+ assert get_homepage_url(meta) == 'http://projurl.com'
53
+
54
+ meta['project_url'] = ['Source, http://projurl.com']
55
+ assert get_homepage_url(meta) == 'http://projurl.com'
56
+
57
+ meta['project_url'] = None
58
+ assert get_homepage_url(meta) == ''
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '0.1.5rc1'
21
- __version_tuple__ = version_tuple = (0, 1, 5)
20
+ __version__ = version = '0.1.6'
21
+ __version_tuple__ = version_tuple = (0, 1, 6)
@@ -23,7 +23,7 @@ from logging import getLogger
23
23
  from pathlib import Path
24
24
  from subprocess import call
25
25
  from tempfile import gettempdir
26
- from typing import TypedDict
26
+ from typing import Optional, TypedDict
27
27
 
28
28
  from napari.plugins import plugin_manager
29
29
  from napari.plugins.npe2api import _user_agent
@@ -636,8 +636,8 @@ class InstallerQueue(QObject):
636
636
  def _on_process_done(
637
637
  self,
638
638
  exit_code: int | None = None,
639
- exit_status: QProcess.ExitStatus | None = None,
640
- error: QProcess.ProcessError | None = None,
639
+ exit_status: Optional[QProcess.ExitStatus] = None, # noqa
640
+ error: Optional[QProcess.ProcessError] = None, # noqa
641
641
  ):
642
642
  item = None
643
643
  with contextlib.suppress(IndexError):
@@ -53,7 +53,7 @@ from napari_plugin_manager.base_qt_package_installer import (
53
53
  )
54
54
  from napari_plugin_manager.qt_warning_dialog import RestartWarningDialog
55
55
  from napari_plugin_manager.qt_widgets import ClickableLabel
56
- from napari_plugin_manager.utils import is_conda_package
56
+ from napari_plugin_manager.utils import get_homepage_url, is_conda_package
57
57
 
58
58
  CONDA = 'Conda'
59
59
  PYPI = 'PyPI'
@@ -1225,7 +1225,8 @@ class BaseQtPluginDialog(QDialog):
1225
1225
  self.already_installed.add(norm_name)
1226
1226
  else:
1227
1227
  meta = {}
1228
-
1228
+ meta_dict = meta if isinstance(meta, dict) else meta.json
1229
+ home_page = get_homepage_url(meta_dict)
1229
1230
  self.installed_list.addItem(
1230
1231
  self.PROJECT_INFO_VERSION_CLASS(
1231
1232
  display_name=norm_name,
@@ -1236,7 +1237,7 @@ class BaseQtPluginDialog(QDialog):
1236
1237
  name=norm_name,
1237
1238
  version=meta.get('version', ''),
1238
1239
  summary=meta.get('summary', ''),
1239
- home_page=meta.get('Home-page', ''),
1240
+ home_page=home_page,
1240
1241
  author=meta.get('author', ''),
1241
1242
  license=meta.get('license', ''),
1242
1243
  ),
@@ -19,6 +19,8 @@ from napari.utils.notifications import show_warning
19
19
  from npe2 import PackageMetadata
20
20
  from typing_extensions import NotRequired
21
21
 
22
+ from napari_plugin_manager.utils import get_homepage_url
23
+
22
24
  PyPIname = str
23
25
 
24
26
 
@@ -98,12 +100,15 @@ def iter_napari_plugin_info() -> Iterator[tuple[PackageMetadata, bool, dict]]:
98
100
 
99
101
  conda_set = {normalized_name(x) for x in conda}
100
102
  for info in data_set:
101
- info_copy = dict(info)
103
+ info_copy: dict[str, str | list[str]] = dict(info)
102
104
  info_copy.pop('display_name', None)
103
105
  pypi_versions = info_copy.pop('pypi_versions')
104
106
  conda_versions = info_copy.pop('conda_versions')
105
107
  info_ = cast(_ShortSummaryDict, info_copy)
106
-
108
+ home_page = get_homepage_url(info_copy)
109
+ # this URL is used for the widget, so we have to replace the home_page
110
+ # link here as well as returning it in extra_info
111
+ info_['home_page'] = home_page
107
112
  # TODO: use this better.
108
113
  # this would require changing the api that qt_plugin_dialog expects to
109
114
  # receive
@@ -111,7 +116,7 @@ def iter_napari_plugin_info() -> Iterator[tuple[PackageMetadata, bool, dict]]:
111
116
  # TODO: once the new version of npe2 is out, this can be refactored
112
117
  # to all the metadata includes the conda and pypi versions.
113
118
  extra_info = {
114
- 'home_page': info_.get('home_page', ''),
119
+ 'home_page': home_page,
115
120
  'display_name': info.get('display_name', ''),
116
121
  'pypi_versions': pypi_versions,
117
122
  'conda_versions': conda_versions,
@@ -1,4 +1,5 @@
1
1
  import re
2
+ import string
2
3
  import sys
3
4
  from pathlib import Path
4
5
 
@@ -19,3 +20,57 @@ def is_conda_package(pkg: str, prefix: str | None = None) -> bool:
19
20
  re.match(rf"{pkg}-[^-]+-[^-]+.json", p.name)
20
21
  for p in conda_meta_dir.glob(f"{pkg}-*-*.json")
21
22
  )
23
+
24
+
25
+ def normalize_label(label: str) -> str:
26
+ """Normalize project URL label.
27
+
28
+ Code reproduced from:
29
+ https://packaging.python.org/en/latest/specifications/well-known-project-urls/#label-normalization
30
+ """
31
+ chars_to_remove = string.punctuation + string.whitespace
32
+ removal_map = str.maketrans("", "", chars_to_remove)
33
+ return label.translate(removal_map).lower()
34
+
35
+
36
+ def get_homepage_url(metadata: dict[str, str | list[str] | None]) -> str:
37
+ """Get URL for package homepage, if available.
38
+
39
+ Checks metadata first for `Home-page` field before
40
+ looking for `Project-URL` 'homepage' label and finally
41
+ 'source'/'sourcecode' label.
42
+
43
+ Parameters
44
+ ----------
45
+ metadata : dict[str, str | list[str] | None]
46
+ Package metadata information.
47
+
48
+ Returns
49
+ -------
50
+ str
51
+ Returns homepage URL if present, otherwise empty string.
52
+ """
53
+ if not len(metadata):
54
+ return ''
55
+
56
+ homepage = metadata.get('Home-page', '') or metadata.get('home_page', '')
57
+ if isinstance(homepage, str) and len(homepage):
58
+ return homepage
59
+
60
+ urls = {}
61
+ project_urls = metadata.get('Project-URL', []) or metadata.get(
62
+ 'project_url', []
63
+ )
64
+ if project_urls is None:
65
+ return ''
66
+
67
+ for url_info in project_urls:
68
+ label, url = url_info.split(', ')
69
+ urls[normalize_label(label)] = url
70
+
71
+ homepage = (
72
+ urls.get('homepage', '')
73
+ or urls.get('source', '')
74
+ or urls.get('sourcecode', '')
75
+ )
76
+ return homepage
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: napari-plugin-manager
3
- Version: 0.1.5rc1
3
+ Version: 0.1.6
4
4
  Summary: Install plugins for napari, in napari.
5
5
  Author-email: napari team <napari-steering-council@googlegroups.com>
6
6
  License: BSD 3-Clause License
@@ -0,0 +1,23 @@
1
+ napari_plugin_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ napari_plugin_manager/_version.py,sha256=ESbJO0YD7TYfOUv_WDIJJgWELGepEWsoyhqVifEcXPA,511
3
+ napari_plugin_manager/base_qt_package_installer.py,sha256=Nw6EIjZOmKVrJJCQrb1TjUMVeey4WIbib6hzBXMcSBc,21857
4
+ napari_plugin_manager/base_qt_plugin_dialog.py,sha256=nLqOJs_kUdGmmlTjaQRCu-EWB-4smwjbHlYpoSJ5jZs,66093
5
+ napari_plugin_manager/npe2api.py,sha256=KtfV-fspfADxSHMD_AoBaRt2WFkfeZ-W4aRl0SLyna8,4367
6
+ napari_plugin_manager/qt_package_installer.py,sha256=j-pacW6wHVq3iJaZXsj6D-_VH25Fz-55r7clcd_CQvE,2804
7
+ napari_plugin_manager/qt_plugin_dialog.py,sha256=Ig4TtjCh9Z2Dx_QpiOsfLlgolPJHmJ5_7VuTU2DE0Ag,9607
8
+ napari_plugin_manager/qt_warning_dialog.py,sha256=ue4CeMptlBBkBctPg7qCayamrkm75iLqASSFUvwo_Bc,669
9
+ napari_plugin_manager/qt_widgets.py,sha256=O8t5CbN8r_16cQzshyjvhTEYdUcj7OX0-bfYIiN2uSs,356
10
+ napari_plugin_manager/styles.qss,sha256=9ODPba2IorJybWObWoEO9VGq4AO0IYlAa8brN14tgZU,7379
11
+ napari_plugin_manager/utils.py,sha256=u0OSzNbSTyk7a-NdwGfrqry_q94GiHfKQnWB20r6V9A,2247
12
+ napari_plugin_manager/_tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ napari_plugin_manager/_tests/conftest.py,sha256=OvzenfBP2oIS6x8ksr9FhPXdsLV3Q_3Kzr6PRJe45Uc,1885
14
+ napari_plugin_manager/_tests/test_base_installer_process.py,sha256=Cv-nBnUeNAX6pYUE1zs38I9vGtCE-ahBN4q-xcBH-pw,561
15
+ napari_plugin_manager/_tests/test_installer_process.py,sha256=qPSDcYWPQ08gzM38av2tcE9XCtruHv-Mo6duQ0sZp-8,11614
16
+ napari_plugin_manager/_tests/test_npe2api.py,sha256=nf3UG68gqoCFyiPDisToZsLpZG0uvzGUUk8H6Fy3dqE,1248
17
+ napari_plugin_manager/_tests/test_qt_plugin_dialog.py,sha256=IRXodt3IrE7rXHZO0R69lhz4_2mMW3MOE9LLQ5tCxWY,21727
18
+ napari_plugin_manager/_tests/test_utils.py,sha256=I9rYJV_JVKg6GeBlhY4A_6aY1N5MbM7jgNz5wewiWIQ,1669
19
+ napari_plugin_manager-0.1.6.dist-info/licenses/LICENSE,sha256=8dAlKbOqTMYe9L-gL_kEx5Xr1Sd0AbaWQDUkpiOp3vI,1506
20
+ napari_plugin_manager-0.1.6.dist-info/METADATA,sha256=HQvATPh6tVJmaZBlNTG9BmG488v4ATn6OoposuwN4zE,13810
21
+ napari_plugin_manager-0.1.6.dist-info/WHEEL,sha256=ooBFpIzZCPdw3uqIQsOo4qqbA4ZRPxHnOH7peeONza0,91
22
+ napari_plugin_manager-0.1.6.dist-info/top_level.txt,sha256=pmCqLetuumhY1CKSuTZ5eQsitzazrSvc7V_mkugEPTY,22
23
+ napari_plugin_manager-0.1.6.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (78.1.0)
2
+ Generator: setuptools (80.0.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,23 +0,0 @@
1
- napari_plugin_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- napari_plugin_manager/_version.py,sha256=wQaAqCMIBuF3fOz_hscpjKVmnhNsU3hxiNQwtVyHi3c,514
3
- napari_plugin_manager/base_qt_package_installer.py,sha256=Tp2dt5BBT-5CsXXlQPIPxuXSDMvUgKy2kSgw2Y2G9Dk,21825
4
- napari_plugin_manager/base_qt_plugin_dialog.py,sha256=gkrEkVf_WGJHjZFORMoCiw-gxCwFuTZ04Q0PGFK8gLk,65978
5
- napari_plugin_manager/npe2api.py,sha256=bXmhwFkwKw_1DfnGLhWhEGaEAA3oYPFaw4eR4SX2Nyg,4075
6
- napari_plugin_manager/qt_package_installer.py,sha256=j-pacW6wHVq3iJaZXsj6D-_VH25Fz-55r7clcd_CQvE,2804
7
- napari_plugin_manager/qt_plugin_dialog.py,sha256=Ig4TtjCh9Z2Dx_QpiOsfLlgolPJHmJ5_7VuTU2DE0Ag,9607
8
- napari_plugin_manager/qt_warning_dialog.py,sha256=ue4CeMptlBBkBctPg7qCayamrkm75iLqASSFUvwo_Bc,669
9
- napari_plugin_manager/qt_widgets.py,sha256=O8t5CbN8r_16cQzshyjvhTEYdUcj7OX0-bfYIiN2uSs,356
10
- napari_plugin_manager/styles.qss,sha256=9ODPba2IorJybWObWoEO9VGq4AO0IYlAa8brN14tgZU,7379
11
- napari_plugin_manager/utils.py,sha256=V0QmCQNP2OwszoQ2n9Gnau9jH81rLKwfskL4ebex7EE,722
12
- napari_plugin_manager/_tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
- napari_plugin_manager/_tests/conftest.py,sha256=OvzenfBP2oIS6x8ksr9FhPXdsLV3Q_3Kzr6PRJe45Uc,1885
14
- napari_plugin_manager/_tests/test_base_installer_process.py,sha256=Cv-nBnUeNAX6pYUE1zs38I9vGtCE-ahBN4q-xcBH-pw,561
15
- napari_plugin_manager/_tests/test_installer_process.py,sha256=qPSDcYWPQ08gzM38av2tcE9XCtruHv-Mo6duQ0sZp-8,11614
16
- napari_plugin_manager/_tests/test_npe2api.py,sha256=GRXucH7kWHt6thgueppHHWaToTvQG1PXH6UECFeVxcM,1225
17
- napari_plugin_manager/_tests/test_qt_plugin_dialog.py,sha256=IRXodt3IrE7rXHZO0R69lhz4_2mMW3MOE9LLQ5tCxWY,21727
18
- napari_plugin_manager/_tests/test_utils.py,sha256=7EilxmDkRjU6UO2AnaqyYovdAs18D0ZA5GCVGN62-3M,720
19
- napari_plugin_manager-0.1.5rc1.dist-info/licenses/LICENSE,sha256=8dAlKbOqTMYe9L-gL_kEx5Xr1Sd0AbaWQDUkpiOp3vI,1506
20
- napari_plugin_manager-0.1.5rc1.dist-info/METADATA,sha256=QeYCn3PpTMce-zZOvmAftJacUGvf4eUNkMU2p9Gv6PI,13813
21
- napari_plugin_manager-0.1.5rc1.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
22
- napari_plugin_manager-0.1.5rc1.dist-info/top_level.txt,sha256=pmCqLetuumhY1CKSuTZ5eQsitzazrSvc7V_mkugEPTY,22
23
- napari_plugin_manager-0.1.5rc1.dist-info/RECORD,,