code-sandboxes 1.9.17__tar.gz → 1.9.18__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 (263) hide show
  1. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/CHANGELOG.md +17 -0
  2. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/PKG-INFO +1 -1
  3. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/__version__.py +1 -1
  4. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/resolve.py +10 -8
  5. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/resolve_conda.py +22 -23
  6. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_environment_resolve.py +10 -4
  7. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_environment_resolve_conda.py +9 -15
  8. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/.github/workflows/build.yml +0 -0
  9. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/.github/workflows/environments-live.yml +0 -0
  10. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/.github/workflows/py-code-style.yml +0 -0
  11. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/.github/workflows/py-tests.yml +0 -0
  12. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/.github/workflows/py-typing.yml +0 -0
  13. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/.github/workflows/reusable-python.yml +0 -0
  14. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/.gitignore +0 -0
  15. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/.licenserc.yaml +0 -0
  16. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/.pre-commit-config.yaml +0 -0
  17. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/.vscode/settings.json +0 -0
  18. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/Dockerfile +0 -0
  19. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/LICENSE +0 -0
  20. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/Makefile +0 -0
  21. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/README.md +0 -0
  22. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/__init__.py +0 -0
  23. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/base.py +0 -0
  24. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/bridge_mount.py +0 -0
  25. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/builds.py +0 -0
  26. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/cli.py +0 -0
  27. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/client.py +0 -0
  28. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/cloudflare_sandbox.py +0 -0
  29. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/commands.py +0 -0
  30. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/console.py +0 -0
  31. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/contents.py +0 -0
  32. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/coreweave_sandbox.py +0 -0
  33. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/datalayer_sandbox.py +0 -0
  34. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/daytona_sandbox.py +0 -0
  35. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/docker_sandbox.py +0 -0
  36. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/e2b_sandbox.py +0 -0
  37. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/__init__.py +0 -0
  38. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/__main__.py +0 -0
  39. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/accounts.py +0 -0
  40. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/adapters/__init__.py +0 -0
  41. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/adapters/datalayer.py +0 -0
  42. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/adapters/daytona.py +0 -0
  43. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/adapters/e2b.py +0 -0
  44. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/adapters/managed.py +0 -0
  45. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/adapters/modal.py +0 -0
  46. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/attest.py +0 -0
  47. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/bases.py +0 -0
  48. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/breaker.py +0 -0
  49. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/build_secrets.py +0 -0
  50. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/builders.py +0 -0
  51. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/canonical.py +0 -0
  52. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/conformance.py +0 -0
  53. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/constraints/sandbox-contract-v1.txt +0 -0
  54. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/constraints/wheelhouse/README.md +0 -0
  55. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/constraints/wheelhouse/jupyter_server-2.21.0+datalayer.1-py3-none-any.whl +0 -0
  56. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/contract.py +0 -0
  57. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/doctor/__init__.py +0 -0
  58. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/doctor/build.py +0 -0
  59. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/doctor/datalayer_sandbox.py +0 -0
  60. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/doctor/report.schema.json +0 -0
  61. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/errors.py +0 -0
  62. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/files.py +0 -0
  63. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/image_import.py +0 -0
  64. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/lifecycle.py +0 -0
  65. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/policy.py +0 -0
  66. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/redact.py +0 -0
  67. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/schema.py +0 -0
  68. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/environments/spec.py +0 -0
  69. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/eval_sandbox.py +0 -0
  70. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/exceptions.py +0 -0
  71. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/filesystem.py +0 -0
  72. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/google_colab.py +0 -0
  73. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/google_colab_sandbox.py +0 -0
  74. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/interfaces.py +0 -0
  75. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/jupyter_ingress.py +0 -0
  76. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/jupyter_server_sandbox.py +0 -0
  77. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/kaggle.py +0 -0
  78. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/kaggle_execute.py +0 -0
  79. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/kaggle_live.py +0 -0
  80. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/kaggle_sandbox.py +0 -0
  81. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/lifecycle.py +0 -0
  82. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/manage.py +0 -0
  83. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/modal_sandbox.py +0 -0
  84. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/models.py +0 -0
  85. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/monty_sandbox.py +0 -0
  86. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/provider_ingress.py +0 -0
  87. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/code_sandboxes/providers.py +0 -0
  88. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docker/Dockerfile +0 -0
  89. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/.gitignore +0 -0
  90. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/LICENSE +0 -0
  91. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/Makefile +0 -0
  92. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/README.md +0 -0
  93. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/babel.config.js +0 -0
  94. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/api-reference/_category_.yml +0 -0
  95. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/api-reference/index.mdx +0 -0
  96. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/cli/_category_.yml +0 -0
  97. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/cli/index.mdx +0 -0
  98. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/contribute/_category_.yml +0 -0
  99. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/contribute/index.mdx +0 -0
  100. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/environments/_category_.yml +0 -0
  101. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/environments/contract.mdx +0 -0
  102. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/environments/index.mdx +0 -0
  103. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/environments/specification.mdx +0 -0
  104. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/environments/spike-2026-09.mdx +0 -0
  105. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/examples/_category_.yml +0 -0
  106. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/examples/index.mdx +0 -0
  107. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/guide/_category_.yml +0 -0
  108. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/guide/index.mdx +0 -0
  109. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/index.mdx +0 -0
  110. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/install/_category_.yml +0 -0
  111. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/install/index.mdx +0 -0
  112. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/provider-ingress.mdx +0 -0
  113. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/providers/_category_.yml +0 -0
  114. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/providers/cloudflare.mdx +0 -0
  115. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/providers/coreweave.mdx +0 -0
  116. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/providers/datalayer.mdx +0 -0
  117. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/providers/daytona.mdx +0 -0
  118. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/providers/docker.mdx +0 -0
  119. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/providers/e2b.mdx +0 -0
  120. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/providers/eval.mdx +0 -0
  121. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/providers/google-colab.mdx +0 -0
  122. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/providers/index.mdx +0 -0
  123. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/providers/jupyter-server.mdx +0 -0
  124. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/providers/kaggle.mdx +0 -0
  125. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/providers/modal.mdx +0 -0
  126. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docs/providers/monty.mdx +0 -0
  127. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/docusaurus.config.js +0 -0
  128. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/package.json +0 -0
  129. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/sidebars.js +0 -0
  130. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/src/components/HomepageRow1.js +0 -0
  131. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/src/components/HomepageRow1.module.css +0 -0
  132. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/src/components/HomepageRow2.js +0 -0
  133. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/src/components/HomepageRow2.module.css +0 -0
  134. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/src/components/HomepageRow3.js +0 -0
  135. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/src/components/HomepageRow3.module.css +0 -0
  136. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/src/css/custom.css +0 -0
  137. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/src/pages/index.module.css +0 -0
  138. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/src/pages/markdown-page.md +0 -0
  139. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/src/theme/CustomDocItem.tsx +0 -0
  140. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/src/theme/IconsTitle.tsx +0 -0
  141. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/static/img/bricks.svg +0 -0
  142. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/static/img/building-construction.svg +0 -0
  143. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/static/img/cloud-sun.svg +0 -0
  144. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/static/img/cloud.svg +0 -0
  145. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/static/img/collaboration.svg +0 -0
  146. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/static/img/copy-left.svg +0 -0
  147. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/static/img/datalayer/logo.png +0 -0
  148. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/static/img/datalayer/logo.svg +0 -0
  149. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/static/img/datalayer/personas/business.svg +0 -0
  150. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/static/img/datalayer/personas/data-scientist.svg +0 -0
  151. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/static/img/datalayer/personas/devops.svg +0 -0
  152. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/static/img/datalayer/project/project-line.svg +0 -0
  153. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/static/img/favicon.ico +0 -0
  154. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/static/img/jupyter.svg +0 -0
  155. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/static/img/open-source.svg +0 -0
  156. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/static/img/react-js.svg +0 -0
  157. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/static/img/react-js2.svg +0 -0
  158. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/static/img/ringed-planet.svg +0 -0
  159. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/static/img/robot.svg +0 -0
  160. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/static/img/rocket.svg +0 -0
  161. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/static/img/shield.svg +0 -0
  162. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/static/img/sparkles.svg +0 -0
  163. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/static/img/streamlit.gif +0 -0
  164. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/static/img/super-hero.svg +0 -0
  165. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/static/img/target.svg +0 -0
  166. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/docs/static/img/thumbs-up.svg +0 -0
  167. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/examples/README.md +0 -0
  168. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/examples/exec/Makefile +0 -0
  169. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/examples/exec/cloudflare_sandbox_example.py +0 -0
  170. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/examples/exec/coreweave_sandbox_example.py +0 -0
  171. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/examples/exec/datalayer_sandbox_example.py +0 -0
  172. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/examples/exec/daytona_sandbox_example.py +0 -0
  173. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/examples/exec/docker_sandbox_example.py +0 -0
  174. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/examples/exec/e2b_sandbox_example.py +0 -0
  175. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/examples/exec/eval_sandbox_example.py +0 -0
  176. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/examples/exec/google_colab_sandbox_example.py +0 -0
  177. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/examples/exec/jupyter_server_sandbox_example.py +0 -0
  178. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/examples/exec/kaggle_sandbox_example.py +0 -0
  179. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/examples/exec/modal_sandbox_example.py +0 -0
  180. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/examples/exec/monty_sandbox_example.py +0 -0
  181. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/examples/repl/Makefile +0 -0
  182. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/examples/repl/cloudflare_sandbox_example.py +0 -0
  183. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/examples/repl/coreweave_sandbox_example.py +0 -0
  184. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/examples/repl/datalayer_sandbox_example.py +0 -0
  185. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/examples/repl/daytona_sandbox_example.py +0 -0
  186. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/examples/repl/docker_sandbox_example.py +0 -0
  187. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/examples/repl/e2b_sandbox_example.py +0 -0
  188. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/examples/repl/eval_sandbox_example.py +0 -0
  189. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/examples/repl/google_colab_sandbox_example.py +0 -0
  190. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/examples/repl/jupyter_server_sandbox_example.py +0 -0
  191. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/examples/repl/kaggle_sandbox_example.py +0 -0
  192. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/examples/repl/modal_sandbox_example.py +0 -0
  193. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/examples/repl/monty_sandbox_example.py +0 -0
  194. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/pyproject.toml +0 -0
  195. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/schemas/environment-v1alpha1.json +0 -0
  196. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/__init__.py +0 -0
  197. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/conftest.py +0 -0
  198. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_a_datalayer_sandbox_can_be_interrupted.py +0 -0
  199. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_bridge_mount.py +0 -0
  200. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_builds.py +0 -0
  201. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_cli_exec.py +0 -0
  202. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_cli_repl.py +0 -0
  203. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_client.py +0 -0
  204. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_client_contents.py +0 -0
  205. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_client_files.py +0 -0
  206. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_client_outcome_error_output.py +0 -0
  207. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_cloudflare.py +0 -0
  208. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_commands_envelope.py +0 -0
  209. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_console.py +0 -0
  210. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_contents_contract.py +0 -0
  211. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_contents_live_matrix.py +0 -0
  212. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_coreweave.py +0 -0
  213. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_datalayer_sandbox.py +0 -0
  214. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_daytona.py +0 -0
  215. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_e2b.py +0 -0
  216. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_environment_accounts.py +0 -0
  217. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_environment_attest.py +0 -0
  218. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_environment_bases.py +0 -0
  219. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_environment_breaker.py +0 -0
  220. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_environment_build_secrets.py +0 -0
  221. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_environment_builders.py +0 -0
  222. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_environment_canonical.py +0 -0
  223. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_environment_conformance.py +0 -0
  224. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_environment_constraints.py +0 -0
  225. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_environment_contract.py +0 -0
  226. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_environment_cross_variant_report.py +0 -0
  227. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_environment_datalayer_builder.py +0 -0
  228. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_environment_daytona_builder.py +0 -0
  229. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_environment_doctor.py +0 -0
  230. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_environment_e2b_builder.py +0 -0
  231. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_environment_errors.py +0 -0
  232. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_environment_image_import.py +0 -0
  233. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_environment_lifecycle.py +0 -0
  234. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_environment_live_matrix.py +0 -0
  235. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_environment_managed_builders.py +0 -0
  236. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_environment_modal_builder.py +0 -0
  237. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_environment_redact.py +0 -0
  238. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_environment_spec.py +0 -0
  239. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_eval.py +0 -0
  240. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_every_variant_has_a_real_interrupt.py +0 -0
  241. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_factory.py +0 -0
  242. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_google_colab.py +0 -0
  243. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_integration.py +0 -0
  244. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_jupyter_ingress.py +0 -0
  245. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_jupyter_server.py +0 -0
  246. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_jupyter_server_streaming.py +0 -0
  247. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_kaggle.py +0 -0
  248. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_kaggle_execute.py +0 -0
  249. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_kaggle_live.py +0 -0
  250. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_kaggle_session.py +0 -0
  251. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_kernel_client_compatibility.py +0 -0
  252. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_lifecycle_vocabulary.py +0 -0
  253. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_manage.py +0 -0
  254. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_manage_datalayer.py +0 -0
  255. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_modal_google_colab_sandbox.py +0 -0
  256. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_modal_session.py +0 -0
  257. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_models.py +0 -0
  258. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_output_line_fidelity.py +0 -0
  259. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_provider_catalog_names.py +0 -0
  260. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_provider_ingress.py +0 -0
  261. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_providers.py +0 -0
  262. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_sandboxes.py +0 -0
  263. {code_sandboxes-1.9.17 → code_sandboxes-1.9.18}/tests/test_the_kill_relaunch_drill.py +0 -0
@@ -8,6 +8,23 @@
8
8
 
9
9
  ## Unreleased
10
10
 
11
+ ## 1.9.18
12
+
13
+ - **A lock no longer carries a wall clock, so the build cache can hit**
14
+ (`environments/resolve.py`, `resolve_conda.py`; PLAN_ENVS.md E1-26, D-12).
15
+ The lock's header carried a `# resolved-at:` line, and its digest is over
16
+ the whole text — so two resolves of the same spec, in the same base,
17
+ pinning the same 320 packages, produced two different digests. Found by
18
+ resolving one environment twice on r1 on 2026-09-16: the texts differed in
19
+ exactly that one line out of 5,388. Section 5's cache key is over the lock
20
+ digest, so D-12's build cache could never hit, and it never had:
21
+ `environments.cache.lookups` read `hit=false` twelve times out of twelve.
22
+ When a lock was resolved is on the lock document Runtimes stores, in its
23
+ `created_at`, which is where it belongs. `resolved_at` is gone from
24
+ `lock_document`, `conda_lock_document`, `resolve_environment` and
25
+ `resolve_conda_environment`; the two tests that asserted determinism by
26
+ freezing the clock now assert it without one.
27
+
11
28
  ## 1.9.17
12
29
 
13
30
  - **An artifact's size is read from the registry** (`environments/attest.py`;
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: code_sandboxes
3
- Version: 1.9.17
3
+ Version: 1.9.18
4
4
  Project-URL: Home, https://github.com/datalayer/code-sandboxes
5
5
  Author-email: Datalayer <info@datalayer.io>
6
6
  License: BSD 3-Clause License
@@ -3,4 +3,4 @@
3
3
 
4
4
  """Code Sandboxes."""
5
5
 
6
- __version__ = "1.9.17"
6
+ __version__ = "1.9.18"
@@ -889,7 +889,6 @@ def lock_document(
889
889
  python_version: str,
890
890
  base_reference: str,
891
891
  merged: MergedRequirements,
892
- resolved_at: datetime | None = None,
893
892
  ) -> dict[str, Any]:
894
893
  """The stored lock: its text, its digest, and what a reader needs from it.
895
894
 
@@ -897,11 +896,19 @@ def lock_document(
897
896
  output, so the document is still a requirements file — ``pip install -r``
898
897
  reads it, and so does every tool that only knows that format — while
899
898
  saying everything the build installs.
899
+
900
+ **Nothing here is a wall clock.** The header carried a ``# resolved-at:``
901
+ line until 2026-09-16, and since the digest is over the whole text, two
902
+ resolves of the same spec, in the same base, pinning the same 320 packages
903
+ produced two different digests — the texts differed in that one line out
904
+ of 5,388, found by resolving the same environment twice on r1. The cache
905
+ key of section 5 is over the lock digest, so D-12's build cache could
906
+ never hit: `environments.cache.lookups` read `hit=false` 12 times out of
907
+ 12. When the lock was resolved is on the lock document Runtimes stores, in
908
+ its ``created_at``, where it belongs.
900
909
  """
901
- when = (resolved_at or _utcnow()).replace(microsecond=0).isoformat()
902
910
  header = [
903
911
  "# Resolved by Datalayer (PLAN_ENV.md D-9). Do not edit: a change makes a new version.",
904
- f"# resolved-at: {when}",
905
912
  f"# python: {python_version}",
906
913
  f"# base: {base_reference}",
907
914
  ]
@@ -1163,7 +1170,6 @@ def resolve_environment(
1163
1170
  runner: ResolveRunner | None = None,
1164
1171
  conda_runner: CondaResolveRunner | None = None,
1165
1172
  bases: dict[str, ApprovedBase] = APPROVED_BASES,
1166
- resolved_at: datetime | None = None,
1167
1173
  uv: str | None = None,
1168
1174
  pyproject_run: Callable[..., subprocess.CompletedProcess[str]] | None = None,
1169
1175
  image_transport: Any = None,
@@ -1198,8 +1204,6 @@ def resolve_environment(
1198
1204
  bases
1199
1205
  The approved bases, injected by tests and by a plane whose channel is
1200
1206
  published somewhere else.
1201
- resolved_at
1202
- The moment the lock records. Now by default.
1203
1207
  uv, pyproject_run
1204
1208
  A `pyproject` `dependencyFile` source's own verification (E3-01):
1205
1209
  the `uv` to check and export with, and how it is run — injected by
@@ -1274,7 +1278,6 @@ def resolve_environment(
1274
1278
  credential=credential,
1275
1279
  log=say,
1276
1280
  runner=conda_runner,
1277
- resolved_at=resolved_at,
1278
1281
  )
1279
1282
  if dependency_file.source_format == "pyproject":
1280
1283
  # Verified, not re-resolved (E3-01): the author's own uv.lock is
@@ -1321,7 +1324,6 @@ def resolve_environment(
1321
1324
  python_version=environment.spec.language.version,
1322
1325
  base_reference=solving_in,
1323
1326
  merged=merged,
1324
- resolved_at=resolved_at,
1325
1327
  )
1326
1328
  say(
1327
1329
  f"Locked {document['package_count']} packages"
@@ -644,24 +644,28 @@ class BuildkitCondaResolveRunner:
644
644
  carries the whole of what the solve resolved, not the conda layer alone.
645
645
  """
646
646
  micromamba = shlex.quote(MICROMAMBA_BINARY)
647
- return "\n".join(
648
- [
649
- f"FROM {request.base_reference} AS solve",
650
- "USER root",
651
- "WORKDIR /solve",
652
- micromamba_bootstrap_dockerfile_line(),
653
- "COPY environment.yml ./environment.yml",
654
- "ENV PIP_FIND_LINKS=" + shlex.quote(WHEELHOUSE_IMAGE_PATH),
655
- "RUN --mount=type=cache,target=/opt/conda/pkgs "
656
- f"{micromamba} create --yes --prefix /solve/prefix "
657
- f"--platform {shlex.quote(request.platform)} --file environment.yml",
658
- f"RUN {micromamba} env export --explicit --prefix /solve/prefix > /solve/lock.txt",
659
- f"RUN {micromamba} env export --prefix /solve/prefix > /solve/pip-env.yml",
660
- "FROM scratch",
661
- "COPY --from=solve /solve/lock.txt /lock.txt",
662
- "COPY --from=solve /solve/pip-env.yml /pip-env.yml",
663
- ]
664
- ) + "\n"
647
+ return (
648
+ "\n".join(
649
+ [
650
+ f"FROM {request.base_reference} AS solve",
651
+ "USER root",
652
+ "WORKDIR /solve",
653
+ micromamba_bootstrap_dockerfile_line(),
654
+ "COPY environment.yml ./environment.yml",
655
+ "ENV PIP_FIND_LINKS=" + shlex.quote(WHEELHOUSE_IMAGE_PATH),
656
+ "RUN --mount=type=cache,target=/opt/conda/pkgs "
657
+ f"{micromamba} create --yes --prefix /solve/prefix "
658
+ f"--platform {shlex.quote(request.platform)} --file environment.yml",
659
+ f"RUN {micromamba} env export --explicit "
660
+ "--prefix /solve/prefix > /solve/lock.txt",
661
+ f"RUN {micromamba} env export --prefix /solve/prefix > /solve/pip-env.yml",
662
+ "FROM scratch",
663
+ "COPY --from=solve /solve/lock.txt /lock.txt",
664
+ "COPY --from=solve /solve/pip-env.yml /pip-env.yml",
665
+ ]
666
+ )
667
+ + "\n"
668
+ )
665
669
 
666
670
  def solve(
667
671
  self, request: CondaResolveRequest, log: Callable[[str], None] | None = None
@@ -800,7 +804,6 @@ def conda_lock_document(
800
804
  base_reference: str,
801
805
  merged: MergedRequirements,
802
806
  platform: str = CONDA_PLATFORM,
803
- resolved_at: datetime | None = None,
804
807
  ) -> dict[str, Any]:
805
808
  """The stored conda lock: its text, its digest, and what a reader needs.
806
809
 
@@ -814,10 +817,8 @@ def conda_lock_document(
814
817
  could read the prefix back, and the merged requirements otherwise, so it is
815
818
  always complete rather than the protected pins alone.
816
819
  """
817
- when = (resolved_at or _utcnow()).replace(microsecond=0).isoformat()
818
820
  header = [
819
821
  "# Resolved by Datalayer (PLAN_ENV.md D-9). Do not edit: a change makes a new version.",
820
- f"# resolved-at: {when}",
821
822
  f"# python: {python_version}",
822
823
  f"# platform: {platform}",
823
824
  f"# base: {base_reference}",
@@ -854,7 +855,6 @@ def resolve_conda_environment(
854
855
  credential: Any = None,
855
856
  log: Callable[[str], None] | None = None,
856
857
  runner: CondaResolveRunner | None = None,
857
- resolved_at: datetime | None = None,
858
858
  ) -> dict[str, Any]:
859
859
  """A conda version's lock, from its ``environment.yml`` (E3-02).
860
860
 
@@ -892,7 +892,6 @@ def resolve_conda_environment(
892
892
  base_reference=solving_in,
893
893
  merged=merged,
894
894
  platform=platform,
895
- resolved_at=resolved_at,
896
895
  )
897
896
  say(f"Locked {document['package_count']} conda packages as {document['digest']}")
898
897
  return {**document, "resolved_bases": dict(resolved_bases)}
@@ -13,7 +13,6 @@ paraphrase of them that cannot go out of date.
13
13
  from __future__ import annotations
14
14
 
15
15
  import subprocess
16
- from datetime import datetime, timezone
17
16
 
18
17
  import httpx
19
18
  import pytest
@@ -266,7 +265,6 @@ class TestTheLock:
266
265
  python_version="3.13",
267
266
  base_reference="environments/base/python-cpu@sha256:" + "11" * 32,
268
267
  merged=merge_requirements(["geopandas==1.1.1"]),
269
- resolved_at=datetime(2026, 9, 12, 8, 30, tzinfo=timezone.utc),
270
268
  )
271
269
  assert document["format"] == LOCK_FORMAT
272
270
  assert document["digest"].startswith("sha256:")
@@ -275,7 +273,6 @@ class TestTheLock:
275
273
  content = document["content"]
276
274
  assert f"{APT_PIN_PREFIX}gdal-bin=3.8.4+dfsg-3build2" in content
277
275
  assert "# datalayer-protected: ipykernel==7.3.0" in content
278
- assert "# resolved-at: 2026-09-12T08:30:00+00:00" in content
279
276
  # The snapshot the pins came from, which the builder installs from.
280
277
  from code_sandboxes.environments.resolve import apt_pins_in, apt_snapshot_in
281
278
 
@@ -289,15 +286,24 @@ class TestTheLock:
289
286
  }
290
287
 
291
288
  def test_the_same_lock_digests_the_same_and_a_changed_one_does_not(self) -> None:
289
+ """And nothing here may pin a clock to make it true.
290
+
291
+ The header carried a `# resolved-at:` line until 2026-09-16, and this
292
+ test passed only because it froze the moment. Resolving the same spec
293
+ twice on r1 produced two digests differing in that one line out of
294
+ 5,388, and section 5's cache key is over the lock digest — so D-12's
295
+ build cache had never hit, 12 lookups out of 12.
296
+ """
292
297
  arguments = {
293
298
  "python_version": "3.13",
294
299
  "base_reference": "environments/base/python-cpu@sha256:" + "11" * 32,
295
300
  "merged": MergedRequirements((), (), ()),
296
- "resolved_at": datetime(2026, 9, 12, tzinfo=timezone.utc),
297
301
  }
298
302
  first = lock_document(A_LOCK, **arguments)
299
303
  again = lock_document(A_LOCK, **arguments)
300
304
  assert first["digest"] == again["digest"]
305
+ assert first["content"] == again["content"]
306
+ assert "resolved-at" not in first["content"]
301
307
  moved = lock_document(
302
308
  ResolveOutcome(lock_text=A_LOCK.lock_text.replace("1.1.1", "1.1.2")), **arguments
303
309
  )
@@ -12,7 +12,6 @@ tested against the solver's own words rather than a paraphrase of them.
12
12
  from __future__ import annotations
13
13
 
14
14
  import subprocess
15
- from datetime import datetime, timezone
16
15
 
17
16
  import pytest
18
17
 
@@ -192,8 +191,7 @@ class TestParsingTheEnvironmentYml:
192
191
 
193
192
  def test_a_plain_channel_url_without_a_credential_is_kept(self) -> None:
194
193
  env = parse_conda_environment(
195
- "channels:\n - https://conda.anaconda.org/conda-forge\n"
196
- "dependencies:\n - gdal\n"
194
+ "channels:\n - https://conda.anaconda.org/conda-forge\n" "dependencies:\n - gdal\n"
197
195
  )
198
196
  assert env.channels == ("https://conda.anaconda.org/conda-forge",)
199
197
 
@@ -235,17 +233,13 @@ class TestMergingThePipLayer:
235
233
  assert {"shapely", "ipykernel", "jupyter-server"} <= names
236
234
 
237
235
  def test_a_pip_requirement_contradicting_a_pin_is_refused(self) -> None:
238
- env = parse_conda_environment(
239
- "dependencies:\n - pip:\n - ipykernel==6.0.0\n"
240
- )
236
+ env = parse_conda_environment("dependencies:\n - pip:\n - ipykernel==6.0.0\n")
241
237
  with pytest.raises(EnvironmentsError) as caught:
242
238
  merge_conda_pip(env)
243
239
  assert caught.value.code.code == "DL_ENV_PROTECTED_PACKAGE"
244
240
 
245
241
  def test_the_interpreter_is_pinned_and_never_doubled(self) -> None:
246
- env = parse_conda_environment(
247
- "dependencies:\n - python=3.11\n - gdal=3.9\n"
248
- )
242
+ env = parse_conda_environment("dependencies:\n - python=3.11\n - gdal=3.9\n")
249
243
  merged = merge_conda_pip(env)
250
244
  rendered = rendered_environment(env, merged, python_version="3.13")
251
245
  assert rendered.count("python=3.13") == 1
@@ -291,13 +285,11 @@ class TestTheLock:
291
285
  def test_the_document_records_the_pins_and_is_deterministic(self) -> None:
292
286
  env = parse_conda_environment(A_YAML)
293
287
  merged = merge_conda_pip(env)
294
- at = datetime(2026, 9, 14, tzinfo=timezone.utc)
295
288
  document = conda_lock_document(
296
289
  CondaResolveOutcome(lock_text=EXPLICIT_LOCK),
297
290
  python_version="3.13",
298
291
  base_reference="registry/base@sha256:" + "11" * 32,
299
292
  merged=merged,
300
- resolved_at=at,
301
293
  )
302
294
  assert document["format"] == CONDA_LOCK_FORMAT
303
295
  assert document["package_count"] == 2
@@ -311,9 +303,13 @@ class TestTheLock:
311
303
  python_version="3.13",
312
304
  base_reference="registry/base@sha256:" + "11" * 32,
313
305
  merged=merged,
314
- resolved_at=at,
315
306
  )
307
+ # Deterministic without anybody pinning a clock: the header carried a
308
+ # `# resolved-at:` line until 2026-09-16, which made two resolves of
309
+ # one spec two different digests and kept D-12's cache from ever
310
+ # hitting.
316
311
  assert document["digest"] == again["digest"]
312
+ assert "resolved-at" not in document["content"]
317
313
 
318
314
  def test_an_export_without_the_marker_is_a_provider_error(self) -> None:
319
315
  env = parse_conda_environment(A_YAML)
@@ -353,9 +349,7 @@ class TestTheRunners:
353
349
  return subprocess.CompletedProcess(argv, 0, stdout="", stderr="")
354
350
  raise subprocess.TimeoutExpired(argv, 5.0)
355
351
 
356
- monkeypatch.setattr(
357
- "code_sandboxes.environments.resolve_conda.subprocess.run", fake_run
358
- )
352
+ monkeypatch.setattr("code_sandboxes.environments.resolve_conda.subprocess.run", fake_run)
359
353
  with pytest.raises(EnvironmentsError) as caught:
360
354
  runner.solve(CondaResolveRequest(environment_yml=A_YAML, python_version="3.13"))
361
355
  assert caught.value.code.code == "DL_ENV_PROVIDER_ERROR"
File without changes