calkit-python 0.47.2__py3-none-any.whl → 0.47.3__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 (25) hide show
  1. calkit/cli/latex.py +38 -1
  2. calkit/cli/main/core.py +8 -0
  3. calkit/conda.py +68 -7
  4. calkit/tests/cli/main/test_core.py +40 -0
  5. calkit/tests/cli/test_latex.py +15 -0
  6. calkit/tests/test_conda.py +59 -0
  7. {calkit_python-0.47.2.dist-info → calkit_python-0.47.3.dist-info}/METADATA +1 -1
  8. {calkit_python-0.47.2.dist-info → calkit_python-0.47.3.dist-info}/RECORD +25 -25
  9. {calkit_python-0.47.2.data → calkit_python-0.47.3.data}/data/etc/jupyter/jupyter_server_config.d/calkit.json +0 -0
  10. {calkit_python-0.47.2.data → calkit_python-0.47.3.data}/data/share/jupyter/labextensions/calkit/package.json +0 -0
  11. {calkit_python-0.47.2.data → calkit_python-0.47.3.data}/data/share/jupyter/labextensions/calkit/schemas/calkit/package.json.orig +0 -0
  12. {calkit_python-0.47.2.data → calkit_python-0.47.3.data}/data/share/jupyter/labextensions/calkit/schemas/calkit/plugin.json +0 -0
  13. {calkit_python-0.47.2.data → calkit_python-0.47.3.data}/data/share/jupyter/labextensions/calkit/static/502.9a2c5772a15466e923ef.js +0 -0
  14. {calkit_python-0.47.2.data → calkit_python-0.47.3.data}/data/share/jupyter/labextensions/calkit/static/695.2c41003a452d43d2b358.js +0 -0
  15. {calkit_python-0.47.2.data → calkit_python-0.47.3.data}/data/share/jupyter/labextensions/calkit/static/867.a42a046aa5108f54f8fb.js +0 -0
  16. {calkit_python-0.47.2.data → calkit_python-0.47.3.data}/data/share/jupyter/labextensions/calkit/static/909.6d8285ce7c45878ac508.js +0 -0
  17. {calkit_python-0.47.2.data → calkit_python-0.47.3.data}/data/share/jupyter/labextensions/calkit/static/946.050af2abf7845cfbdbd2.js +0 -0
  18. {calkit_python-0.47.2.data → calkit_python-0.47.3.data}/data/share/jupyter/labextensions/calkit/static/946.050af2abf7845cfbdbd2.js.LICENSE.txt +0 -0
  19. {calkit_python-0.47.2.data → calkit_python-0.47.3.data}/data/share/jupyter/labextensions/calkit/static/b2f1c3efe70cb539d121.png +0 -0
  20. {calkit_python-0.47.2.data → calkit_python-0.47.3.data}/data/share/jupyter/labextensions/calkit/static/remoteEntry.d7a43c7948f690d37d19.js +0 -0
  21. {calkit_python-0.47.2.data → calkit_python-0.47.3.data}/data/share/jupyter/labextensions/calkit/static/style.js +0 -0
  22. {calkit_python-0.47.2.data → calkit_python-0.47.3.data}/data/share/jupyter/labextensions/calkit/static/third-party-licenses.json +0 -0
  23. {calkit_python-0.47.2.dist-info → calkit_python-0.47.3.dist-info}/WHEEL +0 -0
  24. {calkit_python-0.47.2.dist-info → calkit_python-0.47.3.dist-info}/entry_points.txt +0 -0
  25. {calkit_python-0.47.2.dist-info → calkit_python-0.47.3.dist-info}/licenses/LICENSE +0 -0
calkit/cli/latex.py CHANGED
@@ -5,6 +5,7 @@ from __future__ import annotations
5
5
  import hashlib
6
6
  import json
7
7
  import os
8
+ import re
8
9
  import shutil
9
10
  import string
10
11
  import subprocess
@@ -539,8 +540,44 @@ def _build_diff(
539
540
  try:
540
541
  # --flatten pulls \input and \include files into one document on
541
542
  # each side, so a multi-file paper compares as a whole
543
+ latexdiff_cmd = ["latexdiff", "--flatten", "--encoding=utf8"]
544
+ # latexdiff dies trying to open a verbatim input that's a macro
545
+ # parameter, e.g., \verbatiminput{#1.wcsum} in a \newcommand, so a
546
+ # filter breaks the line after the command, which TeX reads the same
547
+ # but latexdiff's pattern doesn't match
548
+ verbatim_param = re.compile(
549
+ r"\\(?:verbatiminput\*?|lstinputlisting)"
550
+ r"\s*(?:\[[^\]\n]*\])?\s*\{[^}\n]*#[0-9]"
551
+ )
552
+ sources = [base_tex, head_tex] + [
553
+ path
554
+ for side in (base_tex, head_tex)
555
+ for path in calkit.latex.detect_inputs(side)
556
+ if Path(path).suffix in calkit.latex._SOURCE_EXTS
557
+ ]
558
+ if any(
559
+ os.path.isfile(path)
560
+ and verbatim_param.search(
561
+ Path(path).read_text(encoding="utf-8", errors="replace")
562
+ )
563
+ for path in sources
564
+ ):
565
+ filter_path = Path(DIFF_TMP_DIR, "verbatim-param-filter.pl")
566
+ os.makedirs(filter_path.parent, exist_ok=True)
567
+ # latexdiff appends a newline to what it sends, so drop it
568
+ filter_path.write_text(
569
+ "local $/;\n"
570
+ "my $text = <STDIN>;\n"
571
+ "$text =~ s/\\n\\z//;\n"
572
+ "$text =~ s/(\\\\(?:verbatiminput\\*?|lstinputlisting))"
573
+ "(?=\\s*(?:\\[[^\\]\\n]*\\])?\\s*\\{[^}\\n]*#[0-9])/$1%\\n/g;\n"
574
+ "print $text;\n"
575
+ )
576
+ latexdiff_cmd.append(
577
+ f"--filter-script=perl {filter_path.as_posix()}"
578
+ )
542
579
  cmd = _tex_cmd(
543
- ["latexdiff", "--flatten", "--encoding=utf8", base_tex, head_tex],
580
+ latexdiff_cmd + [base_tex, head_tex],
544
581
  environment=environment,
545
582
  no_check=no_check,
546
583
  verbose=verbose,
calkit/cli/main/core.py CHANGED
@@ -1672,6 +1672,14 @@ def push(
1672
1672
  git_cmd = ["git", "push"]
1673
1673
  if not no_recursive and "--recurse-submodules" not in git_args:
1674
1674
  git_cmd.append("--recurse-submodules=on-demand")
1675
+ # A plain `git push` leaves tags behind, so annotated tags end
1676
+ # up only on the machine that made them
1677
+ if not {
1678
+ "--follow-tags",
1679
+ "--no-follow-tags",
1680
+ "--tags",
1681
+ }.intersection(git_args):
1682
+ git_cmd.append("--follow-tags")
1675
1683
  subprocess.check_call(git_cmd + git_args)
1676
1684
  except subprocess.CalledProcessError:
1677
1685
  raise_error("Git push failed")
calkit/conda.py CHANGED
@@ -207,6 +207,42 @@ def _normalize_git_dep_url(dep: str) -> str:
207
207
  return url.rstrip("/")
208
208
 
209
209
 
210
+ def _unparseable_version_satisfies(
211
+ req_spec: str, actual_vers: str
212
+ ) -> bool | None:
213
+ """Check a requirement spec against a version string PEP 440 rejects.
214
+
215
+ Returns ``True`` or ``False`` when every clause in ``req_spec`` is a plain
216
+ equality or inequality (``==``, ``===`` or ``!=``), since those can be
217
+ decided by comparing the version strings directly. Returns ``None`` when
218
+ the spec needs version ordering (``<``, ``<=``, ``>``, ``>=``, ``~=``) or
219
+ contains a wildcard, both of which need a parsed version.
220
+
221
+ An empty spec means any version satisfies the requirement.
222
+
223
+ The comparison is an exact string match: without a parsed version there is
224
+ no zero-padding, so ``==1.0`` will not match an installed ``1.0.0``.
225
+ """
226
+ if not req_spec:
227
+ return True
228
+ clauses = [clause for clause in req_spec.split(",") if clause]
229
+ for clause in clauses:
230
+ for op in ("===", "==", "!="):
231
+ if not clause.startswith(op):
232
+ continue
233
+ value = clause[len(op) :]
234
+ if "*" in value:
235
+ # Wildcards need normalised versions to expand.
236
+ return None
237
+ if (actual_vers == value) == (op == "!="):
238
+ return False
239
+ break
240
+ else:
241
+ # An ordering operator, or something unrecognized.
242
+ return None
243
+ return True
244
+
245
+
210
246
  def _check_single(
211
247
  req: str, actual: str, env_spec_dir: str, conda: bool = False
212
248
  ) -> bool:
@@ -248,7 +284,10 @@ def _check_single(
248
284
  return _pkg_name_from_dep(req) == _pkg_name_from_dep(actual)
249
285
  if req_is_git:
250
286
  req = _GIT_RE.split(req)[0].strip()
251
- req_name = re.split("[=<>]", req)[0].strip()
287
+ # Split on the first version operator. "!" and "~" are in the class so
288
+ # that "!=" and "~=" requirements yield the bare package name instead of a
289
+ # name with the operator's leading character stuck to it.
290
+ req_name = re.split("[=<>!~]", req)[0].strip()
252
291
  req_spec = req.removeprefix(req_name).strip().replace(" ", "")
253
292
  if "[" in req_name:
254
293
  warnings.warn(f"Cannot check optional dependencies for {req_name}")
@@ -266,7 +305,7 @@ def _check_single(
266
305
  if actual_is_git:
267
306
  # Spec has no git URL but installed dep does; name match is sufficient
268
307
  actual = _GIT_RE.split(actual)[0].strip()
269
- actual_parts = re.split("[=<>]+", actual, maxsplit=1)
308
+ actual_parts = re.split("[=<>!~]+", actual, maxsplit=1)
270
309
  actual_name = actual_parts[0]
271
310
  actual_vers = actual_parts[1] if len(actual_parts) > 1 else ""
272
311
  if actual_name.strip().lower() != req_name.lower():
@@ -279,11 +318,33 @@ def _check_single(
279
318
  try:
280
319
  version = Version(actual_vers)
281
320
  except InvalidVersion:
282
- warnings.warn(
283
- f"Cannot properly check {actual_name} version {actual_vers}"
284
- )
285
- # TODO: Check exact version only
286
- return True
321
+ # An unparseable actual version (e.g. conda's "9e") can't go through
322
+ # SpecifierSet, which needs a parsed version to order by. Equality
323
+ # comparisons don't need ordering, so decide those from the version
324
+ # strings directly.
325
+ exact = _unparseable_version_satisfies(req_spec, actual_vers)
326
+ if exact is None:
327
+ # Ordering constraints and wildcards are genuinely undecidable
328
+ # here. A bare package name accepts any version; a pinned
329
+ # constraint we can't confirm counts as not satisfied rather than
330
+ # silently passing.
331
+ if not req_spec:
332
+ warnings.warn(
333
+ f"Cannot properly check {actual_name} version "
334
+ f"{actual_vers}"
335
+ )
336
+ return True
337
+ warnings.warn(
338
+ f"Cannot properly check {actual_name} version {actual_vers} "
339
+ f"against constraint '{req_spec}'"
340
+ )
341
+ return False
342
+ if not exact:
343
+ warnings.warn(
344
+ f"Installed {actual_name} version {actual_vers} does not "
345
+ f"satisfy '{req_spec}'"
346
+ )
347
+ return exact
287
348
  spec = SpecifierSet(req_spec)
288
349
  return spec.contains(version, prereleases=editable)
289
350
 
@@ -2784,3 +2784,43 @@ def test_push_reports_what_was_pushed(monkeypatch, tmp_dir):
2784
2784
  assert sent[-1]["targets"] == ["dvc"]
2785
2785
  cli_core._tell_hub_we_pushed(["dvc", "docker", "git"], [])
2786
2786
  assert sent[-1]["targets"] == ["dvc", "docker", "git"]
2787
+
2788
+
2789
+ def test_push_carries_annotated_tags(tmp_dir):
2790
+ """Annotated tags should reach the remote along with their commits.
2791
+
2792
+ A plain ``git push`` leaves tags behind, so a project that tags its
2793
+ results ends up with labels that exist only on the machine that made
2794
+ them.
2795
+ """
2796
+ remote = os.path.join(tmp_dir, "remote.git")
2797
+ subprocess.check_call(["git", "init", "--bare", "-q", remote])
2798
+ work = os.path.join(tmp_dir, "work")
2799
+ os.makedirs(work)
2800
+ os.chdir(work)
2801
+ subprocess.check_call(["git", "init", "-q"])
2802
+ subprocess.check_call(["git", "remote", "add", "origin", remote])
2803
+ # ``calkit init`` commits what it creates, so there is a commit to tag
2804
+ subprocess.check_call(["calkit", "init"])
2805
+ subprocess.check_call(["git", "tag", "-a", "v0.1.0", "-m", "First"])
2806
+ # An unannotated tag must stay local: --follow-tags is deliberately the
2807
+ # conservative form, so scratch tags do not get published by accident
2808
+ subprocess.check_call(["git", "tag", "scratch"])
2809
+ subprocess.check_call(
2810
+ [
2811
+ "calkit",
2812
+ "push",
2813
+ "git",
2814
+ "--git-arg",
2815
+ "-u",
2816
+ "--git-arg",
2817
+ "origin",
2818
+ "--git-arg",
2819
+ "HEAD",
2820
+ ]
2821
+ )
2822
+ tags = subprocess.check_output(
2823
+ ["git", "ls-remote", "--tags", remote], text=True
2824
+ )
2825
+ assert "v0.1.0" in tags
2826
+ assert "scratch" not in tags
@@ -358,6 +358,7 @@ def test_marked_up_digest_ignores_the_header():
358
358
  assert _marked_up_digest(changed) != _marked_up_digest(first)
359
359
 
360
360
 
361
+ @skipif_windows_docker
361
362
  def test_latex_diff_of_one_revision_against_itself(tmp_dir):
362
363
  # Two revisions that resolve to the same commit is what a pull request
363
364
  # diff looks like from the default branch. The pipeline resolves both
@@ -387,3 +388,17 @@ def test_latex_diff_of_one_revision_against_itself(tmp_dir):
387
388
  text=True,
388
389
  )
389
390
  assert "Nothing to compare" not in result.stderr
391
+ # A verbatim input that's a macro parameter used to make latexdiff try
392
+ # to open, e.g., '#1.wcsum' and fail
393
+ with open("paper/main.tex", "w") as f:
394
+ f.write("\\documentclass{article}\n\\usepackage{verbatim}\n")
395
+ f.write("\\newcommand{\\wc}[1]{\\verbatiminput{#1.wcsum}}\n")
396
+ f.write("\\begin{document}\nHi\n\\end{document}\n")
397
+ _commit("macro")
398
+ result = subprocess.run(
399
+ ["calkit", "latex", "diff", "paper/main.tex", "--from", sha],
400
+ capture_output=True,
401
+ text=True,
402
+ )
403
+ assert "Couldn't open" not in result.stderr
404
+ assert result.returncode == 0, result.stderr
@@ -14,6 +14,7 @@ from calkit.conda import (
14
14
  _enrich_pip_deps_from_freeze,
15
15
  _get_pip_dependency_list,
16
16
  _split_env_dependencies,
17
+ _unparseable_version_satisfies,
17
18
  check_env,
18
19
  find_conda_exe,
19
20
  )
@@ -77,6 +78,64 @@ def test_check_single():
77
78
  env_spec_dir=".",
78
79
  conda=False,
79
80
  )
81
+ # Unparseable actual version (e.g. conda's "9e"): equality and inequality
82
+ # are still decidable by comparing version strings, a bare name accepts any
83
+ # version, and an ordering constraint can't be confirmed so it counts as
84
+ # unsatisfied.
85
+ assert _check_single("jpeg", "jpeg=9e", env_spec_dir=".", conda=True)
86
+ assert _check_single("jpeg=9e", "jpeg=9e", env_spec_dir=".", conda=True)
87
+ assert _check_single("jpeg!=1", "jpeg=9e", env_spec_dir=".", conda=True)
88
+ assert not _check_single(
89
+ "jpeg!=9e", "jpeg=9e", env_spec_dir=".", conda=True
90
+ )
91
+ assert not _check_single("jpeg=1", "jpeg=9e", env_spec_dir=".", conda=True)
92
+ # conda's "=1.2" expands to "==1.2.*", and a wildcard needs a parsed
93
+ # version, so it stays unverifiable.
94
+ assert not _check_single(
95
+ "jpeg=1.2", "jpeg=9e", env_spec_dir=".", conda=True
96
+ )
97
+ assert not _check_single(
98
+ "jpeg>=1", "jpeg=9e", env_spec_dir=".", conda=True
99
+ )
100
+ # Pip-style specifiers behave the same way
101
+ assert _check_single("jpeg==9e", "jpeg==9e", env_spec_dir=".", conda=False)
102
+ # "!=" and "~=" must parse the package name correctly, which they didn't
103
+ # when the name was split on "=<>" alone
104
+ assert _check_single(
105
+ "jpeg!=1.0", "jpeg==9.0", env_spec_dir=".", conda=False
106
+ )
107
+ assert not _check_single(
108
+ "jpeg!=9.0", "jpeg==9.0", env_spec_dir=".", conda=False
109
+ )
110
+ assert _check_single(
111
+ "jpeg~=1.0", "jpeg==1.9", env_spec_dir=".", conda=False
112
+ )
113
+ assert not _check_single(
114
+ "jpeg~=1.0", "jpeg==2.0", env_spec_dir=".", conda=False
115
+ )
116
+
117
+
118
+ def test_unparseable_version_satisfies():
119
+ check = _unparseable_version_satisfies
120
+ # No constraint accepts anything
121
+ assert check("", "9e") is True
122
+ # Plain equality and inequality compare as strings
123
+ assert check("==9e", "9e") is True
124
+ assert check("==9e", "9f") is False
125
+ assert check("!=9e", "9e") is False
126
+ assert check("!=9f", "9e") is True
127
+ # PEP 440 arbitrary equality is also a string comparison
128
+ assert check("===9e", "9e") is True
129
+ # Conjunctions hold only if every clause holds
130
+ assert check("==9e,!=9f", "9e") is True
131
+ assert check("==9e,==9f", "9e") is False
132
+ # Wildcards and ordering operators need a parsed version
133
+ assert check("==1.*", "9e") is None
134
+ assert check("!=1.*", "9e") is None
135
+ assert check(">=1", "9e") is None
136
+ assert check("~=1.2", "9e") is None
137
+ # Matching is exact, with no zero-padding
138
+ assert check("==1.0", "1.0.0") is False
80
139
 
81
140
 
82
141
  def test_enrich_pip_deps_from_freeze():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: calkit-python
3
- Version: 0.47.2
3
+ Version: 0.47.3
4
4
  Summary: Reproducibility simplified.
5
5
  Project-URL: Homepage, https://calkit.org
6
6
  Project-URL: Issues, https://github.com/calkit/calkit/issues
@@ -1,7 +1,7 @@
1
1
  calkit/__init__.py,sha256=wZKQLIAhgCoR4vP8tWa2yFOPU9bUqE0qXWkOyFPyx1s,2920
2
2
  calkit/__main__.py,sha256=whqS7I7q_c9004emvKptZ9B9OVn-jgr5kaLaCFKmwa0,112
3
3
  calkit/calc.py,sha256=5RQVwH3goakmeDwHtmslcAZJXEZihIBuLNw_lF6QCcc,7924
4
- calkit/conda.py,sha256=Jb1Fz3jwkk4SZ0NgoWXd4lf50gEC8d8U87ElrYjdiwk,30752
4
+ calkit/conda.py,sha256=ddsHScMlPkpPU-d5vi-X--ANFvO2fi0fRFUFd_Ux51Y,33399
5
5
  calkit/config.py,sha256=RS-i2Qi4OczpjzkreNfLBX8ltZqSFSKIO9aiohvqXoA,20304
6
6
  calkit/core.py,sha256=z-2lQ61bOF90FUQvDFyi8cmZfMJ03gVLiQ8z16Ert5g,52259
7
7
  calkit/datasets.py,sha256=3YtDmvBCzyX5AC-7Mb7ylnxM1mFLyTLj5CH7QqblDwA,2212
@@ -46,7 +46,7 @@ calkit/cli/describe.py,sha256=LMODpla_g7hyTI7Oi7V5dAb9WSp5nZ_4-XhSYmZP1eo,3608
46
46
  calkit/cli/dev.py,sha256=cu4QsfDiA_KurGx4WJcgA2qgfghMoZutE8kl4IZbUcM,1070
47
47
  calkit/cli/hub.py,sha256=ZBOlL7-mV57q_ynr4hPuhV7NlkKEkINSRksXD-jjiOg,2972
48
48
  calkit/cli/import_.py,sha256=QOZEfKUmqMntle47PRZhN8cs7gfWCBte_smPZqksl54,25563
49
- calkit/cli/latex.py,sha256=AfhEgRKVBnWFkMl-6rhEvy814biFAkHehfjdrVh6qoY,36596
49
+ calkit/cli/latex.py,sha256=dp-bjrKvkzkKx0-k-AKqCL9HyH0a3iP0t4RoaRJUZpA,38190
50
50
  calkit/cli/list.py,sha256=CU5JCPYs7iNdzdaQoVzJcJj3cfZ_jfSdv6D048zP1Oo,18982
51
51
  calkit/cli/new.py,sha256=uoONf8jrrCx7R1tmRdInKjJGp_xeo9nTs9AzEixCe_M,158163
52
52
  calkit/cli/notebooks.py,sha256=aR4I0qatOtkrAxEG5PVLej20SBLKo8qr-lxDSzgljUQ,38836
@@ -56,7 +56,7 @@ calkit/cli/scheduler.py,sha256=s4q9wLcvTCmxuLmAoz7ptJZiNXPWCamn-NU1S5l28go,52719
56
56
  calkit/cli/sync.py,sha256=WlY5XwoS_KGJ2s7hZhsowcg73Y0L3YDKzYzbZp8obUw,12485
57
57
  calkit/cli/update.py,sha256=A1QWp1G69rMJkW058NbW29OXPZYEcKvuVW9WvBOqMso,53738
58
58
  calkit/cli/main/__init__.py,sha256=qu1POZPyqs33ZKfasOxv_Wc-EzVcEgK3Dt_vwFL8Bi8,65
59
- calkit/cli/main/core.py,sha256=8o1WzYjjadq6jUsRkKSUf_98pkW-qx-131xwUXvM7-Y,170778
59
+ calkit/cli/main/core.py,sha256=01dw513Qd3aJGCpQ_zu2QqMoQrNpF1lKz9HfWw-xFpg,171107
60
60
  calkit/cli/main/xr.py,sha256=cYQBNVlRTzp6ba3EwEwZylOxVpk9ThWhy6IAD7_ahWw,37594
61
61
  calkit/dvc/__init__.py,sha256=-B6tilCb_jw7QFmJ2srILez24wDhNKUzIBhZUMt01dE,381
62
62
  calkit/dvc/core.py,sha256=R6Fm65ZwG_yq0PNN3kfiMaQV_fba0B7MEkWHOhY8xhk,39505
@@ -97,7 +97,7 @@ calkit/templates/latex/jfm/upmath.sty,sha256=9nzNixqQd18zVrv0vLBjGjfnc8L19tP_m0b
97
97
  calkit/templates/latex/report/paper.tex,sha256=Sc_ZrBKg6DK_xjjUKkiHTjYXl0HoxSrJkwYgtcDJakA,1037
98
98
  calkit/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
99
99
  calkit/tests/test_calc.py,sha256=h-wOUIRqfyi06LTzhY_rS-a1xChZTkmwdEfBybMUM7E,2033
100
- calkit/tests/test_conda.py,sha256=me6nteGTmI6rN9xqHwn44OqkERCRUqLx57NnHeOpd8M,14433
100
+ calkit/tests/test_conda.py,sha256=-TMM_IKptQgmD8VZmS_6X67Ig9A2qMcSSCRKoHBtYbQ,16995
101
101
  calkit/tests/test_config.py,sha256=m08u_2IG4c391Vn_MYdJ4QS1w4PBHctUQa4IG7EsH6k,13656
102
102
  calkit/tests/test_core.py,sha256=FpQWshX_0XxCqDB9-HEqtnktZ_yvfz7MIyhywAzEqzI,14697
103
103
  calkit/tests/test_dependencies.py,sha256=Stb_pQr8HTrkUSTjZFAJ2aFOXAzlFNXtEjf2Uh0PF2E,12672
@@ -139,7 +139,7 @@ calkit/tests/cli/test_delete.py,sha256=qIbgwKc8nBjmkynzyVuVAjrQB96XSmGRet_jfxs19
139
139
  calkit/tests/cli/test_describe.py,sha256=uJ6r11Wkh1oVkPB-U9Kt5ktCSDFLTSL0OCIHy43sWIU,2657
140
140
  calkit/tests/cli/test_hub.py,sha256=z3ne8Bnjv-V85OEh15FbAV4STrFwZKMgl_DgWwQ2wzY,7385
141
141
  calkit/tests/cli/test_import.py,sha256=snQgCw6SM9V3g5NS8oBK-2B3bYFVyJcuXtJuFtDtfA8,13441
142
- calkit/tests/cli/test_latex.py,sha256=z6Y7OQp7n_FBMnTdQJD-qT5q268zBK7Up5eEcpS65oo,12566
142
+ calkit/tests/cli/test_latex.py,sha256=gzFaAf-u68fm-e5DORUd_d-mKOaINfa_BObbtQp7_4Y,13219
143
143
  calkit/tests/cli/test_list.py,sha256=5jc_OYI_rXNVv2UQc6IS8ItjQbBwEI5IDw5xKU_Uk98,9165
144
144
  calkit/tests/cli/test_new.py,sha256=Hpo7cHPyxWRVQF1JVkznO3YPhw9YxI92f017xLeHZLc,75600
145
145
  calkit/tests/cli/test_notebooks.py,sha256=2t1KiGhEz9H9LcIdWy4jGM05REUxJpWiIg6fSpX12ME,10678
@@ -148,7 +148,7 @@ calkit/tests/cli/test_scheduler.py,sha256=YfJi_fcRlQt1bdFyo3b8BFelA1PcH-wn5lAVXi
148
148
  calkit/tests/cli/test_sync.py,sha256=jmhfgoMIjdihIuu9UVyHSizBDTF0hlBt2VWqEdVkAKk,4375
149
149
  calkit/tests/cli/test_update.py,sha256=S2pBvJg8GCGVxie_eG9e176-opO43lKtHTvLK0x63ck,17783
150
150
  calkit/tests/cli/main/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
151
- calkit/tests/cli/main/test_core.py,sha256=Vy75WNMW5_N-BfoBAfrTG_P3NM5I5OOugn3Ronx7Tyk,103717
151
+ calkit/tests/cli/main/test_core.py,sha256=4Z294o-9IkljrKgZid8THkhifIZBeHTBCgVcgC77n-0,105126
152
152
  calkit/tests/cli/main/test_lock.py,sha256=1iX8iSbGtr4O9OkaAi4d3gP3_QzNl6Rr6HLtbEpS6iU,9847
153
153
  calkit/tests/cli/main/test_subprojects.py,sha256=Qs5NvwhQEFlZUvAtOyCWN243PONz8N79np5HwlgUl7E,18709
154
154
  calkit/tests/cli/main/test_xr.py,sha256=iauAWKXdzaaRFu5W91l4ZdH_ZU3h2NAn3v5p-EhAbco,28798
@@ -168,22 +168,22 @@ calkit/agent_skills/check-questions/SKILL.md,sha256=WlQWWuS-TgsoDU504WdLR6UW3Grc
168
168
  calkit/agent_skills/check-reproducibility/SKILL.md,sha256=5SGmtnbq8bSJW0Zwav_aVzfuhilHwBkkdxGuZvPHxGU,4699
169
169
  calkit/agent_skills/conventions/SKILL.md,sha256=kK0Sa54uIORAslE3U53sXJUG-TMdM-Ie72hCMIzzbxQ,8909
170
170
  calkit/agent_skills/create-pipeline/SKILL.md,sha256=2FGw1iDQVRk5FUq79GP3lPdgvgof2Wi1O9O-abGGtgs,5422
171
- calkit_python-0.47.2.data/data/etc/jupyter/jupyter_server_config.d/calkit.json,sha256=CWrZP--JDGz8fsvbAlKr_duTL1vDriGT48SL1YCtkY0,81
172
- calkit_python-0.47.2.data/data/share/jupyter/labextensions/calkit/package.json,sha256=tYRdVVqmPBoUJzNrMc7Da9Lk-NB54vhnplKRSlOTMIE,6224
173
- calkit_python-0.47.2.data/data/share/jupyter/labextensions/calkit/schemas/calkit/package.json.orig,sha256=NBG3t7gFYb6_2J-yPU29qS7Ck9pYgm8-wC5Q1LrzQeI,6082
174
- calkit_python-0.47.2.data/data/share/jupyter/labextensions/calkit/schemas/calkit/plugin.json,sha256=YSpIrwpwB-lQBk9Mwv-npedWTOOZreO6nlWZhqlWyGI,840
175
- calkit_python-0.47.2.data/data/share/jupyter/labextensions/calkit/static/502.9a2c5772a15466e923ef.js,sha256=mixXcqFUZukj7_jQVxHTavsYl7cdZv83sEe4phJgkh0,59893
176
- calkit_python-0.47.2.data/data/share/jupyter/labextensions/calkit/static/695.2c41003a452d43d2b358.js,sha256=LEEAOkUtQ9KzWEHn-QFv5yGi70B-sBOnrvztzHr0Shw,223
177
- calkit_python-0.47.2.data/data/share/jupyter/labextensions/calkit/static/867.a42a046aa5108f54f8fb.js,sha256=pCoEaqUQj1T4-zAc9SUd__9ZGm7uL2wHQve2xwL89NI,8156
178
- calkit_python-0.47.2.data/data/share/jupyter/labextensions/calkit/static/909.6d8285ce7c45878ac508.js,sha256=bYKFznxFh4rFCPs8tWnbZgaFGp72DuPZGdkzYCoCaSU,114583
179
- calkit_python-0.47.2.data/data/share/jupyter/labextensions/calkit/static/946.050af2abf7845cfbdbd2.js,sha256=n_a0yu_gE7l6fauyoXXv9BZ7ZEYt2387mTfs7CbLcs4,51939
180
- calkit_python-0.47.2.data/data/share/jupyter/labextensions/calkit/static/946.050af2abf7845cfbdbd2.js.LICENSE.txt,sha256=eNJ8gc9n9IF8nW1d9sI9niuHstYzjNz5vqXx9UgWSPc,249
181
- calkit_python-0.47.2.data/data/share/jupyter/labextensions/calkit/static/b2f1c3efe70cb539d121.png,sha256=svHD7-cMtTnRITFwugwsVaB9nZ-h8A61ose8z32HiRE,24850
182
- calkit_python-0.47.2.data/data/share/jupyter/labextensions/calkit/static/remoteEntry.d7a43c7948f690d37d19.js,sha256=16Q8eUj2kNN9Gaeoe3hOSEUPMJ5IUHQnJF1h9DRUIJY,8737
183
- calkit_python-0.47.2.data/data/share/jupyter/labextensions/calkit/static/style.js,sha256=r89Jlk5v1drcwhCpv9FnC3Jig_JH4k24kZNIvxh6Htk,149
184
- calkit_python-0.47.2.data/data/share/jupyter/labextensions/calkit/static/third-party-licenses.json,sha256=2BGdItLJwO3fAopLl4eJvp26TEwuscYC0-yFaF-LaLU,13683
185
- calkit_python-0.47.2.dist-info/METADATA,sha256=Eq2PAKShw5noFiVU_MBbHJMxpJ_KZ9v4uv-3ib057k0,12895
186
- calkit_python-0.47.2.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
187
- calkit_python-0.47.2.dist-info/entry_points.txt,sha256=TtpHpcv2vFVAVYxFVp0XrwCV_z7FWIOguEiypXRDoOw,131
188
- calkit_python-0.47.2.dist-info/licenses/LICENSE,sha256=9ZamCaSUTZk9rcrnf-sWFKLOHr3ws-S_dgKMegW4nw8,1056
189
- calkit_python-0.47.2.dist-info/RECORD,,
171
+ calkit_python-0.47.3.data/data/etc/jupyter/jupyter_server_config.d/calkit.json,sha256=CWrZP--JDGz8fsvbAlKr_duTL1vDriGT48SL1YCtkY0,81
172
+ calkit_python-0.47.3.data/data/share/jupyter/labextensions/calkit/package.json,sha256=tYRdVVqmPBoUJzNrMc7Da9Lk-NB54vhnplKRSlOTMIE,6224
173
+ calkit_python-0.47.3.data/data/share/jupyter/labextensions/calkit/schemas/calkit/package.json.orig,sha256=NBG3t7gFYb6_2J-yPU29qS7Ck9pYgm8-wC5Q1LrzQeI,6082
174
+ calkit_python-0.47.3.data/data/share/jupyter/labextensions/calkit/schemas/calkit/plugin.json,sha256=YSpIrwpwB-lQBk9Mwv-npedWTOOZreO6nlWZhqlWyGI,840
175
+ calkit_python-0.47.3.data/data/share/jupyter/labextensions/calkit/static/502.9a2c5772a15466e923ef.js,sha256=mixXcqFUZukj7_jQVxHTavsYl7cdZv83sEe4phJgkh0,59893
176
+ calkit_python-0.47.3.data/data/share/jupyter/labextensions/calkit/static/695.2c41003a452d43d2b358.js,sha256=LEEAOkUtQ9KzWEHn-QFv5yGi70B-sBOnrvztzHr0Shw,223
177
+ calkit_python-0.47.3.data/data/share/jupyter/labextensions/calkit/static/867.a42a046aa5108f54f8fb.js,sha256=pCoEaqUQj1T4-zAc9SUd__9ZGm7uL2wHQve2xwL89NI,8156
178
+ calkit_python-0.47.3.data/data/share/jupyter/labextensions/calkit/static/909.6d8285ce7c45878ac508.js,sha256=bYKFznxFh4rFCPs8tWnbZgaFGp72DuPZGdkzYCoCaSU,114583
179
+ calkit_python-0.47.3.data/data/share/jupyter/labextensions/calkit/static/946.050af2abf7845cfbdbd2.js,sha256=n_a0yu_gE7l6fauyoXXv9BZ7ZEYt2387mTfs7CbLcs4,51939
180
+ calkit_python-0.47.3.data/data/share/jupyter/labextensions/calkit/static/946.050af2abf7845cfbdbd2.js.LICENSE.txt,sha256=eNJ8gc9n9IF8nW1d9sI9niuHstYzjNz5vqXx9UgWSPc,249
181
+ calkit_python-0.47.3.data/data/share/jupyter/labextensions/calkit/static/b2f1c3efe70cb539d121.png,sha256=svHD7-cMtTnRITFwugwsVaB9nZ-h8A61ose8z32HiRE,24850
182
+ calkit_python-0.47.3.data/data/share/jupyter/labextensions/calkit/static/remoteEntry.d7a43c7948f690d37d19.js,sha256=16Q8eUj2kNN9Gaeoe3hOSEUPMJ5IUHQnJF1h9DRUIJY,8737
183
+ calkit_python-0.47.3.data/data/share/jupyter/labextensions/calkit/static/style.js,sha256=r89Jlk5v1drcwhCpv9FnC3Jig_JH4k24kZNIvxh6Htk,149
184
+ calkit_python-0.47.3.data/data/share/jupyter/labextensions/calkit/static/third-party-licenses.json,sha256=2BGdItLJwO3fAopLl4eJvp26TEwuscYC0-yFaF-LaLU,13683
185
+ calkit_python-0.47.3.dist-info/METADATA,sha256=XlYnQQhD0jSQPdMfobf5otA6sCfJpSkSy7vqZE0eR9o,12895
186
+ calkit_python-0.47.3.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
187
+ calkit_python-0.47.3.dist-info/entry_points.txt,sha256=TtpHpcv2vFVAVYxFVp0XrwCV_z7FWIOguEiypXRDoOw,131
188
+ calkit_python-0.47.3.dist-info/licenses/LICENSE,sha256=9ZamCaSUTZk9rcrnf-sWFKLOHr3ws-S_dgKMegW4nw8,1056
189
+ calkit_python-0.47.3.dist-info/RECORD,,