calkit-python 0.11.0__tar.gz → 0.11.1__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 (66) hide show
  1. {calkit_python-0.11.0 → calkit_python-0.11.1}/PKG-INFO +1 -1
  2. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/__init__.py +1 -1
  3. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/conda.py +37 -30
  4. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/tests/test_conda.py +38 -1
  5. {calkit_python-0.11.0 → calkit_python-0.11.1}/.github/FUNDING.yml +0 -0
  6. {calkit_python-0.11.0 → calkit_python-0.11.1}/.github/workflows/publish-test.yml +0 -0
  7. {calkit_python-0.11.0 → calkit_python-0.11.1}/.github/workflows/publish.yml +0 -0
  8. {calkit_python-0.11.0 → calkit_python-0.11.1}/.gitignore +0 -0
  9. {calkit_python-0.11.0 → calkit_python-0.11.1}/LICENSE +0 -0
  10. {calkit_python-0.11.0 → calkit_python-0.11.1}/README.md +0 -0
  11. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/calc.py +0 -0
  12. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/check.py +0 -0
  13. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/cli/__init__.py +0 -0
  14. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/cli/check.py +0 -0
  15. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/cli/config.py +0 -0
  16. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/cli/core.py +0 -0
  17. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/cli/import_.py +0 -0
  18. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/cli/list.py +0 -0
  19. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/cli/main.py +0 -0
  20. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/cli/new.py +0 -0
  21. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/cli/notebooks.py +0 -0
  22. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/cli/office.py +0 -0
  23. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/cli/update.py +0 -0
  24. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/cloud.py +0 -0
  25. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/config.py +0 -0
  26. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/core.py +0 -0
  27. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/data.py +0 -0
  28. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/docker.py +0 -0
  29. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/dvc.py +0 -0
  30. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/git.py +0 -0
  31. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/gui.py +0 -0
  32. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/jupyter.py +0 -0
  33. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/magics.py +0 -0
  34. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/models.py +0 -0
  35. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/office.py +0 -0
  36. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/server.py +0 -0
  37. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/templates/__init__.py +0 -0
  38. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/templates/core.py +0 -0
  39. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/templates/latex/__init__.py +0 -0
  40. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/templates/latex/article/paper.tex +0 -0
  41. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/templates/latex/core.py +0 -0
  42. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/templates/latex/jfm/jfm.bst +0 -0
  43. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/templates/latex/jfm/jfm.cls +0 -0
  44. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/templates/latex/jfm/lineno-FLM.sty +0 -0
  45. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/templates/latex/jfm/paper.tex +0 -0
  46. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/templates/latex/jfm/upmath.sty +0 -0
  47. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/tests/__init__.py +0 -0
  48. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/tests/cli/__init__.py +0 -0
  49. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/tests/cli/test_list.py +0 -0
  50. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/tests/cli/test_main.py +0 -0
  51. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/tests/cli/test_new.py +0 -0
  52. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/tests/test_calc.py +0 -0
  53. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/tests/test_check.py +0 -0
  54. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/tests/test_core.py +0 -0
  55. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/tests/test_dvc.py +0 -0
  56. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/tests/test_jupyter.py +0 -0
  57. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/tests/test_magics.py +0 -0
  58. {calkit_python-0.11.0 → calkit_python-0.11.1}/calkit/tests/test_templates.py +0 -0
  59. {calkit_python-0.11.0 → calkit_python-0.11.1}/docs/img/calkit-no-bg.png +0 -0
  60. {calkit_python-0.11.0 → calkit_python-0.11.1}/docs/tutorials/adding-latex-pub-docker.md +0 -0
  61. {calkit_python-0.11.0 → calkit_python-0.11.1}/docs/tutorials/conda-envs.md +0 -0
  62. {calkit_python-0.11.0 → calkit_python-0.11.1}/docs/tutorials/img/run-proc.png +0 -0
  63. {calkit_python-0.11.0 → calkit_python-0.11.1}/docs/tutorials/notebook-pipeline.md +0 -0
  64. {calkit_python-0.11.0 → calkit_python-0.11.1}/docs/tutorials/procedures.md +0 -0
  65. {calkit_python-0.11.0 → calkit_python-0.11.1}/pyproject.toml +0 -0
  66. {calkit_python-0.11.0 → calkit_python-0.11.1}/test/pipeline.ipynb +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: calkit-python
3
- Version: 0.11.0
3
+ Version: 0.11.1
4
4
  Summary: Reproducibility simplified.
5
5
  Project-URL: Homepage, https://github.com/calkit/calkit
6
6
  Project-URL: Issues, https://github.com/calkit/calkit/issues
@@ -1,4 +1,4 @@
1
- __version__ = "0.11.0"
1
+ __version__ = "0.11.1"
2
2
 
3
3
  from .core import *
4
4
  from . import git
@@ -2,14 +2,43 @@
2
2
 
3
3
  import json
4
4
  import os
5
+ import re
5
6
  import subprocess
6
7
 
8
+ from packaging.specifiers import SpecifierSet
9
+ from packaging.version import Version
7
10
  from pydantic import BaseModel
8
11
 
9
12
  import calkit
10
13
  from calkit import ryaml
11
14
 
12
15
 
16
+ def _check_single(req: str, actual: str, conda: bool = False) -> bool:
17
+ """Helper function for checking actual versions against requirements."""
18
+ req_name = re.split("[=<>]", req)[0]
19
+ req_spec = req.removeprefix(req_name)
20
+ if conda and req_spec.startswith("="):
21
+ req_spec = "=" + req_spec
22
+ if not req_spec.endswith(".*"):
23
+ req_spec += ".*"
24
+ actual_name, actual_vers = re.split("[=<>]+", actual, maxsplit=1)
25
+ if actual_name != req_name:
26
+ return False
27
+ actual_spec = actual.removeprefix(actual_name)
28
+ if conda and actual_spec.startswith("="):
29
+ actual_spec = "=" + actual_spec
30
+ version = Version(actual_vers)
31
+ spec = SpecifierSet(req_spec)
32
+ return spec.contains(version)
33
+
34
+
35
+ def _check_list(req: str, actual: list[str], conda: bool = False) -> bool:
36
+ for installed in actual:
37
+ if _check_single(req, installed, conda=conda):
38
+ return True
39
+ return False
40
+
41
+
13
42
  class EnvCheckResult(BaseModel):
14
43
  env_exists: bool | None = None
15
44
  env_needs_export: bool | None = None
@@ -127,45 +156,23 @@ def check_env(
127
156
  required_conda_deps.append(dep.replace("==", "="))
128
157
  log_func("Checking conda dependencies")
129
158
  for dep in required_conda_deps:
130
- dep_split = dep.split("=")
131
- package = dep_split[0]
132
- if len(dep_split) > 1:
133
- version = dep_split[1]
134
- else:
135
- version = None
136
- if version is not None and dep not in existing_conda_deps:
159
+ is_okay = _check_list(
160
+ req=dep, actual=existing_conda_deps, conda=True
161
+ )
162
+ if not is_okay:
137
163
  log_func(f"Found missing dependency: {dep}")
138
164
  env_needs_rebuild = True
139
165
  break
140
- elif version is None:
141
- # TODO: This does not handle specification of only major or
142
- # major+minor version
143
- if package not in [
144
- d.split("=")[0] for d in existing_conda_deps
145
- ]:
146
- log_func(f"Found missing dependency: {dep}")
147
- env_needs_rebuild = True
148
- break
149
166
  if not env_needs_rebuild and not relaxed:
150
167
  log_func("Checking pip dependencies")
151
168
  for dep in required_pip_deps:
152
- dep_split = dep.split("==")
153
- package = dep_split[0]
154
- if len(dep_split) > 1:
155
- version = dep_split[1]
156
- else:
157
- version = None
158
- if version is not None and dep not in existing_pip_deps:
169
+ is_okay = _check_list(
170
+ req=dep, actual=existing_pip_deps, conda=False
171
+ )
172
+ if not is_okay:
159
173
  env_needs_rebuild = True
160
174
  log_func(f"Found missing dependency: {dep}")
161
175
  break
162
- elif version is None:
163
- if package not in [
164
- d.split("==")[0] for d in existing_pip_deps
165
- ]:
166
- log_func(f"Found missing dependency: {dep}")
167
- env_needs_rebuild = True
168
- break
169
176
  if env_needs_rebuild:
170
177
  res.env_needs_rebuild = True
171
178
  log_func(f"Rebuilding {env_name} since it does not match spec")
@@ -5,7 +5,25 @@ import uuid
5
5
 
6
6
  import pytest
7
7
 
8
- from calkit.conda import check_env
8
+ from calkit.conda import _check_list, _check_single, check_env
9
+
10
+
11
+ def test_check_single():
12
+ assert _check_single("python=3.12", "python=3.12.18", conda=True)
13
+ assert _check_single("python=3", "python=3.12.18", conda=True)
14
+ assert _check_single("python=3.12.18", "python=3.12.18", conda=True)
15
+ assert _check_single("python>=3.12,<3.13", "python==3.12.18", conda=False)
16
+
17
+
18
+ def test_check_list():
19
+ installed = ["python=3.12.1", "numpy=1.0.11"]
20
+ assert _check_list("python=3", installed, conda=True)
21
+ assert _check_list("numpy", installed, conda=True)
22
+ assert not _check_list("pandas", installed, conda=True)
23
+ installed = ["python==3.12.1", "numpy==1.0.11"]
24
+ assert _check_list("python>=3", installed, conda=False)
25
+ assert _check_list("numpy", installed, conda=False)
26
+ assert not _check_list("pandas", installed, conda=False)
9
27
 
10
28
 
11
29
  def delete_env(name: str):
@@ -124,3 +142,22 @@ def test_check_env(tmp_dir, env_name):
124
142
  )
125
143
  res = check_env(relaxed=True)
126
144
  assert not res.env_needs_rebuild
145
+ # Make sure we can handle other ways of specifying versions
146
+ subprocess.check_call(
147
+ [
148
+ "calkit",
149
+ "new",
150
+ "conda-env",
151
+ "--overwrite",
152
+ "-n",
153
+ env_name,
154
+ "python=3.12",
155
+ "--pip",
156
+ "numpy>=1",
157
+ ]
158
+ )
159
+ res = check_env()
160
+ assert res.env_needs_rebuild
161
+ res = check_env()
162
+ assert not res.env_needs_export
163
+ assert not res.env_needs_rebuild
File without changes
File without changes