calkit-python 0.49.1__py3-none-any.whl → 0.49.2__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 (22) hide show
  1. calkit/cli/check.py +1 -1
  2. calkit/conda.py +1 -1
  3. calkit/environments.py +20 -12
  4. calkit/tests/test_environments.py +15 -4
  5. {calkit_python-0.49.1.dist-info → calkit_python-0.49.2.dist-info}/METADATA +1 -1
  6. {calkit_python-0.49.1.dist-info → calkit_python-0.49.2.dist-info}/RECORD +22 -22
  7. {calkit_python-0.49.1.data → calkit_python-0.49.2.data}/data/etc/jupyter/jupyter_server_config.d/calkit.json +0 -0
  8. {calkit_python-0.49.1.data → calkit_python-0.49.2.data}/data/share/jupyter/labextensions/calkit/package.json +0 -0
  9. {calkit_python-0.49.1.data → calkit_python-0.49.2.data}/data/share/jupyter/labextensions/calkit/schemas/calkit/package.json.orig +0 -0
  10. {calkit_python-0.49.1.data → calkit_python-0.49.2.data}/data/share/jupyter/labextensions/calkit/schemas/calkit/plugin.json +0 -0
  11. {calkit_python-0.49.1.data → calkit_python-0.49.2.data}/data/share/jupyter/labextensions/calkit/static/506.c34b070098184e33.js +0 -0
  12. {calkit_python-0.49.1.data → calkit_python-0.49.2.data}/data/share/jupyter/labextensions/calkit/static/57d13a7399cec3c5.png +0 -0
  13. {calkit_python-0.49.1.data → calkit_python-0.49.2.data}/data/share/jupyter/labextensions/calkit/static/616.528427eb54a4a0c0.js +0 -0
  14. {calkit_python-0.49.1.data → calkit_python-0.49.2.data}/data/share/jupyter/labextensions/calkit/static/740.6bf87276e9e5788a.js +0 -0
  15. {calkit_python-0.49.1.data → calkit_python-0.49.2.data}/data/share/jupyter/labextensions/calkit/static/899.f9b9f9bf705a6493.js +0 -0
  16. {calkit_python-0.49.1.data → calkit_python-0.49.2.data}/data/share/jupyter/labextensions/calkit/static/935.46ecc6bf99aa593a.js +0 -0
  17. {calkit_python-0.49.1.data → calkit_python-0.49.2.data}/data/share/jupyter/labextensions/calkit/static/remoteEntry.109a3a8379365e59.js +0 -0
  18. {calkit_python-0.49.1.data → calkit_python-0.49.2.data}/data/share/jupyter/labextensions/calkit/static/style.js +0 -0
  19. {calkit_python-0.49.1.data → calkit_python-0.49.2.data}/data/share/jupyter/labextensions/calkit/static/third-party-licenses.json +0 -0
  20. {calkit_python-0.49.1.dist-info → calkit_python-0.49.2.dist-info}/WHEEL +0 -0
  21. {calkit_python-0.49.1.dist-info → calkit_python-0.49.2.dist-info}/entry_points.txt +0 -0
  22. {calkit_python-0.49.1.dist-info → calkit_python-0.49.2.dist-info}/licenses/LICENSE +0 -0
calkit/cli/check.py CHANGED
@@ -2053,7 +2053,7 @@ def check_venv(
2053
2053
  )
2054
2054
  # Last, so an interrupted relock isn't taken as current
2055
2055
  calkit.environments.write_env_spec_hash(
2056
- lock_fpath, path, python=python, wdir=wdir
2056
+ lock_fpath, spec_hash, wdir=wdir
2057
2057
  )
2058
2058
  # Delete legacy lock file after use
2059
2059
  if used_legacy_lock:
calkit/conda.py CHANGED
@@ -995,7 +995,7 @@ def check_env(
995
995
  relock=spec_changed and recorded_hash is not None,
996
996
  )
997
997
  # Last, so an interrupted relock isn't taken as current
998
- write_env_spec_hash(lock_fpath, env_fpath)
998
+ write_env_spec_hash(lock_fpath, spec_hash)
999
999
  return res
1000
1000
 
1001
1001
 
calkit/environments.py CHANGED
@@ -1750,7 +1750,7 @@ def env_spec_hash(spec_fpath: str, python: str | None = None) -> str:
1750
1750
  if python is not None:
1751
1751
  content += f"\npython={python}"
1752
1752
  # Named so a reader knows what to check it with
1753
- return "md5:" + hashlib.md5(content.encode()).hexdigest()
1753
+ return "sha256:" + hashlib.sha256(content.encode()).hexdigest()
1754
1754
 
1755
1755
 
1756
1756
  def _env_spec_hash_key(lock_fpath: str, wdir: str | None) -> str:
@@ -1760,8 +1760,11 @@ def _env_spec_hash_key(lock_fpath: str, wdir: str | None) -> str:
1760
1760
  if lock_dir and os.path.splitext(name)[0] in CONDA_VENV_ARCHS:
1761
1761
  lock_fpath = lock_dir
1762
1762
  if os.path.isabs(lock_fpath):
1763
- lock_fpath = os.path.relpath(lock_fpath, wdir or ".")
1764
- return Path(lock_fpath).as_posix()
1763
+ try:
1764
+ lock_fpath = os.path.relpath(lock_fpath, wdir or ".")
1765
+ except ValueError: # On another Windows drive
1766
+ pass
1767
+ return Path(os.path.normpath(lock_fpath)).as_posix()
1765
1768
 
1766
1769
 
1767
1770
  def read_env_spec_hash(lock_fpath: str, wdir: str | None = None) -> str | None:
@@ -1775,16 +1778,17 @@ def read_env_spec_hash(lock_fpath: str, wdir: str | None = None) -> str | None:
1775
1778
  return None
1776
1779
  if not isinstance(hashes, dict):
1777
1780
  return None
1778
- return hashes.get(_env_spec_hash_key(lock_fpath, wdir))
1781
+ value = hashes.get(_env_spec_hash_key(lock_fpath, wdir))
1782
+ # Older md5 hashes would make every lock look stale, so they're ignored
1783
+ if isinstance(value, str) and value.startswith("sha256:"):
1784
+ return value
1785
+ return None
1779
1786
 
1780
1787
 
1781
1788
  def write_env_spec_hash(
1782
- lock_fpath: str,
1783
- spec_fpath: str,
1784
- python: str | None = None,
1785
- wdir: str | None = None,
1789
+ lock_fpath: str, spec_hash: str, wdir: str | None = None
1786
1790
  ) -> None:
1787
- """Record that a lock was resolved from the spec as it is now.
1791
+ """Record that a lock was resolved from a spec with the given hash.
1788
1792
 
1789
1793
  Kept outside the lock directory, which stages depend on, so recording
1790
1794
  it for a lock that already matches its spec reruns nothing.
@@ -1797,11 +1801,15 @@ def write_env_spec_hash(
1797
1801
  hashes = {}
1798
1802
  if not isinstance(hashes, dict):
1799
1803
  hashes = {}
1804
+ hashes = {
1805
+ k: v
1806
+ for k, v in hashes.items()
1807
+ if isinstance(v, str) and v.startswith("sha256:")
1808
+ }
1800
1809
  key = _env_spec_hash_key(lock_fpath, wdir)
1801
- value = env_spec_hash(os.path.join(wdir or "", spec_fpath), python=python)
1802
- if hashes.get(key) == value:
1810
+ if hashes.get(key) == spec_hash:
1803
1811
  return
1804
- hashes[key] = value
1812
+ hashes[key] = spec_hash
1805
1813
  os.makedirs(os.path.dirname(fpath), exist_ok=True)
1806
1814
  with open(fpath, "w", encoding="utf-8", newline="\n") as f:
1807
1815
  json.dump(hashes, f, indent=2, sort_keys=True)
@@ -2055,7 +2055,7 @@ def test_env_spec_hashes(tmp_dir):
2055
2055
  write(lock, "idna==3.10\n")
2056
2056
  # Recorded beside the lock, not in it
2057
2057
  assert envs.read_env_spec_hash(lock) is None
2058
- envs.write_env_spec_hash(lock, spec)
2058
+ envs.write_env_spec_hash(lock, envs.env_spec_hash(spec))
2059
2059
  assert envs.read_env_spec_hash(lock) == envs.env_spec_hash(spec)
2060
2060
  with open(lock) as f:
2061
2061
  assert f.read() == "idna==3.10\n"
@@ -2094,18 +2094,29 @@ def test_env_spec_hashes(tmp_dir):
2094
2094
  write(os.path.join("sub", spec), "idna\n")
2095
2095
  envs.write_env_spec_hash(
2096
2096
  os.path.join(".calkit", "env-locks", "py", "linux-64.txt"),
2097
- spec,
2097
+ envs.env_spec_hash(os.path.join("sub", spec)),
2098
2098
  wdir="sub",
2099
2099
  )
2100
2100
  assert envs.read_env_spec_hash(
2101
2101
  os.path.join(".calkit", "env-locks", "py", "win-64.txt"), wdir="sub"
2102
2102
  ) == envs.env_spec_hash(os.path.join("sub", spec))
2103
2103
  with open(os.path.join("sub", envs.ENV_SPEC_HASHES_FPATH)) as f:
2104
- assert list(json.load(f)) == [".calkit/env-locks/py"]
2104
+ assert json.load(f) == {
2105
+ ".calkit/env-locks/py": envs.env_spec_hash(
2106
+ os.path.join("sub", spec)
2107
+ )
2108
+ }
2109
+ assert envs.env_spec_hash(spec).startswith("sha256:")
2110
+ # Older md5 hashes aren't read, and are dropped on the next write
2111
+ write(envs.ENV_SPEC_HASHES_FPATH, json.dumps({"old": "md5:abc"}))
2112
+ assert envs.read_env_spec_hash("old") is None
2113
+ envs.write_env_spec_hash(lock, envs.env_spec_hash(spec))
2114
+ with open(envs.ENV_SPEC_HASHES_FPATH) as f:
2115
+ assert list(json.load(f)) == [lock]
2105
2116
  # An unreadable file records nothing, and is replaced on the next write
2106
2117
  write(envs.ENV_SPEC_HASHES_FPATH, "not json")
2107
2118
  assert envs.read_env_spec_hash(lock) is None
2108
- envs.write_env_spec_hash(lock, spec)
2119
+ envs.write_env_spec_hash(lock, envs.env_spec_hash(spec))
2109
2120
  assert envs.read_env_spec_hash(lock) == envs.env_spec_hash(spec)
2110
2121
 
2111
2122
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: calkit-python
3
- Version: 0.49.1
3
+ Version: 0.49.2
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=5DjFhcuxL5SlsB1Nm1Wf4APuYcR5Kg38IHCxGOhaFPA,2952
2
2
  calkit/__main__.py,sha256=whqS7I7q_c9004emvKptZ9B9OVn-jgr5kaLaCFKmwa0,112
3
3
  calkit/calc.py,sha256=drtxAZS8lWGKoB3Re29_IVsZNZu7gObuQd3ufFIgqYo,8096
4
- calkit/conda.py,sha256=ToRoQgpGfZmkSdQPXzn5mmUiGaMkjuq9NJakyjcYq0w,49924
4
+ calkit/conda.py,sha256=9zauxFAXhLef5q-S0RgKATTa0IFkYjC3Nji3RhHpRIw,49924
5
5
  calkit/conditions.py,sha256=eaAkq5h2mbE3SRK4mDi_hMax7MnlRXAfl7s9-UPsCpo,9214
6
6
  calkit/config.py,sha256=Fx-uSsCrQgxiiS0P219D94uJ0A2bgXCLLjCbKhJLC-U,20996
7
7
  calkit/core.py,sha256=fe56ZUQj6SFXc8VzBSRx3Ypn1T2m8Iov82wdTczXo_M,65541
@@ -9,7 +9,7 @@ calkit/datasets.py,sha256=3YtDmvBCzyX5AC-7Mb7ylnxM1mFLyTLj5CH7QqblDwA,2212
9
9
  calkit/detect.py,sha256=qEdYOrXMVCUYRoQ7YBQZBn_YZQT3K2GeWSOnWceGpNA,88418
10
10
  calkit/docker.py,sha256=i4OqBILrEPUPTmWlMKcB-7vvLZ9lFxBtoqnuCOZcqpU,54825
11
11
  calkit/docx.py,sha256=kh9eHBmKBJjH5kYefKg5DyfraDkeLUpdeBFBXwRozoM,55475
12
- calkit/environments.py,sha256=ITVA8qCfLyM5Ccb7p6XT-5MaEWsHI8mbg8NptYX_bU4,146446
12
+ calkit/environments.py,sha256=qXRm6jCL_cEOHd7t6eTnjHrOGkrDmKWehecKYeDo628,146756
13
13
  calkit/fs.py,sha256=7huOJIDPni4bTJ3MZyyifgE4NqbfbT_bPW8Uff-7JMU,45658
14
14
  calkit/git.py,sha256=NgUIcpdwWxiHmKrbRGybg10JTRoc-Fr-xzn61vDBiRw,30216
15
15
  calkit/github.py,sha256=nBR3CH3mFIDk_atWtZ_EdQEP3ktDi-xNPbe6Bbusarg,1699
@@ -40,7 +40,7 @@ calkit/server.py,sha256=GQm1bI5Q1NLFNwQL-iP6j4iWKUpKpP3cLEyfj5IMwe4,22009
40
40
  calkit/upgrade.py,sha256=leUZmUUU8dUAJblTmDBIb6aODmrEzIO2S_uF-aAqEzE,15844
41
41
  calkit/workspace.py,sha256=-DlOfzAOg175FBuwOxwO9GAXsDygbfZW_CVFbgljU1w,76264
42
42
  calkit/cli/__init__.py,sha256=a6cvqTR1QJpZWloNHDrmWP-X-rRKe5Z0pqCqWtbik0k,4139
43
- calkit/cli/check.py,sha256=nTeTQ10FZ0njEpAecv06bLKLRwBnmcVef4ztuu37M5w,98097
43
+ calkit/cli/check.py,sha256=wI4Jx9sg7hEkQ3JveNrRontqXyMPSG65g7JIQdYtAx0,98087
44
44
  calkit/cli/config.py,sha256=WGve-2OZ4hEv5Z6wpZi536fZyvRMeMv_ZcZGSmmqEDQ,15307
45
45
  calkit/cli/core.py,sha256=xracagL9n55c1PjlgWDtL81n1GnnPzeh0f3C25eralk,5698
46
46
  calkit/cli/delete.py,sha256=upkQ1P5bghtNc1F71XfOKXo6fbtQfhNXzdpKtcajCIo,1668
@@ -110,7 +110,7 @@ calkit/tests/test_detect.py,sha256=rNi_W5ck4_TZo2_tXfIfTc-U_GxOePdz_jJjaqnewlA,4
110
110
  calkit/tests/test_docker.py,sha256=rjGUFCw0zvNMgGqnOo1X9orAOR4x2Pv7yxz2CmhLc9I,23994
111
111
  calkit/tests/test_docs_references.py,sha256=n9XZMniIH1XvlUxdlFcLeQuNBwJsDydyVYZOeAh2XrA,5264
112
112
  calkit/tests/test_docx.py,sha256=mT2zfx0ysJfpNx746nYD6LDg2jutUhBXYz0uzFlPvdk,32303
113
- calkit/tests/test_environments.py,sha256=1WL6e2XRv96o4xGwp-yDN7qndNytdDWjoH9oEsoADkE,99426
113
+ calkit/tests/test_environments.py,sha256=wcJqH_JQTQAiJ4ZwhxBJd-DP2zVJSPG5aVEAAhkpSBM,100001
114
114
  calkit/tests/test_fs.py,sha256=vBbzZlikzwAQkPwn8_-wdsD-l1R4YTH7g-ghGfWrtzE,13785
115
115
  calkit/tests/test_git.py,sha256=gf3V6JfZfFf1ZcwjFu-BF_bgF4eMA83GwkAr1iqgxN0,27081
116
116
  calkit/tests/test_hub.py,sha256=H7We9KFZnW2Y5SqKVRqQCOksCjZHDoFc_IFJmiXDANQ,17824
@@ -176,21 +176,21 @@ calkit/agent_skills/check-questions/SKILL.md,sha256=yn6geOQUNQnJbM_Bn9grULerzreG
176
176
  calkit/agent_skills/check-reproducibility/SKILL.md,sha256=5SGmtnbq8bSJW0Zwav_aVzfuhilHwBkkdxGuZvPHxGU,4699
177
177
  calkit/agent_skills/conventions/SKILL.md,sha256=W9ayIG76Q8BTBgIRhpZz52dCKDLsSVj8_7O3LPeffU4,10323
178
178
  calkit/agent_skills/create-pipeline/SKILL.md,sha256=2FGw1iDQVRk5FUq79GP3lPdgvgof2Wi1O9O-abGGtgs,5422
179
- calkit_python-0.49.1.data/data/etc/jupyter/jupyter_server_config.d/calkit.json,sha256=CWrZP--JDGz8fsvbAlKr_duTL1vDriGT48SL1YCtkY0,81
180
- calkit_python-0.49.1.data/data/share/jupyter/labextensions/calkit/package.json,sha256=0hnHqhCly59Wg7urFGahc2mSupCWwiPfwKWCYfnbB2E,6202
181
- calkit_python-0.49.1.data/data/share/jupyter/labextensions/calkit/schemas/calkit/package.json.orig,sha256=egkbkHmJYzDARH3_4qpoF75_Svpj_dfPaIwRU-PNjW4,6064
182
- calkit_python-0.49.1.data/data/share/jupyter/labextensions/calkit/schemas/calkit/plugin.json,sha256=YSpIrwpwB-lQBk9Mwv-npedWTOOZreO6nlWZhqlWyGI,840
183
- calkit_python-0.49.1.data/data/share/jupyter/labextensions/calkit/static/506.c34b070098184e33.js,sha256=0PxdmgdZvLeh6RBcfgN1pcriNO8oCeTK5WJvUIEA3MY,112384
184
- calkit_python-0.49.1.data/data/share/jupyter/labextensions/calkit/static/57d13a7399cec3c5.png,sha256=svHD7-cMtTnRITFwugwsVaB9nZ-h8A61ose8z32HiRE,24850
185
- calkit_python-0.49.1.data/data/share/jupyter/labextensions/calkit/static/616.528427eb54a4a0c0.js,sha256=d0rHq7cqAjj1GNAMLOpl8dyY8yyKUQcLPCOUr-wJGdQ,8129
186
- calkit_python-0.49.1.data/data/share/jupyter/labextensions/calkit/static/740.6bf87276e9e5788a.js,sha256=4E0sK8x-ldVkL-1sM07wgJGS1vtVD9Uly7VtoFTi23c,221
187
- calkit_python-0.49.1.data/data/share/jupyter/labextensions/calkit/static/899.f9b9f9bf705a6493.js,sha256=RNTIItG9k-A_Ip54fRR3QMCjiffkY0bo8zQ2Xh7TyOY,57096
188
- calkit_python-0.49.1.data/data/share/jupyter/labextensions/calkit/static/935.46ecc6bf99aa593a.js,sha256=Cmp0KWM5YDZ-zcsJWWgqCMIF6adeHQH80rxz1sas45E,51183
189
- calkit_python-0.49.1.data/data/share/jupyter/labextensions/calkit/static/remoteEntry.109a3a8379365e59.js,sha256=4JavPLcn703qVSC2E1_MD1thrJNL4N-eITjnfNhSDSM,15066
190
- calkit_python-0.49.1.data/data/share/jupyter/labextensions/calkit/static/style.js,sha256=LTlA3M58hwjqmhomdcrNRO9GM58zZcf0V76WX9HI6EQ,146
191
- calkit_python-0.49.1.data/data/share/jupyter/labextensions/calkit/static/third-party-licenses.json,sha256=2BGdItLJwO3fAopLl4eJvp26TEwuscYC0-yFaF-LaLU,13683
192
- calkit_python-0.49.1.dist-info/METADATA,sha256=Q5SDce0Wf_w48juxxkVRLzPG2PRSR37azzsSWStPl1Y,22473
193
- calkit_python-0.49.1.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
194
- calkit_python-0.49.1.dist-info/entry_points.txt,sha256=TtpHpcv2vFVAVYxFVp0XrwCV_z7FWIOguEiypXRDoOw,131
195
- calkit_python-0.49.1.dist-info/licenses/LICENSE,sha256=9ZamCaSUTZk9rcrnf-sWFKLOHr3ws-S_dgKMegW4nw8,1056
196
- calkit_python-0.49.1.dist-info/RECORD,,
179
+ calkit_python-0.49.2.data/data/etc/jupyter/jupyter_server_config.d/calkit.json,sha256=CWrZP--JDGz8fsvbAlKr_duTL1vDriGT48SL1YCtkY0,81
180
+ calkit_python-0.49.2.data/data/share/jupyter/labextensions/calkit/package.json,sha256=0hnHqhCly59Wg7urFGahc2mSupCWwiPfwKWCYfnbB2E,6202
181
+ calkit_python-0.49.2.data/data/share/jupyter/labextensions/calkit/schemas/calkit/package.json.orig,sha256=egkbkHmJYzDARH3_4qpoF75_Svpj_dfPaIwRU-PNjW4,6064
182
+ calkit_python-0.49.2.data/data/share/jupyter/labextensions/calkit/schemas/calkit/plugin.json,sha256=YSpIrwpwB-lQBk9Mwv-npedWTOOZreO6nlWZhqlWyGI,840
183
+ calkit_python-0.49.2.data/data/share/jupyter/labextensions/calkit/static/506.c34b070098184e33.js,sha256=0PxdmgdZvLeh6RBcfgN1pcriNO8oCeTK5WJvUIEA3MY,112384
184
+ calkit_python-0.49.2.data/data/share/jupyter/labextensions/calkit/static/57d13a7399cec3c5.png,sha256=svHD7-cMtTnRITFwugwsVaB9nZ-h8A61ose8z32HiRE,24850
185
+ calkit_python-0.49.2.data/data/share/jupyter/labextensions/calkit/static/616.528427eb54a4a0c0.js,sha256=d0rHq7cqAjj1GNAMLOpl8dyY8yyKUQcLPCOUr-wJGdQ,8129
186
+ calkit_python-0.49.2.data/data/share/jupyter/labextensions/calkit/static/740.6bf87276e9e5788a.js,sha256=4E0sK8x-ldVkL-1sM07wgJGS1vtVD9Uly7VtoFTi23c,221
187
+ calkit_python-0.49.2.data/data/share/jupyter/labextensions/calkit/static/899.f9b9f9bf705a6493.js,sha256=RNTIItG9k-A_Ip54fRR3QMCjiffkY0bo8zQ2Xh7TyOY,57096
188
+ calkit_python-0.49.2.data/data/share/jupyter/labextensions/calkit/static/935.46ecc6bf99aa593a.js,sha256=Cmp0KWM5YDZ-zcsJWWgqCMIF6adeHQH80rxz1sas45E,51183
189
+ calkit_python-0.49.2.data/data/share/jupyter/labextensions/calkit/static/remoteEntry.109a3a8379365e59.js,sha256=4JavPLcn703qVSC2E1_MD1thrJNL4N-eITjnfNhSDSM,15066
190
+ calkit_python-0.49.2.data/data/share/jupyter/labextensions/calkit/static/style.js,sha256=LTlA3M58hwjqmhomdcrNRO9GM58zZcf0V76WX9HI6EQ,146
191
+ calkit_python-0.49.2.data/data/share/jupyter/labextensions/calkit/static/third-party-licenses.json,sha256=2BGdItLJwO3fAopLl4eJvp26TEwuscYC0-yFaF-LaLU,13683
192
+ calkit_python-0.49.2.dist-info/METADATA,sha256=PIzOMSpvNfpXR4kIV4dTKLDBW9B-cZSIEvIknKfdiWE,22473
193
+ calkit_python-0.49.2.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
194
+ calkit_python-0.49.2.dist-info/entry_points.txt,sha256=TtpHpcv2vFVAVYxFVp0XrwCV_z7FWIOguEiypXRDoOw,131
195
+ calkit_python-0.49.2.dist-info/licenses/LICENSE,sha256=9ZamCaSUTZk9rcrnf-sWFKLOHr3ws-S_dgKMegW4nw8,1056
196
+ calkit_python-0.49.2.dist-info/RECORD,,