calkit-python 0.48.3__py3-none-any.whl → 0.49.1__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.
Files changed (72) hide show
  1. calkit/__init__.py +2 -2
  2. calkit/cli/__init__.py +65 -1
  3. calkit/cli/check.py +344 -47
  4. calkit/cli/core.py +7 -17
  5. calkit/cli/delete.py +25 -0
  6. calkit/cli/describe.py +9 -1
  7. calkit/cli/latex.py +90 -144
  8. calkit/cli/list.py +119 -0
  9. calkit/cli/main/core.py +595 -129
  10. calkit/cli/main/xr.py +55 -29
  11. calkit/cli/new.py +67 -0
  12. calkit/cli/overleaf.py +139 -109
  13. calkit/cli/scheduler.py +217 -2
  14. calkit/cli/update.py +161 -6
  15. calkit/conda.py +455 -41
  16. calkit/conditions.py +251 -0
  17. calkit/config.py +2 -25
  18. calkit/core.py +315 -114
  19. calkit/docker.py +112 -0
  20. calkit/dvc/core.py +224 -4
  21. calkit/environments.py +1226 -72
  22. calkit/latex.py +191 -24
  23. calkit/models/core.py +358 -220
  24. calkit/models/io.py +26 -2
  25. calkit/models/pipeline.py +202 -23
  26. calkit/models/requirements.py +250 -0
  27. calkit/overleaf.py +89 -8
  28. calkit/pipeline.py +499 -15
  29. calkit/questions.py +30 -160
  30. calkit/{dependencies.py → requirements.py} +196 -81
  31. calkit/tests/cli/main/test_core.py +550 -11
  32. calkit/tests/cli/main/test_xr.py +8 -0
  33. calkit/tests/cli/test_check.py +329 -0
  34. calkit/tests/cli/test_delete.py +53 -0
  35. calkit/tests/cli/test_describe.py +17 -0
  36. calkit/tests/cli/test_latex.py +80 -0
  37. calkit/tests/cli/test_list.py +142 -0
  38. calkit/tests/cli/test_new.py +60 -0
  39. calkit/tests/cli/test_overleaf.py +60 -1
  40. calkit/tests/cli/test_scheduler.py +146 -0
  41. calkit/tests/cli/test_update.py +162 -0
  42. calkit/tests/models/test_core.py +136 -1
  43. calkit/tests/test_conda.py +325 -0
  44. calkit/tests/test_conditions.py +114 -0
  45. calkit/tests/test_core.py +125 -3
  46. calkit/tests/test_docker.py +81 -0
  47. calkit/tests/test_environments.py +834 -1
  48. calkit/tests/test_overleaf.py +76 -0
  49. calkit/tests/test_pipeline.py +456 -3
  50. calkit/tests/test_questions.py +79 -127
  51. calkit/tests/{test_dependencies.py → test_requirements.py} +171 -46
  52. calkit/tests/test_workspace.py +65 -2
  53. calkit/upgrade.py +1 -1
  54. calkit/workspace.py +110 -28
  55. {calkit_python-0.48.3.dist-info → calkit_python-0.49.1.dist-info}/METADATA +4 -3
  56. {calkit_python-0.48.3.dist-info → calkit_python-0.49.1.dist-info}/RECORD +72 -69
  57. {calkit_python-0.48.3.data → calkit_python-0.49.1.data}/data/etc/jupyter/jupyter_server_config.d/calkit.json +0 -0
  58. {calkit_python-0.48.3.data → calkit_python-0.49.1.data}/data/share/jupyter/labextensions/calkit/package.json +0 -0
  59. {calkit_python-0.48.3.data → calkit_python-0.49.1.data}/data/share/jupyter/labextensions/calkit/schemas/calkit/package.json.orig +0 -0
  60. {calkit_python-0.48.3.data → calkit_python-0.49.1.data}/data/share/jupyter/labextensions/calkit/schemas/calkit/plugin.json +0 -0
  61. {calkit_python-0.48.3.data → calkit_python-0.49.1.data}/data/share/jupyter/labextensions/calkit/static/506.c34b070098184e33.js +0 -0
  62. {calkit_python-0.48.3.data → calkit_python-0.49.1.data}/data/share/jupyter/labextensions/calkit/static/57d13a7399cec3c5.png +0 -0
  63. {calkit_python-0.48.3.data → calkit_python-0.49.1.data}/data/share/jupyter/labextensions/calkit/static/616.528427eb54a4a0c0.js +0 -0
  64. {calkit_python-0.48.3.data → calkit_python-0.49.1.data}/data/share/jupyter/labextensions/calkit/static/740.6bf87276e9e5788a.js +0 -0
  65. {calkit_python-0.48.3.data → calkit_python-0.49.1.data}/data/share/jupyter/labextensions/calkit/static/899.f9b9f9bf705a6493.js +0 -0
  66. {calkit_python-0.48.3.data → calkit_python-0.49.1.data}/data/share/jupyter/labextensions/calkit/static/935.46ecc6bf99aa593a.js +0 -0
  67. {calkit_python-0.48.3.data → calkit_python-0.49.1.data}/data/share/jupyter/labextensions/calkit/static/remoteEntry.109a3a8379365e59.js +0 -0
  68. {calkit_python-0.48.3.data → calkit_python-0.49.1.data}/data/share/jupyter/labextensions/calkit/static/style.js +0 -0
  69. {calkit_python-0.48.3.data → calkit_python-0.49.1.data}/data/share/jupyter/labextensions/calkit/static/third-party-licenses.json +0 -0
  70. {calkit_python-0.48.3.dist-info → calkit_python-0.49.1.dist-info}/WHEEL +0 -0
  71. {calkit_python-0.48.3.dist-info → calkit_python-0.49.1.dist-info}/entry_points.txt +0 -0
  72. {calkit_python-0.48.3.dist-info → calkit_python-0.49.1.dist-info}/licenses/LICENSE +0 -0
calkit/__init__.py CHANGED
@@ -13,7 +13,6 @@ if TYPE_CHECKING:
13
13
  conda,
14
14
  config,
15
15
  datasets,
16
- dependencies,
17
16
  detect,
18
17
  docker,
19
18
  docx,
@@ -44,6 +43,7 @@ if TYPE_CHECKING:
44
43
  questions,
45
44
  releases,
46
45
  reproducibility,
46
+ requirements,
47
47
  resources,
48
48
  schema,
49
49
  server,
@@ -60,7 +60,6 @@ _SUBMODULES = {
60
60
  "conda",
61
61
  "config",
62
62
  "datasets",
63
- "dependencies",
64
63
  "detect",
65
64
  "docker",
66
65
  "docx",
@@ -91,6 +90,7 @@ _SUBMODULES = {
91
90
  "questions",
92
91
  "releases",
93
92
  "reproducibility",
93
+ "requirements",
94
94
  "resources",
95
95
  "schema",
96
96
  "server",
calkit/cli/__init__.py CHANGED
@@ -1,7 +1,17 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
1
5
  from .core import * # noqa: F403
2
6
 
7
+ if TYPE_CHECKING:
8
+ import typer
9
+
3
10
 
4
11
  def run() -> None:
12
+ import os
13
+ import sys
14
+
5
15
  # Intercept ``--use-version`` before Typer/Click parses argv: Click
6
16
  # processes eager options like ``--help`` and ``--version`` (and the
7
17
  # group's ``no_args_is_help``) ahead of the callback body, so an
@@ -11,7 +21,61 @@ def run() -> None:
11
21
  _maybe_exec_with_version()
12
22
  from .main import app
13
23
 
14
- app()
24
+ # Completion lists commands, so needs them all
25
+ if any(k.startswith("_") and k.endswith("_COMPLETE") for k in os.environ):
26
+ app()
27
+ else:
28
+ _only_invoked(app, sys.argv[1:])()
29
+
30
+
31
+ def _only_invoked(
32
+ app: typer.Typer, args: list[str], top: bool = True
33
+ ) -> typer.Typer:
34
+ """Narrow ``app`` to the command or group ``args`` invoke.
35
+
36
+ Typer builds every command's options before running one, which for all
37
+ of Calkit's takes a few tenths of a second, so this leaves out the ones
38
+ that won't run. Anything else, e.g., ``--help`` or a misspelled command,
39
+ keeps them all, so help and suggestions list everything.
40
+ decisions/calkit.yaml has a question on how much that saves.
41
+ """
42
+ import copy
43
+ import re
44
+
45
+ from typer.main import get_command_name, solve_typer_info_defaults
46
+
47
+ from .main.core import APP_OPTIONS_WITH_VALUES
48
+
49
+ # Find the command name, skipping the top level's options
50
+ takes_value = {
51
+ flag for flags in APP_OPTIONS_WITH_VALUES.values() for flag in flags
52
+ }
53
+ i = 0
54
+ while i < len(args) and args[i].startswith("-") and top:
55
+ i += 2 if args[i] in takes_value else 1
56
+ if i >= len(args) or args[i].startswith("-"):
57
+ return app
58
+ name, rest = args[i], args[i + 1 :]
59
+
60
+ def names(spec: str | None) -> list[str]:
61
+ return re.split(r" ?[,|] ?", spec) if spec else []
62
+
63
+ narrowed = copy.copy(app)
64
+ for cmd in app.registered_commands:
65
+ default = cmd.callback and get_command_name(cmd.callback.__name__)
66
+ if name in names(cmd.name or default):
67
+ narrowed.registered_commands = [cmd]
68
+ narrowed.registered_groups = []
69
+ return narrowed
70
+ for group in app.registered_groups:
71
+ sub_app = group.typer_instance
72
+ if sub_app and name in names(solve_typer_info_defaults(group).name):
73
+ group = copy.copy(group)
74
+ group.typer_instance = _only_invoked(sub_app, rest, top=False)
75
+ narrowed.registered_commands = []
76
+ narrowed.registered_groups = [group]
77
+ return narrowed
78
+ return app
15
79
 
16
80
 
17
81
  def _maybe_exec_with_version() -> None: