spin 0.14__tar.gz → 0.15__tar.gz

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.
Files changed (32) hide show
  1. {spin-0.14/spin.egg-info → spin-0.15}/PKG-INFO +4 -3
  2. {spin-0.14 → spin-0.15}/pyproject.toml +3 -2
  3. {spin-0.14 → spin-0.15}/spin/__init__.py +1 -1
  4. {spin-0.14 → spin-0.15}/spin/__main__.py +11 -13
  5. {spin-0.14 → spin-0.15}/spin/cmds/meson.py +48 -22
  6. {spin-0.14 → spin-0.15}/spin/cmds/pip.py +3 -1
  7. {spin-0.14 → spin-0.15}/spin/cmds/util.py +1 -1
  8. {spin-0.14 → spin-0.15/spin.egg-info}/PKG-INFO +4 -3
  9. {spin-0.14 → spin-0.15}/spin.egg-info/requires.txt +2 -2
  10. {spin-0.14 → spin-0.15}/LICENSE +0 -0
  11. {spin-0.14 → spin-0.15}/README.md +0 -0
  12. {spin-0.14 → spin-0.15}/setup.cfg +0 -0
  13. {spin-0.14 → spin-0.15}/spin/cmds/__init__.py +0 -0
  14. {spin-0.14 → spin-0.15}/spin/cmds/build.py +0 -0
  15. {spin-0.14 → spin-0.15}/spin/cmds/meta.py +0 -0
  16. {spin-0.14 → spin-0.15}/spin/color_format.py +0 -0
  17. {spin-0.14 → spin-0.15}/spin/containers.py +0 -0
  18. {spin-0.14 → spin-0.15}/spin/sectioned_help.py +0 -0
  19. {spin-0.14 → spin-0.15}/spin/tests/__init__.py +0 -0
  20. {spin-0.14 → spin-0.15}/spin/tests/conftest.py +0 -0
  21. {spin-0.14 → spin-0.15}/spin/tests/test_build_cmds.py +0 -0
  22. {spin-0.14 → spin-0.15}/spin/tests/test_cli.py +0 -0
  23. {spin-0.14 → spin-0.15}/spin/tests/test_editable.py +0 -0
  24. {spin-0.14 → spin-0.15}/spin/tests/test_extend_command.py +0 -0
  25. {spin-0.14 → spin-0.15}/spin/tests/test_meson.py +0 -0
  26. {spin-0.14 → spin-0.15}/spin/tests/test_test.py +0 -0
  27. {spin-0.14 → spin-0.15}/spin/tests/test_util.py +0 -0
  28. {spin-0.14 → spin-0.15}/spin/tests/testutil.py +0 -0
  29. {spin-0.14 → spin-0.15}/spin.egg-info/SOURCES.txt +0 -0
  30. {spin-0.14 → spin-0.15}/spin.egg-info/dependency_links.txt +0 -0
  31. {spin-0.14 → spin-0.15}/spin.egg-info/entry_points.txt +0 -0
  32. {spin-0.14 → spin-0.15}/spin.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spin
3
- Version: 0.14
3
+ Version: 0.15
4
4
  Summary: Developer tool for scientific Python libraries
5
5
  Maintainer-email: Scientific Python <spin@discuss.scientific-python.org>
6
6
  License: BSD 3-Clause License
@@ -46,16 +46,17 @@ Classifier: Programming Language :: Python :: 3.10
46
46
  Classifier: Programming Language :: Python :: 3.11
47
47
  Classifier: Programming Language :: Python :: 3.12
48
48
  Classifier: Programming Language :: Python :: 3.13
49
+ Classifier: Programming Language :: Python :: 3.14
49
50
  Classifier: Programming Language :: Python :: 3 :: Only
50
51
  Requires-Python: >=3.9
51
52
  Description-Content-Type: text/markdown
52
53
  License-File: LICENSE
53
- Requires-Dist: click
54
+ Requires-Dist: click<8.3,>=8
54
55
  Requires-Dist: tomli; python_version < "3.11"
55
56
  Requires-Dist: colorama; platform_system == "Windows"
56
57
  Requires-Dist: importlib_metadata>=7
57
58
  Provides-Extra: lint
58
- Requires-Dist: pre-commit==4.2.0; extra == "lint"
59
+ Requires-Dist: pre-commit==4.3.0; extra == "lint"
59
60
  Provides-Extra: dev
60
61
  Requires-Dist: changelist==0.5; extra == "dev"
61
62
  Dynamic: license-file
@@ -20,10 +20,11 @@ classifiers = [
20
20
  "Programming Language :: Python :: 3.11",
21
21
  "Programming Language :: Python :: 3.12",
22
22
  "Programming Language :: Python :: 3.13",
23
+ "Programming Language :: Python :: 3.14",
23
24
  "Programming Language :: Python :: 3 :: Only",
24
25
  ]
25
26
  dependencies = [
26
- "click",
27
+ "click>=8,<8.3",
27
28
  "tomli; python_version < '3.11'",
28
29
  "colorama; platform_system == 'Windows'",
29
30
  "importlib_metadata >= 7"
@@ -34,7 +35,7 @@ dynamic = ['version']
34
35
  spin = "spin.__main__:main"
35
36
 
36
37
  [project.optional-dependencies]
37
- lint = ["pre-commit == 4.2.0"]
38
+ lint = ["pre-commit == 4.3.0"]
38
39
  dev = ["changelist == 0.5"]
39
40
 
40
41
  [project.urls]
@@ -6,7 +6,7 @@ For usage information see `python -m spin`.
6
6
  Read more at https://github.com/scientific-python/spin
7
7
  """
8
8
 
9
- __version__ = "0.14"
9
+ __version__ = "0.15"
10
10
 
11
11
  from .cmds import util
12
12
 
@@ -1,11 +1,11 @@
1
1
  import collections
2
2
  import importlib
3
3
  import importlib.util
4
- import inspect
5
4
  import os
6
5
  import pathlib
7
6
  import sys
8
7
  import textwrap
8
+ import traceback
9
9
  from typing import Union
10
10
 
11
11
  import click
@@ -199,17 +199,16 @@ def main():
199
199
 
200
200
  try:
201
201
  group()
202
- except Exception as e:
202
+ except Exception:
203
203
  click.secho(
204
- textwrap.dedent(
205
- f"""\
206
-
207
- {type(e).__name__}: {e}
208
-
209
- This exception was raised from:
210
-
211
- {inspect.trace()[-1].filename}
204
+ "\n" + "".join(traceback.format_exception(*sys.exc_info(), limit=-1)),
205
+ fg="red",
206
+ bold=True,
207
+ file=sys.stderr,
208
+ )
212
209
 
210
+ click.secho(
211
+ textwrap.dedent(f"""\
213
212
  If you suspect this is a bug in `spin`, please file a report at:
214
213
 
215
214
  https://github.com/scientific-python/spin
@@ -218,9 +217,8 @@ def main():
218
217
 
219
218
  spin: {__version__}, package: {proj_name}
220
219
 
221
- Aborting."""
222
- ),
223
- fg="red",
220
+ Aborting."""),
221
+ fg="yellow",
224
222
  bold=True,
225
223
  file=sys.stderr,
226
224
  )
@@ -8,6 +8,7 @@ import signal
8
8
  import sys
9
9
  from enum import Enum
10
10
  from pathlib import Path
11
+ from typing import Union
11
12
 
12
13
  import click
13
14
 
@@ -35,7 +36,15 @@ def _meson_cli():
35
36
  return [meson_cli]
36
37
 
37
38
 
38
- def _editable_install_path(distname):
39
+ def editable_install_path(distname: str) -> Union[str, None]:
40
+ """Return path of the editable install for package `distname`.
41
+
42
+ If the package is not an editable install, return None.
43
+
44
+ See Also
45
+ --------
46
+ is_editable_install
47
+ """
39
48
  import importlib_metadata
40
49
 
41
50
  try:
@@ -57,16 +66,34 @@ def _editable_install_path(distname):
57
66
  return None
58
67
 
59
68
 
60
- def _is_editable_install(distname):
61
- return _editable_install_path(distname) is not None
69
+ # backward compat
70
+ _editable_install_path = editable_install_path
71
+
72
+
73
+ def is_editable_install(distname: str, verify_path: bool = False) -> bool:
74
+ """Whether or not an editable install of `distname` is present.
75
+
76
+ Parameters
77
+ ----------
78
+ `distname` : str
79
+ Name of the package. E.g., ``numpy`` or ``scikit-image``.
80
+ Not always the same as the module name (``numpy`` and
81
+ ``skimage`` for the above).
82
+ """
83
+ return editable_install_path(distname) is not None
84
+
85
+
86
+ # backward compat
87
+ _is_editable_install = is_editable_install
62
88
 
63
89
 
64
- def _is_editable_install_of_same_source(distname):
65
- editable_path = _editable_install_path(distname)
66
- return editable_path and os.path.samefile(_editable_install_path(distname), ".")
90
+ def _is_editable_install_of_same_source(distname: str) -> bool:
91
+ """Check whether the editable install was made from the current directory."""
92
+ editable_path = editable_install_path(distname)
93
+ return (editable_path is not None) and os.path.samefile(editable_path, ".")
67
94
 
68
95
 
69
- def _set_pythonpath(build_dir, quiet=False):
96
+ def _set_pythonpath(build_dir: str, quiet: bool = False) -> str:
70
97
  """Set first entry of PYTHONPATH to site packages directory.
71
98
 
72
99
  For editable installs, leave the PYTHONPATH alone.
@@ -78,12 +105,12 @@ def _set_pythonpath(build_dir, quiet=False):
78
105
  cfg = get_config()
79
106
  distname = cfg.get("project.name", None)
80
107
  if distname:
81
- if _is_editable_install(distname):
108
+ if is_editable_install(distname):
82
109
  if _is_editable_install_of_same_source(distname):
83
110
  if not (quiet):
84
111
  click.secho(
85
112
  "Editable install of same source directory detected; not setting PYTHONPATH",
86
- fg="bright_red",
113
+ fg="yellow",
87
114
  )
88
115
  return ""
89
116
  else:
@@ -114,11 +141,11 @@ def _set_pythonpath(build_dir, quiet=False):
114
141
  return site_packages
115
142
 
116
143
 
117
- def _get_install_dir(build_dir):
144
+ def _get_install_dir(build_dir: str) -> str:
118
145
  return f"{build_dir}-install"
119
146
 
120
147
 
121
- def _get_site_packages(build_dir):
148
+ def _get_site_packages(build_dir: str) -> str:
122
149
  install_dir = _get_install_dir(build_dir)
123
150
  try:
124
151
  cfg = get_config()
@@ -140,13 +167,12 @@ def _get_site_packages(build_dir):
140
167
  site_packages = None
141
168
  if any(f"python{X}." in p for p in candidate_paths):
142
169
  # We have a system that uses `python3.X/site-packages` or `python3.X/dist-packages`
143
- site_packages = [p for p in candidate_paths if f"python{X}.{Y}" in p]
144
- if len(site_packages) == 0:
170
+ site_packages_paths = [p for p in candidate_paths if f"python{X}.{Y}" in p]
171
+ if len(site_packages_paths) == 0:
145
172
  raise FileNotFoundError(
146
173
  f"No site-packages found in {install_dir} for Python {X}.{Y}"
147
174
  )
148
- else:
149
- site_packages = site_packages[0]
175
+ site_packages = site_packages_paths[0]
150
176
  else:
151
177
  # A naming scheme that does not encode the Python major/minor version is used, so return
152
178
  # whatever site-packages path was found
@@ -165,22 +191,22 @@ def _get_site_packages(build_dir):
165
191
  return site_packages
166
192
 
167
193
 
168
- def _meson_version():
194
+ def _meson_version() -> Union[str, None]:
169
195
  try:
170
196
  p = _run(_meson_cli() + ["--version"], output=False, echo=False)
171
197
  return p.stdout.decode("ascii").strip()
172
198
  except:
173
- pass
199
+ return None
174
200
 
175
201
 
176
- def _meson_version_configured(build_dir):
202
+ def _meson_version_configured(build_dir: str) -> Union[str, None]:
177
203
  try:
178
204
  meson_info_fn = os.path.join(build_dir, "meson-info", "meson-info.json")
179
205
  with open(meson_info_fn) as f:
180
206
  meson_info = json.load(f)
181
207
  return meson_info["meson_version"]["full"]
182
208
  except:
183
- pass
209
+ return None
184
210
 
185
211
 
186
212
  def _meson_coverage_configured() -> bool:
@@ -199,7 +225,7 @@ def _meson_coverage_configured() -> bool:
199
225
  return False
200
226
 
201
227
 
202
- def _check_coverage_tool_installation(coverage_type: GcovReportFormat, build_dir):
228
+ def _check_coverage_tool_installation(coverage_type: GcovReportFormat, build_dir: str):
203
229
  requirements = { # https://github.com/mesonbuild/meson/blob/6e381714c7cb15877e2bcaa304b93c212252ada3/docs/markdown/Unit-tests.md?plain=1#L49-L62
204
230
  GcovReportFormat.html: ["Gcovr/GenHTML", "lcov"],
205
231
  GcovReportFormat.xml: ["Gcovr (version 3.3 or higher)"],
@@ -336,7 +362,7 @@ def build(
336
362
  if not quiet:
337
363
  click.secho(
338
364
  "Editable install of same source detected; skipping build",
339
- fg="bright_red",
365
+ fg="yellow",
340
366
  )
341
367
  return
342
368
 
@@ -487,7 +513,7 @@ def test(
487
513
 
488
514
  To run test modules, functions, classes, or methods:
489
515
 
490
- spin -t numpy.random
516
+ spin test -t numpy.random
491
517
 
492
518
  To report the durations of the N slowest tests:
493
519
 
@@ -1,3 +1,5 @@
1
+ import sys
2
+
1
3
  import click
2
4
 
3
5
  from .util import run as _run
@@ -37,7 +39,7 @@ def install(*, pip_args, editable, verbose, verbose_import):
37
39
  pip install . --no-build-isolation --editable --no-clean
38
40
  """
39
41
  pip_args = list(pip_args)
40
- pip_cmd = ["pip", "install"]
42
+ pip_cmd = [sys.executable, "-m", "pip", "install"]
41
43
  pip_args += ["--no-build-isolation"]
42
44
 
43
45
  if editable:
@@ -168,7 +168,7 @@ def extend_command(
168
168
  return user_func(*args, parent_callback=parent_cmd, **kwargs)
169
169
 
170
170
  my_cmd.callback = click.pass_context(callback_with_parent_callback)
171
- my_cmd.callback._parent = user_func
171
+ my_cmd.callback._parent = user_func # type: ignore[attr-defined]
172
172
 
173
173
  if doc is not None:
174
174
  my_cmd.help = doc
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spin
3
- Version: 0.14
3
+ Version: 0.15
4
4
  Summary: Developer tool for scientific Python libraries
5
5
  Maintainer-email: Scientific Python <spin@discuss.scientific-python.org>
6
6
  License: BSD 3-Clause License
@@ -46,16 +46,17 @@ Classifier: Programming Language :: Python :: 3.10
46
46
  Classifier: Programming Language :: Python :: 3.11
47
47
  Classifier: Programming Language :: Python :: 3.12
48
48
  Classifier: Programming Language :: Python :: 3.13
49
+ Classifier: Programming Language :: Python :: 3.14
49
50
  Classifier: Programming Language :: Python :: 3 :: Only
50
51
  Requires-Python: >=3.9
51
52
  Description-Content-Type: text/markdown
52
53
  License-File: LICENSE
53
- Requires-Dist: click
54
+ Requires-Dist: click<8.3,>=8
54
55
  Requires-Dist: tomli; python_version < "3.11"
55
56
  Requires-Dist: colorama; platform_system == "Windows"
56
57
  Requires-Dist: importlib_metadata>=7
57
58
  Provides-Extra: lint
58
- Requires-Dist: pre-commit==4.2.0; extra == "lint"
59
+ Requires-Dist: pre-commit==4.3.0; extra == "lint"
59
60
  Provides-Extra: dev
60
61
  Requires-Dist: changelist==0.5; extra == "dev"
61
62
  Dynamic: license-file
@@ -1,4 +1,4 @@
1
- click
1
+ click<8.3,>=8
2
2
  importlib_metadata>=7
3
3
 
4
4
  [:platform_system == "Windows"]
@@ -11,4 +11,4 @@ tomli
11
11
  changelist==0.5
12
12
 
13
13
  [lint]
14
- pre-commit==4.2.0
14
+ pre-commit==4.3.0
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes