spin 0.9__tar.gz → 0.11__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.
- {spin-0.9/spin.egg-info → spin-0.11}/PKG-INFO +4 -7
- {spin-0.9 → spin-0.11}/README.md +2 -5
- {spin-0.9 → spin-0.11}/pyproject.toml +3 -1
- {spin-0.9 → spin-0.11}/spin/__init__.py +1 -1
- {spin-0.9 → spin-0.11}/spin/__main__.py +21 -2
- spin-0.11/spin/cmds/__init__.py +3 -0
- {spin-0.9 → spin-0.11}/spin/cmds/meson.py +87 -41
- {spin-0.9 → spin-0.11}/spin/cmds/pip.py +13 -9
- {spin-0.9 → spin-0.11}/spin/cmds/util.py +14 -2
- {spin-0.9 → spin-0.11}/spin/tests/conftest.py +7 -0
- {spin-0.9 → spin-0.11}/spin/tests/test_build_cmds.py +15 -11
- {spin-0.9 → spin-0.11}/spin/tests/test_editable.py +0 -10
- spin-0.11/spin/tests/test_test.py +29 -0
- {spin-0.9 → spin-0.11}/spin/tests/testutil.py +4 -0
- {spin-0.9 → spin-0.11/spin.egg-info}/PKG-INFO +4 -7
- {spin-0.9 → spin-0.11}/spin.egg-info/SOURCES.txt +1 -0
- {spin-0.9 → spin-0.11}/spin.egg-info/requires.txt +1 -1
- spin-0.9/spin/cmds/__init__.py +0 -8
- {spin-0.9 → spin-0.11}/LICENSE +0 -0
- {spin-0.9 → spin-0.11}/setup.cfg +0 -0
- {spin-0.9 → spin-0.11}/spin/cmds/build.py +0 -0
- {spin-0.9 → spin-0.11}/spin/color_format.py +0 -0
- {spin-0.9 → spin-0.11}/spin/containers.py +0 -0
- {spin-0.9 → spin-0.11}/spin/sectioned_help.py +0 -0
- {spin-0.9 → spin-0.11}/spin/tests/test_cli.py +0 -0
- {spin-0.9 → spin-0.11}/spin/tests/test_meson.py +0 -0
- {spin-0.9 → spin-0.11}/spin.egg-info/dependency_links.txt +0 -0
- {spin-0.9 → spin-0.11}/spin.egg-info/entry_points.txt +0 -0
- {spin-0.9 → spin-0.11}/spin.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: spin
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11
|
|
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
|
|
@@ -55,7 +55,7 @@ Requires-Dist: tomli; python_version < "3.11"
|
|
|
55
55
|
Requires-Dist: colorama; platform_system == "Windows"
|
|
56
56
|
Requires-Dist: importlib_metadata>=7
|
|
57
57
|
Provides-Extra: lint
|
|
58
|
-
Requires-Dist: pre-commit==3.7.
|
|
58
|
+
Requires-Dist: pre-commit==3.7.1; extra == "lint"
|
|
59
59
|
Provides-Extra: dev
|
|
60
60
|
Requires-Dist: changelist==0.5; extra == "dev"
|
|
61
61
|
|
|
@@ -120,7 +120,7 @@ These commands will then be rendered as:
|
|
|
120
120
|
|
|
121
121
|
```
|
|
122
122
|
Build:
|
|
123
|
-
build 🔧 Build package with Meson/ninja
|
|
123
|
+
build 🔧 Build package with Meson/ninja
|
|
124
124
|
test 🔧 Run tests
|
|
125
125
|
|
|
126
126
|
Environments:
|
|
@@ -147,7 +147,7 @@ python -m spin
|
|
|
147
147
|
Available as `spin.cmds.meson.*`.
|
|
148
148
|
|
|
149
149
|
```
|
|
150
|
-
build 🔧 Build package with Meson/ninja
|
|
150
|
+
build 🔧 Build package with Meson/ninja
|
|
151
151
|
ipython 💻 Launch IPython shell with PYTHONPATH set
|
|
152
152
|
python 🐍 Launch Python shell with PYTHONPATH set
|
|
153
153
|
shell 💻 Launch shell with PYTHONPATH set
|
|
@@ -171,9 +171,6 @@ Available as `spin.cmds.build.*`:
|
|
|
171
171
|
`pip` allows for editable installs, another common
|
|
172
172
|
development workflow.
|
|
173
173
|
|
|
174
|
-
Note that, for now, the meson commands above do not work with an
|
|
175
|
-
editable install of the package. We're [working on changing that](https://github.com/scientific-python/spin/pull/141).
|
|
176
|
-
|
|
177
174
|
Available as `spin.cmds.pip.*`:
|
|
178
175
|
|
|
179
176
|
```
|
{spin-0.9 → spin-0.11}/README.md
RENAMED
|
@@ -59,7 +59,7 @@ These commands will then be rendered as:
|
|
|
59
59
|
|
|
60
60
|
```
|
|
61
61
|
Build:
|
|
62
|
-
build 🔧 Build package with Meson/ninja
|
|
62
|
+
build 🔧 Build package with Meson/ninja
|
|
63
63
|
test 🔧 Run tests
|
|
64
64
|
|
|
65
65
|
Environments:
|
|
@@ -86,7 +86,7 @@ python -m spin
|
|
|
86
86
|
Available as `spin.cmds.meson.*`.
|
|
87
87
|
|
|
88
88
|
```
|
|
89
|
-
build 🔧 Build package with Meson/ninja
|
|
89
|
+
build 🔧 Build package with Meson/ninja
|
|
90
90
|
ipython 💻 Launch IPython shell with PYTHONPATH set
|
|
91
91
|
python 🐍 Launch Python shell with PYTHONPATH set
|
|
92
92
|
shell 💻 Launch shell with PYTHONPATH set
|
|
@@ -110,9 +110,6 @@ Available as `spin.cmds.build.*`:
|
|
|
110
110
|
`pip` allows for editable installs, another common
|
|
111
111
|
development workflow.
|
|
112
112
|
|
|
113
|
-
Note that, for now, the meson commands above do not work with an
|
|
114
|
-
editable install of the package. We're [working on changing that](https://github.com/scientific-python/spin/pull/141).
|
|
115
|
-
|
|
116
113
|
Available as `spin.cmds.pip.*`:
|
|
117
114
|
|
|
118
115
|
```
|
|
@@ -34,7 +34,7 @@ dynamic = ['version']
|
|
|
34
34
|
spin = "spin.__main__:main"
|
|
35
35
|
|
|
36
36
|
[project.optional-dependencies]
|
|
37
|
-
lint = ["pre-commit == 3.7.
|
|
37
|
+
lint = ["pre-commit == 3.7.1"]
|
|
38
38
|
dev = ["changelist == 0.5"]
|
|
39
39
|
|
|
40
40
|
[project.urls]
|
|
@@ -54,6 +54,8 @@ filterwarnings = [
|
|
|
54
54
|
[tool.ruff]
|
|
55
55
|
line-length = 88
|
|
56
56
|
target-version = "py38"
|
|
57
|
+
|
|
58
|
+
[tool.ruff.lint]
|
|
57
59
|
select = [
|
|
58
60
|
"C",
|
|
59
61
|
"E",
|
|
@@ -3,6 +3,8 @@ import importlib
|
|
|
3
3
|
import importlib.util
|
|
4
4
|
import os
|
|
5
5
|
import sys
|
|
6
|
+
import textwrap
|
|
7
|
+
import traceback
|
|
6
8
|
|
|
7
9
|
import click
|
|
8
10
|
|
|
@@ -152,8 +154,25 @@ def main():
|
|
|
152
154
|
|
|
153
155
|
try:
|
|
154
156
|
group()
|
|
155
|
-
except Exception
|
|
156
|
-
|
|
157
|
+
except Exception:
|
|
158
|
+
click.secho("\n" + traceback.format_exc(limit=-3), fg="red", file=sys.stderr)
|
|
159
|
+
click.secho(
|
|
160
|
+
textwrap.dedent(
|
|
161
|
+
f"""\
|
|
162
|
+
An internal error has occurred. Please file a bug report at
|
|
163
|
+
|
|
164
|
+
https://github.com/scientific-python/spin
|
|
165
|
+
|
|
166
|
+
including the above traceback and the following information:
|
|
167
|
+
|
|
168
|
+
spin: {__version__}, package: {proj_name}
|
|
169
|
+
|
|
170
|
+
Aborting."""
|
|
171
|
+
),
|
|
172
|
+
fg="red",
|
|
173
|
+
bold=True,
|
|
174
|
+
file=sys.stderr,
|
|
175
|
+
)
|
|
157
176
|
sys.exit(1)
|
|
158
177
|
|
|
159
178
|
|
|
@@ -45,7 +45,12 @@ def _editable_install_path(distname):
|
|
|
45
45
|
except importlib_metadata.PackageNotFoundError:
|
|
46
46
|
return None
|
|
47
47
|
|
|
48
|
-
if
|
|
48
|
+
if dist.origin is None:
|
|
49
|
+
return None
|
|
50
|
+
|
|
51
|
+
if hasattr(dist.origin, "dir_info") and getattr(
|
|
52
|
+
dist.origin.dir_info, "editable", False
|
|
53
|
+
):
|
|
49
54
|
if sys.platform == "win32":
|
|
50
55
|
return dist.origin.url.removeprefix("file:///")
|
|
51
56
|
else:
|
|
@@ -213,9 +218,9 @@ def _check_coverage_tool_installation(coverage_type: GcovReportFormat):
|
|
|
213
218
|
|
|
214
219
|
# Verify the tools are installed prior to the build
|
|
215
220
|
p = _run(["ninja", "-C", build_dir, "-t", "targets", "all"], output=False)
|
|
216
|
-
if f"coverage-{coverage_type
|
|
221
|
+
if f"coverage-{coverage_type}" not in p.stdout.decode("ascii"):
|
|
217
222
|
raise click.ClickException(
|
|
218
|
-
f"coverage-{coverage_type
|
|
223
|
+
f"coverage-{coverage_type} is not supported... "
|
|
219
224
|
f"Ensure the following are installed: {', '.join(requirements[coverage_type])} "
|
|
220
225
|
"and rerun `spin test --gcov`"
|
|
221
226
|
)
|
|
@@ -233,15 +238,17 @@ def _check_coverage_tool_installation(coverage_type: GcovReportFormat):
|
|
|
233
238
|
help="Enable C code coverage using `gcov`. Use `spin test --gcov` to generate reports.",
|
|
234
239
|
)
|
|
235
240
|
@click.argument("meson_args", nargs=-1)
|
|
236
|
-
def build(
|
|
237
|
-
|
|
241
|
+
def build(
|
|
242
|
+
*, meson_args, jobs=None, clean=False, verbose=False, gcov=False, quiet=False
|
|
243
|
+
):
|
|
244
|
+
"""🔧 Build package with Meson/ninja
|
|
245
|
+
|
|
246
|
+
The package is installed to `build-install`.
|
|
238
247
|
|
|
239
248
|
MESON_ARGS are passed through e.g.:
|
|
240
249
|
|
|
241
250
|
spin build -- -Dpkg_config_path=/lib64/pkgconfig
|
|
242
251
|
|
|
243
|
-
The package is installed to build-install
|
|
244
|
-
|
|
245
252
|
By default meson-python does release builds. To be able to use a debugger,
|
|
246
253
|
tell meson to build in debug mode:
|
|
247
254
|
|
|
@@ -361,13 +368,14 @@ Which tests to run. Can be a module, function, class, or method:
|
|
|
361
368
|
)
|
|
362
369
|
@click.option(
|
|
363
370
|
"--gcov-format",
|
|
364
|
-
type=click.Choice(GcovReportFormat),
|
|
371
|
+
type=click.Choice([e.name for e in GcovReportFormat]),
|
|
365
372
|
default="html",
|
|
366
373
|
help=f"Format of the gcov report. Can be one of {', '.join(e.value for e in GcovReportFormat)}.",
|
|
367
374
|
)
|
|
368
375
|
@click.pass_context
|
|
369
376
|
def test(
|
|
370
377
|
ctx,
|
|
378
|
+
*,
|
|
371
379
|
pytest_args,
|
|
372
380
|
n_jobs,
|
|
373
381
|
tests,
|
|
@@ -420,8 +428,35 @@ def test(
|
|
|
420
428
|
""" # noqa: E501
|
|
421
429
|
cfg = get_config()
|
|
422
430
|
distname = cfg.get("project.name", None)
|
|
431
|
+
pytest_args = pytest_args or ()
|
|
432
|
+
|
|
433
|
+
# User specified tests without -t flag
|
|
434
|
+
# Rewrite arguments as though they specified using -t and proceed
|
|
435
|
+
if (len(pytest_args) == 1) and (not tests):
|
|
436
|
+
tests = pytest_args[0]
|
|
437
|
+
pytest_args = ()
|
|
438
|
+
|
|
439
|
+
package = cfg.get("tool.spin.package", None)
|
|
440
|
+
if package is None:
|
|
441
|
+
print(
|
|
442
|
+
"Please specify `package = packagename` under `tool.spin` section of `pyproject.toml`"
|
|
443
|
+
)
|
|
444
|
+
raise SystemExit(1)
|
|
445
|
+
|
|
446
|
+
# User did not specify what to test, so we test
|
|
447
|
+
# the full package
|
|
448
|
+
if not (pytest_args or tests):
|
|
449
|
+
pytest_args = ("--pyargs", package)
|
|
450
|
+
elif tests:
|
|
451
|
+
if (os.path.sep in tests) or ("/" in tests):
|
|
452
|
+
# Tests specified as file path
|
|
453
|
+
pytest_args = pytest_args + (tests,)
|
|
454
|
+
else:
|
|
455
|
+
# Otherwise tests given as modules
|
|
456
|
+
pytest_args = pytest_args + ("--pyargs", tests)
|
|
423
457
|
|
|
424
|
-
|
|
458
|
+
is_editable_install = distname and _is_editable_install_of_same_source(distname)
|
|
459
|
+
if gcov and is_editable_install:
|
|
425
460
|
click.secho(
|
|
426
461
|
"Error: cannot generate coverage report for editable installs",
|
|
427
462
|
fg="bright_red",
|
|
@@ -433,16 +468,10 @@ def test(
|
|
|
433
468
|
click.secho(
|
|
434
469
|
"Invoking `build` prior to running tests:", bold=True, fg="bright_green"
|
|
435
470
|
)
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
pytest_args = (package,)
|
|
441
|
-
if pytest_args == (None,):
|
|
442
|
-
print(
|
|
443
|
-
"Please specify `package = packagename` under `tool.spin` section of `pyproject.toml`"
|
|
444
|
-
)
|
|
445
|
-
sys.exit(1)
|
|
471
|
+
if gcov is not None:
|
|
472
|
+
ctx.invoke(build_cmd, gcov=bool(gcov))
|
|
473
|
+
else:
|
|
474
|
+
ctx.invoke(build_cmd)
|
|
446
475
|
|
|
447
476
|
site_path = _set_pythonpath()
|
|
448
477
|
if site_path:
|
|
@@ -467,8 +496,8 @@ def test(
|
|
|
467
496
|
if (n_jobs != "1") and ("-n" not in pytest_args):
|
|
468
497
|
pytest_args = ("-n", str(n_jobs)) + pytest_args
|
|
469
498
|
|
|
470
|
-
if
|
|
471
|
-
pytest_args = ("--
|
|
499
|
+
if not any("--import-mode" in arg for arg in pytest_args):
|
|
500
|
+
pytest_args = ("--import-mode=importlib",) + pytest_args
|
|
472
501
|
|
|
473
502
|
if verbose:
|
|
474
503
|
pytest_args = ("-v",) + pytest_args
|
|
@@ -491,11 +520,11 @@ def test(
|
|
|
491
520
|
else:
|
|
492
521
|
cmd = ["pytest"]
|
|
493
522
|
|
|
523
|
+
if not os.path.exists(install_dir):
|
|
524
|
+
os.mkdir(install_dir)
|
|
525
|
+
|
|
494
526
|
cwd = os.getcwd()
|
|
495
|
-
pytest_p = _run(
|
|
496
|
-
cmd + ([f"--rootdir={site_path}"] if site_path else []) + list(pytest_args),
|
|
497
|
-
cwd=site_path,
|
|
498
|
-
)
|
|
527
|
+
pytest_p = _run(cmd + list(pytest_args), cwd=site_path)
|
|
499
528
|
os.chdir(cwd)
|
|
500
529
|
|
|
501
530
|
if gcov:
|
|
@@ -509,7 +538,7 @@ def test(
|
|
|
509
538
|
|
|
510
539
|
# Generate report
|
|
511
540
|
click.secho(
|
|
512
|
-
f"Generating {gcov_format
|
|
541
|
+
f"Generating {gcov_format} coverage report...",
|
|
513
542
|
bold=True,
|
|
514
543
|
fg="bright_yellow",
|
|
515
544
|
)
|
|
@@ -518,7 +547,7 @@ def test(
|
|
|
518
547
|
"ninja",
|
|
519
548
|
"-C",
|
|
520
549
|
build_dir,
|
|
521
|
-
f"coverage-{gcov_format.
|
|
550
|
+
f"coverage-{gcov_format.lower()}",
|
|
522
551
|
],
|
|
523
552
|
output=False,
|
|
524
553
|
)
|
|
@@ -540,7 +569,7 @@ def test(
|
|
|
540
569
|
@click.option("--code", "-c", help="Python program passed in as a string")
|
|
541
570
|
@click.argument("gdb_args", nargs=-1)
|
|
542
571
|
@click.pass_context
|
|
543
|
-
def gdb(ctx, code, gdb_args):
|
|
572
|
+
def gdb(ctx, *, code, gdb_args):
|
|
544
573
|
"""👾 Execute code through GDB
|
|
545
574
|
|
|
546
575
|
spin gdb -c 'import numpy as np; print(np.__version__)'
|
|
@@ -592,7 +621,7 @@ def gdb(ctx, code, gdb_args):
|
|
|
592
621
|
@click.command()
|
|
593
622
|
@click.argument("ipython_args", nargs=-1)
|
|
594
623
|
@click.pass_context
|
|
595
|
-
def ipython(ctx, ipython_args):
|
|
624
|
+
def ipython(ctx, *, ipython_args):
|
|
596
625
|
"""💻 Launch IPython shell with PYTHONPATH set
|
|
597
626
|
|
|
598
627
|
IPYTHON_ARGS are passed through directly to IPython, e.g.:
|
|
@@ -646,7 +675,7 @@ def shell(ctx, shell_args=[]):
|
|
|
646
675
|
@click.command()
|
|
647
676
|
@click.argument("python_args", nargs=-1)
|
|
648
677
|
@click.pass_context
|
|
649
|
-
def python(ctx, python_args):
|
|
678
|
+
def python(ctx, *, python_args):
|
|
650
679
|
"""🐍 Launch Python shell with PYTHONPATH set
|
|
651
680
|
|
|
652
681
|
PYTHON_ARGS are passed through directly to Python, e.g.:
|
|
@@ -687,7 +716,7 @@ def python(ctx, python_args):
|
|
|
687
716
|
@click.command(context_settings={"ignore_unknown_options": True})
|
|
688
717
|
@click.argument("args", nargs=-1)
|
|
689
718
|
@click.pass_context
|
|
690
|
-
def run(ctx, args):
|
|
719
|
+
def run(ctx, *, args):
|
|
691
720
|
"""🏁 Run a shell command with PYTHONPATH set
|
|
692
721
|
|
|
693
722
|
\b
|
|
@@ -761,7 +790,16 @@ def run(ctx, args):
|
|
|
761
790
|
)
|
|
762
791
|
@click.option("--jobs", "-j", default="auto", help="Number of parallel build jobs")
|
|
763
792
|
@click.pass_context
|
|
764
|
-
def docs(
|
|
793
|
+
def docs(
|
|
794
|
+
ctx,
|
|
795
|
+
*,
|
|
796
|
+
sphinx_target,
|
|
797
|
+
clean,
|
|
798
|
+
first_build,
|
|
799
|
+
jobs,
|
|
800
|
+
sphinx_gallery_plot,
|
|
801
|
+
clean_dirs=None,
|
|
802
|
+
):
|
|
765
803
|
"""📖 Build Sphinx documentation
|
|
766
804
|
|
|
767
805
|
By default, SPHINXOPTS="-W", raising errors on warnings.
|
|
@@ -793,13 +831,18 @@ def docs(ctx, sphinx_target, clean, first_build, jobs, sphinx_gallery_plot):
|
|
|
793
831
|
sphinx_target = "help"
|
|
794
832
|
|
|
795
833
|
if clean:
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
834
|
+
if clean_dirs is None:
|
|
835
|
+
clean_dirs = []
|
|
836
|
+
for prefix in ("", "_"):
|
|
837
|
+
clean_dirs += [
|
|
838
|
+
f"./{doc_dir}/{prefix}build/",
|
|
839
|
+
f"./{doc_dir}/{prefix}build/",
|
|
840
|
+
f"./{doc_dir}/{prefix}source/api/",
|
|
841
|
+
f"./{doc_dir}/{prefix}source/auto_examples/",
|
|
842
|
+
f"./{doc_dir}/{prefix}source/jupyterlite_contents/",
|
|
843
|
+
]
|
|
844
|
+
|
|
845
|
+
for target_dir in clean_dirs:
|
|
803
846
|
if os.path.isdir(target_dir):
|
|
804
847
|
print(f"Removing {target_dir!r}")
|
|
805
848
|
shutil.rmtree(target_dir)
|
|
@@ -837,14 +880,17 @@ def docs(ctx, sphinx_target, clean, first_build, jobs, sphinx_gallery_plot):
|
|
|
837
880
|
bold=True,
|
|
838
881
|
fg="bright_blue",
|
|
839
882
|
)
|
|
840
|
-
|
|
883
|
+
|
|
884
|
+
make_bat_exists = (Path(doc_dir) / "make.bat").exists()
|
|
885
|
+
make_cmd = "make.bat" if sys.platform == "win32" and make_bat_exists else "make"
|
|
886
|
+
_run([make_cmd, sphinx_target], cwd=doc_dir, replace=True)
|
|
841
887
|
|
|
842
888
|
|
|
843
889
|
@click.command()
|
|
844
890
|
@click.option("--code", "-c", help="Python program passed in as a string")
|
|
845
891
|
@click.argument("lldb_args", nargs=-1)
|
|
846
892
|
@click.pass_context
|
|
847
|
-
def lldb(ctx, code, lldb_args):
|
|
893
|
+
def lldb(ctx, *, code, lldb_args):
|
|
848
894
|
"""👾 Execute code through LLDB
|
|
849
895
|
|
|
850
896
|
spin lldb -c 'import numpy as np; print(np.__version__)'
|
|
@@ -5,20 +5,19 @@ from .util import run as _run
|
|
|
5
5
|
|
|
6
6
|
@click.command()
|
|
7
7
|
@click.option(
|
|
8
|
-
"-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
default=False,
|
|
12
|
-
help="Print detailed build and installation output",
|
|
8
|
+
"--editable/--no-editable",
|
|
9
|
+
default=True,
|
|
10
|
+
help="Install in editable mode.",
|
|
13
11
|
)
|
|
12
|
+
@click.option("-v", "--verbose", is_flag=True, help="Print detailed build output.")
|
|
14
13
|
@click.option(
|
|
15
|
-
"--
|
|
14
|
+
"--verbose-import/--no-verbose-import",
|
|
16
15
|
is_flag=True,
|
|
17
16
|
default=True,
|
|
18
|
-
help="
|
|
17
|
+
help="Meson only: importing an editable install may trigger a build. This flag determines whether to print that build's output.",
|
|
19
18
|
)
|
|
20
19
|
@click.argument("pip_args", nargs=-1)
|
|
21
|
-
def install(pip_args, verbose,
|
|
20
|
+
def install(*, pip_args, editable, verbose, verbose_import):
|
|
22
21
|
"""💽 Build and install package using pip.
|
|
23
22
|
|
|
24
23
|
By default, the package is installed in editable mode.
|
|
@@ -34,9 +33,14 @@ def install(pip_args, verbose, editable):
|
|
|
34
33
|
pip_args = list(pip_args)
|
|
35
34
|
pip_cmd = ["pip", "install"]
|
|
36
35
|
pip_args += ["--no-build-isolation"]
|
|
36
|
+
|
|
37
37
|
if editable:
|
|
38
38
|
pip_args += ["--editable"]
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
if verbose_import:
|
|
41
|
+
pip_args = ["--config-settings=editable-verbose=true"] + pip_args
|
|
42
|
+
|
|
43
|
+
if verbose:
|
|
44
|
+
pip_args = ["-v"] + pip_args
|
|
41
45
|
|
|
42
46
|
_run(pip_cmd + pip_args + ["."], sys_exit=False, replace=True)
|
|
@@ -2,13 +2,21 @@ import os
|
|
|
2
2
|
import shlex
|
|
3
3
|
import subprocess
|
|
4
4
|
import sys
|
|
5
|
+
from typing import Optional
|
|
5
6
|
|
|
6
7
|
import click
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
def run(
|
|
10
|
-
cmd
|
|
11
|
-
|
|
11
|
+
cmd: list[str],
|
|
12
|
+
cwd: Optional[str] = None, # in 3.10 and up: str | None
|
|
13
|
+
replace: bool = False,
|
|
14
|
+
sys_exit: bool = True,
|
|
15
|
+
output: bool = True,
|
|
16
|
+
echo: bool = True,
|
|
17
|
+
*args,
|
|
18
|
+
**kwargs,
|
|
19
|
+
) -> subprocess.CompletedProcess:
|
|
12
20
|
"""Run a shell command.
|
|
13
21
|
|
|
14
22
|
Parameters
|
|
@@ -33,6 +41,10 @@ def run(
|
|
|
33
41
|
|
|
34
42
|
Other arguments and keywords are passed directly to `subprocess.run`.
|
|
35
43
|
|
|
44
|
+
|
|
45
|
+
Returns
|
|
46
|
+
-------
|
|
47
|
+
p : CompletedProcess
|
|
36
48
|
"""
|
|
37
49
|
if cwd:
|
|
38
50
|
if echo:
|
|
@@ -18,3 +18,10 @@ def pre_post_test():
|
|
|
18
18
|
os.chdir(cwd)
|
|
19
19
|
util.run(["git", "clean", "-xdf"], cwd="example_pkg")
|
|
20
20
|
os.chdir(cwd)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@pytest.fixture
|
|
24
|
+
def editable_install():
|
|
25
|
+
util.run(["pip", "install", "--quiet", "--no-build-isolation", "-e", "."])
|
|
26
|
+
yield
|
|
27
|
+
util.run(["pip", "uninstall", "--quiet", "-y", "example_pkg"])
|
|
@@ -5,7 +5,7 @@ import tempfile
|
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
|
|
7
7
|
import pytest
|
|
8
|
-
from testutil import skip_on_windows, skip_unless_linux, spin, stdout
|
|
8
|
+
from testutil import skip_on_windows, skip_unless_linux, skip_unless_macos, spin, stdout
|
|
9
9
|
|
|
10
10
|
from spin.cmds.util import run
|
|
11
11
|
|
|
@@ -88,16 +88,6 @@ def test_recommend_run_python():
|
|
|
88
88
|
), "Failed to recommend `python run python file.py`"
|
|
89
89
|
|
|
90
90
|
|
|
91
|
-
def test_test():
|
|
92
|
-
"""Does the test command run?"""
|
|
93
|
-
spin("test")
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
def test_test_with_pythonpath():
|
|
97
|
-
"""Does `spin test` work when PYTHONPATH is set?"""
|
|
98
|
-
spin("test", env={**os.environ, "PYTHONPATH": "/tmp"})
|
|
99
|
-
|
|
100
|
-
|
|
101
91
|
def test_sdist():
|
|
102
92
|
spin("sdist")
|
|
103
93
|
|
|
@@ -143,3 +133,17 @@ def test_gdb():
|
|
|
143
133
|
"--batch",
|
|
144
134
|
)
|
|
145
135
|
assert "hi" in stdout(p)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
@skip_unless_macos
|
|
139
|
+
def test_lldb():
|
|
140
|
+
p = spin(
|
|
141
|
+
"lldb",
|
|
142
|
+
"-c",
|
|
143
|
+
'import example_pkg; example_pkg.echo("hi")',
|
|
144
|
+
"--",
|
|
145
|
+
"-o",
|
|
146
|
+
"run",
|
|
147
|
+
"--batch",
|
|
148
|
+
)
|
|
149
|
+
assert "hi" in stdout(p)
|
|
@@ -1,15 +1,5 @@
|
|
|
1
|
-
import pytest
|
|
2
1
|
from testutil import spin, stdout
|
|
3
2
|
|
|
4
|
-
from spin.cmds.util import run
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
@pytest.fixture
|
|
8
|
-
def editable_install():
|
|
9
|
-
run(["pip", "install", "--quiet", "--no-build-isolation", "-e", "."])
|
|
10
|
-
yield
|
|
11
|
-
run(["pip", "uninstall", "--quiet", "-y", "example_pkg"])
|
|
12
|
-
|
|
13
3
|
|
|
14
4
|
def test_detect_editable(editable_install):
|
|
15
5
|
assert "Editable install of same source detected" in stdout(
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from testutil import spin
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_test():
|
|
7
|
+
"""Does the test command run?"""
|
|
8
|
+
spin("test")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def test_test_with_pythonpath():
|
|
12
|
+
"""Does `spin test` work when PYTHONPATH is set?"""
|
|
13
|
+
spin("test", env={**os.environ, "PYTHONPATH": "/tmp"})
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def test_test_file_spec():
|
|
17
|
+
spin("test", "example_pkg/submodule/tests/test_submodule.py")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def test_test_module_spec():
|
|
21
|
+
spin("test", "example_pkg.submodule")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def test_test_editable_file_spec(editable_install):
|
|
25
|
+
spin("test", "example_pkg/submodule/tests/test_submodule.py")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def test_test_editable_module_spec(editable_install):
|
|
29
|
+
spin("test", "example_pkg.submodule")
|
|
@@ -13,6 +13,10 @@ skip_unless_linux = pytest.mark.skipif(
|
|
|
13
13
|
not sys.platform.startswith("linux"), reason="Skipped; platform not Linux"
|
|
14
14
|
)
|
|
15
15
|
|
|
16
|
+
skip_unless_macos = pytest.mark.skipif(
|
|
17
|
+
not sys.platform.startswith("darwin"), reason="Skipped; platform not macOS"
|
|
18
|
+
)
|
|
19
|
+
|
|
16
20
|
|
|
17
21
|
def spin(*args, **user_kwargs):
|
|
18
22
|
args = (str(el) for el in args)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: spin
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11
|
|
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
|
|
@@ -55,7 +55,7 @@ Requires-Dist: tomli; python_version < "3.11"
|
|
|
55
55
|
Requires-Dist: colorama; platform_system == "Windows"
|
|
56
56
|
Requires-Dist: importlib_metadata>=7
|
|
57
57
|
Provides-Extra: lint
|
|
58
|
-
Requires-Dist: pre-commit==3.7.
|
|
58
|
+
Requires-Dist: pre-commit==3.7.1; extra == "lint"
|
|
59
59
|
Provides-Extra: dev
|
|
60
60
|
Requires-Dist: changelist==0.5; extra == "dev"
|
|
61
61
|
|
|
@@ -120,7 +120,7 @@ These commands will then be rendered as:
|
|
|
120
120
|
|
|
121
121
|
```
|
|
122
122
|
Build:
|
|
123
|
-
build 🔧 Build package with Meson/ninja
|
|
123
|
+
build 🔧 Build package with Meson/ninja
|
|
124
124
|
test 🔧 Run tests
|
|
125
125
|
|
|
126
126
|
Environments:
|
|
@@ -147,7 +147,7 @@ python -m spin
|
|
|
147
147
|
Available as `spin.cmds.meson.*`.
|
|
148
148
|
|
|
149
149
|
```
|
|
150
|
-
build 🔧 Build package with Meson/ninja
|
|
150
|
+
build 🔧 Build package with Meson/ninja
|
|
151
151
|
ipython 💻 Launch IPython shell with PYTHONPATH set
|
|
152
152
|
python 🐍 Launch Python shell with PYTHONPATH set
|
|
153
153
|
shell 💻 Launch shell with PYTHONPATH set
|
|
@@ -171,9 +171,6 @@ Available as `spin.cmds.build.*`:
|
|
|
171
171
|
`pip` allows for editable installs, another common
|
|
172
172
|
development workflow.
|
|
173
173
|
|
|
174
|
-
Note that, for now, the meson commands above do not work with an
|
|
175
|
-
editable install of the package. We're [working on changing that](https://github.com/scientific-python/spin/pull/141).
|
|
176
|
-
|
|
177
174
|
Available as `spin.cmds.pip.*`:
|
|
178
175
|
|
|
179
176
|
```
|
spin-0.9/spin/cmds/__init__.py
DELETED
{spin-0.9 → spin-0.11}/LICENSE
RENAMED
|
File without changes
|
{spin-0.9 → spin-0.11}/setup.cfg
RENAMED
|
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
|