lean-runtime 2.1.2__tar.gz → 2.2.0__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.
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/CHANGELOG.md +12 -0
- {lean_runtime-2.1.2/lean_runtime.egg-info → lean_runtime-2.2.0}/PKG-INFO +1 -1
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/environments.py +107 -110
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/runtime.py +41 -1
- {lean_runtime-2.1.2 → lean_runtime-2.2.0/lean_runtime.egg-info}/PKG-INFO +1 -1
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/pyproject.toml +1 -1
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/scripts/announcement_gate.py +5 -3
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/test_multifile.py +37 -1
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/test_runtime.py +60 -1
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/LICENSE +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/MANIFEST.in +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/README.md +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/catalog/environments.toml +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/catalog/locks/core-v4.32.2.lock.json +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/catalog/locks/mathlib-v4.30.0.lock.json +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/catalog/locks/mathlib-v4.31.0.lock.json +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/catalog/locks/mathlib-v4.32.2.lock.json +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/compatibility/README.md +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/compatibility/mathlib-4.32.2.json +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/compatibility/mathlib-4.32.2.toml +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/docs/architecture.md +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/docs/captures.md +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/docs/case-study-v1.md +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/docs/cli.md +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/docs/development.md +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/docs/environments.md +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/docs/getting-started.md +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/docs/index.md +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/docs/local-projects.md +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/docs/portable-copies.md +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/docs/python-api.md +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/docs/ready-programs.md +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/docs/standalone-files.md +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/docs/trust-and-limitations.md +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/docs/v1-precision.md +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/examples/mathlib.toml +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/__init__.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/__main__.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/_git.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/_paths.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/backends.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/bundles.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/cli.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/comparison.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/decisions.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/diagnostics.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/discovery/__init__.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/discovery/analyzer.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/discovery/api.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/discovery/candidate.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/discovery/catalog.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/discovery/catalog_build.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/discovery/catalog_cli.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/discovery/catalog_manifest.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/discovery/data/catalog.json +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/discovery/defaults.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/discovery/engine.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/discovery/errors.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/discovery/module_inventory.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/discovery/planner.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/discovery/policy.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/discovery/probe.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/discovery/py.typed +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/discovery/result.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/discovery/schema_resources.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/discovery/schemas/catalog-v1.schema.json +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/discovery/schemas/plan-v1.schema.json +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/discovery/schemas/result-v1.schema.json +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/errors.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/events.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/facade.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/frontmatter.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/health.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/lake.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/lockfiles.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/locking.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/matrix.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/models.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/oci.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/policies.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/profiling.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/programs.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/projects.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/publisher_verification.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/py.typed +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/references.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/resolver.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/run_cli.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/schema_resources.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/serialization.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/specs.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/store.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/timings.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/toolchain_slim.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/toolchains.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/verification.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/wire.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime.egg-info/SOURCES.txt +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime.egg-info/dependency_links.txt +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime.egg-info/entry_points.txt +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime.egg-info/requires.txt +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime.egg-info/top_level.txt +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/mkdocs.yml +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/schemas/cleanup-v1.schema.json +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/schemas/comparison-v1.schema.json +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/schemas/execution-v1.schema.json +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/schemas/inspect-v1.schema.json +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/schemas/matrix-v1.schema.json +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/schemas/profile-v1.schema.json +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/schemas/verify-v1.schema.json +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/scripts/registry_preflight.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/scripts/run_compatibility.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/scripts/run_v1_case_study.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/scripts/smoke_wheel.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/setup.cfg +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/conftest.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/discovery/e2e/test_real_discovery.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/discovery/test_analyzer.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/discovery/test_catalog.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/discovery/test_catalog_build.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/discovery/test_discovery_schema_resources.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/discovery/test_engine.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/discovery/test_planner.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/discovery/test_policy.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/test_backend.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/test_bundles.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/test_cli.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/test_diagnostics.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/test_environment_integration.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/test_events_health.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/test_facade.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/test_frontmatter.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/test_git.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/test_interactive.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/test_lockfiles.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/test_models.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/test_paths.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/test_prebuilt_policy.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/test_programs.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/test_projects.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/test_references.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/test_run_cli.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/test_schema_resources.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/test_schemas.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/test_signatures.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/test_specs.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/test_store.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/test_toolchain_slim.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/test_toolchains.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/test_v1_precision.py +0 -0
- {lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/test_verification_inventory.py +0 -0
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.2.0 - 2026-08-12
|
|
4
|
+
|
|
5
|
+
- Make published-environment checks invoke Lean directly with the immutable
|
|
6
|
+
compiled module roots instead of cloning the multi-gigabyte workspace and
|
|
7
|
+
asking Lake to rescan its full build graph on every proof. Multi-file checks
|
|
8
|
+
compile support modules into the disposable scratch tree; build and execute
|
|
9
|
+
operations keep their existing isolated workspace clones.
|
|
10
|
+
- Resolve exact bundled references such as `mathlib@v4.32.2` to the catalog's
|
|
11
|
+
downloadable lock before Git/Lake resolution. The Python setup API,
|
|
12
|
+
`lean-run --with`, frontmatter, and `--lock-out` now share the same lock and
|
|
13
|
+
reuse the same environment rather than creating a duplicate cache entry.
|
|
14
|
+
|
|
3
15
|
## 2.1.2 - 2026-08-12
|
|
4
16
|
|
|
5
17
|
- Raise `lean-run`'s default `--check-timeout` from 120 to 300 seconds: a
|
|
@@ -147,6 +147,32 @@ def _package_import_targets(files: Mapping[str, str], lock: EnvironmentLock) ->
|
|
|
147
147
|
return tuple(sorted(targets))
|
|
148
148
|
|
|
149
149
|
|
|
150
|
+
def _check_lean_paths(workspace: Path, scratch: Path, lock: EnvironmentLock) -> tuple[Path, ...]:
|
|
151
|
+
"""Return the compiled module roots for a check without asking Lake to scan them."""
|
|
152
|
+
roots = [scratch / ".lake" / "build" / "lib" / "lean"]
|
|
153
|
+
workspace_root = workspace / ".lake" / "build" / "lib" / "lean"
|
|
154
|
+
|
|
155
|
+
raw_packages_dir = lock.manifest.get("packagesDir", ".lake/packages")
|
|
156
|
+
if not isinstance(raw_packages_dir, str):
|
|
157
|
+
raise EnvironmentError("lock packagesDir must be a relative string")
|
|
158
|
+
packages_dir = PurePosixPath(raw_packages_dir)
|
|
159
|
+
if packages_dir.is_absolute() or ".." in packages_dir.parts:
|
|
160
|
+
raise EnvironmentError("lock packagesDir must be a safe relative path")
|
|
161
|
+
package_root = workspace.joinpath(*packages_dir.parts)
|
|
162
|
+
for package in lock.packages:
|
|
163
|
+
root = package_root / package.name
|
|
164
|
+
if package.subdir:
|
|
165
|
+
root = root.joinpath(*PurePosixPath(package.subdir).parts)
|
|
166
|
+
compiled = root / ".lake" / "build" / "lib" / "lean"
|
|
167
|
+
if compiled.is_dir():
|
|
168
|
+
roots.append(compiled)
|
|
169
|
+
# Lake places dependencies before the root package. Keep that precedence;
|
|
170
|
+
# the scratch root remains first so submitted support modules win.
|
|
171
|
+
if workspace_root.is_dir():
|
|
172
|
+
roots.append(workspace_root)
|
|
173
|
+
return tuple(roots)
|
|
174
|
+
|
|
175
|
+
|
|
150
176
|
@dataclass(frozen=True, slots=True)
|
|
151
177
|
class EnvironmentInfo:
|
|
152
178
|
environment_id: str
|
|
@@ -755,125 +781,96 @@ class Environment:
|
|
|
755
781
|
try:
|
|
756
782
|
instance_started = time.monotonic()
|
|
757
783
|
with self.manager.store.execution_lease(self.id):
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
staging_started = time.monotonic()
|
|
765
|
-
if operation == "check":
|
|
766
|
-
assert entrypoint is not None
|
|
767
|
-
for name, source in files.items():
|
|
768
|
-
source_path = instance / name
|
|
769
|
-
source_path.parent.mkdir(parents=True, exist_ok=True)
|
|
770
|
-
source_path.write_text(source, encoding="utf-8")
|
|
771
|
-
staging_timing = PhaseTiming(
|
|
772
|
-
"input_staging", round((time.monotonic() - staging_started) * 1000)
|
|
784
|
+
if operation == "check":
|
|
785
|
+
instance.mkdir()
|
|
786
|
+
else:
|
|
787
|
+
clone_tree(self.workspace, instance)
|
|
788
|
+
instance_timing = PhaseTiming(
|
|
789
|
+
"instance_creation", round((time.monotonic() - instance_started) * 1000)
|
|
773
790
|
)
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
791
|
+
preliminary: list[BackendResult] = []
|
|
792
|
+
path_map = {str(instance / name): name for name in files}
|
|
793
|
+
staging_started = time.monotonic()
|
|
794
|
+
execution_environment = self.manager.toolchains.environment
|
|
795
|
+
if operation == "check":
|
|
796
|
+
assert entrypoint is not None
|
|
797
|
+
for name, source in files.items():
|
|
798
|
+
source_path = instance / name
|
|
799
|
+
source_path.parent.mkdir(parents=True, exist_ok=True)
|
|
800
|
+
source_path.write_text(source, encoding="utf-8")
|
|
801
|
+
staging_timing = PhaseTiming(
|
|
802
|
+
"input_staging", round((time.monotonic() - staging_started) * 1000)
|
|
778
803
|
)
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
environment=self.manager.toolchains.environment,
|
|
783
|
-
policy=policy,
|
|
784
|
-
cancel=cancel,
|
|
804
|
+
lean_paths = _check_lean_paths(self.workspace, instance, self.lock)
|
|
805
|
+
execution_environment["LEAN_PATH"] = os.pathsep.join(
|
|
806
|
+
str(path) for path in lean_paths
|
|
785
807
|
)
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
808
|
+
for support in _support_order(files, entrypoint):
|
|
809
|
+
support_path = instance / support
|
|
810
|
+
output_path = (
|
|
811
|
+
instance / ".lake" / "build" / "lib" / "lean" / support
|
|
812
|
+
).with_suffix(".olean")
|
|
813
|
+
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
814
|
+
support_command = self.manager.toolchains.command(
|
|
815
|
+
self.lock.toolchain,
|
|
816
|
+
"lean",
|
|
817
|
+
"-R",
|
|
818
|
+
str(instance),
|
|
819
|
+
"-o",
|
|
820
|
+
str(output_path),
|
|
821
|
+
str(support_path),
|
|
822
|
+
)
|
|
823
|
+
support_result = self.manager.backend.execute(
|
|
824
|
+
support_command,
|
|
791
825
|
cwd=instance,
|
|
792
|
-
|
|
793
|
-
request_digest=request_digest,
|
|
794
|
-
source_digest=source_digest,
|
|
795
|
-
started_at=started_at,
|
|
826
|
+
environment=execution_environment,
|
|
796
827
|
policy=policy,
|
|
797
|
-
|
|
798
|
-
path_map=path_map,
|
|
799
|
-
)
|
|
800
|
-
self._record_execution(
|
|
801
|
-
result,
|
|
802
|
-
operation,
|
|
803
|
-
targets,
|
|
804
|
-
entrypoint,
|
|
805
|
-
tuple(files),
|
|
806
|
-
requested_command,
|
|
828
|
+
cancel=cancel,
|
|
807
829
|
)
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
830
|
+
preliminary.append(support_result)
|
|
831
|
+
if support_result.exit_code:
|
|
832
|
+
result = self._result(
|
|
833
|
+
support_result,
|
|
834
|
+
command=support_command,
|
|
835
|
+
cwd=instance,
|
|
836
|
+
execution_id=execution_id,
|
|
837
|
+
request_digest=request_digest,
|
|
838
|
+
source_digest=source_digest,
|
|
839
|
+
started_at=started_at,
|
|
840
|
+
policy=policy,
|
|
841
|
+
timings=(instance_timing, staging_timing),
|
|
842
|
+
path_map=path_map,
|
|
843
|
+
)
|
|
844
|
+
self._record_execution(
|
|
845
|
+
result,
|
|
846
|
+
operation,
|
|
847
|
+
targets,
|
|
848
|
+
entrypoint,
|
|
849
|
+
tuple(files),
|
|
850
|
+
requested_command,
|
|
851
|
+
)
|
|
852
|
+
return result
|
|
853
|
+
source_path = instance / entrypoint
|
|
854
|
+
command = self.manager.toolchains.command(
|
|
855
|
+
self.lock.toolchain, "lean", "-R", str(instance), str(source_path)
|
|
825
856
|
)
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
policy=policy,
|
|
831
|
-
cancel=cancel,
|
|
857
|
+
elif operation == "build":
|
|
858
|
+
staging_timing = PhaseTiming("input_staging", 0, performed=False)
|
|
859
|
+
command = self.manager.toolchains.command(
|
|
860
|
+
self.lock.toolchain, "lake", "build", *targets
|
|
832
861
|
)
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
timings=(instance_timing, staging_timing),
|
|
845
|
-
path_map=path_map,
|
|
846
|
-
)
|
|
847
|
-
self._record_execution(
|
|
848
|
-
result,
|
|
849
|
-
operation,
|
|
850
|
-
targets,
|
|
851
|
-
entrypoint,
|
|
852
|
-
tuple(files),
|
|
853
|
-
requested_command,
|
|
854
|
-
)
|
|
855
|
-
return result
|
|
856
|
-
source_path = instance / entrypoint
|
|
857
|
-
command = self.manager.toolchains.command(
|
|
858
|
-
self.lock.toolchain, "lake", "env", "lean", str(source_path)
|
|
859
|
-
)
|
|
860
|
-
elif operation == "build":
|
|
861
|
-
staging_timing = PhaseTiming("input_staging", 0, performed=False)
|
|
862
|
-
command = self.manager.toolchains.command(
|
|
863
|
-
self.lock.toolchain, "lake", "build", *targets
|
|
864
|
-
)
|
|
865
|
-
else:
|
|
866
|
-
staging_timing = PhaseTiming("input_staging", 0, performed=False)
|
|
867
|
-
command = self.manager.toolchains.command(
|
|
868
|
-
self.lock.toolchain, requested_command[0], *requested_command[1:]
|
|
862
|
+
else:
|
|
863
|
+
staging_timing = PhaseTiming("input_staging", 0, performed=False)
|
|
864
|
+
command = self.manager.toolchains.command(
|
|
865
|
+
self.lock.toolchain, requested_command[0], *requested_command[1:]
|
|
866
|
+
)
|
|
867
|
+
raw = self.manager.backend.execute(
|
|
868
|
+
command,
|
|
869
|
+
cwd=instance,
|
|
870
|
+
environment=execution_environment,
|
|
871
|
+
policy=policy,
|
|
872
|
+
cancel=cancel,
|
|
869
873
|
)
|
|
870
|
-
raw = self.manager.backend.execute(
|
|
871
|
-
command,
|
|
872
|
-
cwd=instance,
|
|
873
|
-
environment=self.manager.toolchains.environment,
|
|
874
|
-
policy=policy,
|
|
875
|
-
cancel=cancel,
|
|
876
|
-
)
|
|
877
874
|
if operation == "check" and preliminary:
|
|
878
875
|
raw = BackendResult(
|
|
879
876
|
exit_code=raw.exit_code,
|
|
@@ -42,7 +42,7 @@ from .profiling import ProfileReport, run_profile
|
|
|
42
42
|
from .programs import ProgramInfo, ProgramLibrary, ProgramManager, ReadyProgram
|
|
43
43
|
from .projects import ProjectContext, ProjectEnvironment, discover_project
|
|
44
44
|
from .publisher_verification import CosignVerifier
|
|
45
|
-
from .references import PackageReference, discover_package, normalize_references
|
|
45
|
+
from .references import PACKAGE_ALIASES, PackageReference, discover_package, normalize_references
|
|
46
46
|
from .resolver import EnvironmentResolver
|
|
47
47
|
from .serialization import sha256_id, sha256_text
|
|
48
48
|
from .specs import EnvironmentSpec, GitPackage
|
|
@@ -66,6 +66,38 @@ from .verification import (
|
|
|
66
66
|
EnvironmentReference = Environment | EnvironmentSpec | EnvironmentLock | str
|
|
67
67
|
|
|
68
68
|
|
|
69
|
+
def _bundled_lock_for_references(
|
|
70
|
+
packages: Sequence[str | PackageReference], toolchain: str | None
|
|
71
|
+
) -> EnvironmentLock | None:
|
|
72
|
+
"""Match a single exact alias tag to its bundled, downloadable catalog lock."""
|
|
73
|
+
references = normalize_references(packages)
|
|
74
|
+
if len(references) != 1:
|
|
75
|
+
return None
|
|
76
|
+
reference = references[0]
|
|
77
|
+
if reference.revision_kind != "tag":
|
|
78
|
+
return None
|
|
79
|
+
alias = next(
|
|
80
|
+
(
|
|
81
|
+
name
|
|
82
|
+
for name, (owner, repository, _command) in PACKAGE_ALIASES.items()
|
|
83
|
+
if reference.url == f"https://github.com/{owner}/{repository}.git"
|
|
84
|
+
),
|
|
85
|
+
None,
|
|
86
|
+
)
|
|
87
|
+
if alias is None:
|
|
88
|
+
return None
|
|
89
|
+
entry_id = f"{alias}-{reference.revision}"
|
|
90
|
+
# Imported lazily: discovery's probe layer also imports Runtime.
|
|
91
|
+
from .discovery.defaults import default_catalog
|
|
92
|
+
|
|
93
|
+
entry = next((item for item in default_catalog().entries if item.id == entry_id), None)
|
|
94
|
+
if entry is None:
|
|
95
|
+
return None
|
|
96
|
+
if toolchain is not None and normalize_toolchain(toolchain) != entry.toolchain:
|
|
97
|
+
return None
|
|
98
|
+
return entry.lock
|
|
99
|
+
|
|
100
|
+
|
|
69
101
|
def _download_reason(error: Exception) -> str:
|
|
70
102
|
message = str(error).lower()
|
|
71
103
|
if "platform" in message or "compatible" in message:
|
|
@@ -631,6 +663,14 @@ class Runtime:
|
|
|
631
663
|
cancel: threading.Event | None = None,
|
|
632
664
|
) -> EnvironmentLock:
|
|
633
665
|
"""Discover package references and resolve their exact Lake graph."""
|
|
666
|
+
catalog_lock = _bundled_lock_for_references(packages, toolchain)
|
|
667
|
+
if catalog_lock is not None:
|
|
668
|
+
self.events.emit(
|
|
669
|
+
"catalog.reference_matched",
|
|
670
|
+
"Using bundled exact environment for package reference",
|
|
671
|
+
lock_id=catalog_lock.lock_id,
|
|
672
|
+
)
|
|
673
|
+
return catalog_lock
|
|
634
674
|
return self.prepare(
|
|
635
675
|
self.spec_from_references(packages, toolchain=toolchain),
|
|
636
676
|
timeout=timeout,
|
|
@@ -35,8 +35,10 @@ from pathlib import Path
|
|
|
35
35
|
ACCEPTANCE = Path(__file__).resolve().parent.parent / "acceptance"
|
|
36
36
|
|
|
37
37
|
COLD_TIMEOUT = 2700 # toolchain download + environment download, no builds
|
|
38
|
-
WARM_TIMEOUT =
|
|
39
|
-
WARM_LIMIT =
|
|
38
|
+
WARM_TIMEOUT = 600
|
|
39
|
+
WARM_LIMIT = 400 # hang detector, not a perf bar: GitHub macOS runners take ~4x
|
|
40
|
+
# longer than real hardware for the warm Lake trace scan (238s observed vs 38s
|
|
41
|
+
# on an M-series laptop)
|
|
40
42
|
|
|
41
43
|
|
|
42
44
|
def run(
|
|
@@ -169,7 +171,7 @@ def main() -> int:
|
|
|
169
171
|
ok = ok and step(
|
|
170
172
|
"python-batch-api",
|
|
171
173
|
[sys.executable, str(ACCEPTANCE / "python_api.py"), str(lock_path)],
|
|
172
|
-
timeout=
|
|
174
|
+
timeout=1500,
|
|
173
175
|
)
|
|
174
176
|
|
|
175
177
|
usage = shutil.disk_usage(home)
|
|
@@ -3,7 +3,12 @@ from __future__ import annotations
|
|
|
3
3
|
import pytest
|
|
4
4
|
|
|
5
5
|
from lean_runtime import EnvironmentError, EnvironmentLock, LockedPackage
|
|
6
|
-
from lean_runtime.environments import
|
|
6
|
+
from lean_runtime.environments import (
|
|
7
|
+
_check_lean_paths,
|
|
8
|
+
_package_import_targets,
|
|
9
|
+
_source_files,
|
|
10
|
+
_support_order,
|
|
11
|
+
)
|
|
7
12
|
|
|
8
13
|
|
|
9
14
|
def test_nested_lean_sources_are_normalized() -> None:
|
|
@@ -55,3 +60,34 @@ def test_package_import_targets_exclude_core_and_submitted_modules() -> None:
|
|
|
55
60
|
"Main.lean": "import Init\nimport Local\nimport ProofWidgets.Util",
|
|
56
61
|
}
|
|
57
62
|
assert _package_import_targets(files, lock) == ("ProofWidgets",)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def test_check_lean_paths_include_scratch_root_and_compiled_packages(tmp_path) -> None:
|
|
66
|
+
lock = EnvironmentLock(
|
|
67
|
+
toolchain="leanprover/lean4:v4.32.0",
|
|
68
|
+
spec_digest="spec_" + "a" * 64,
|
|
69
|
+
root_lakefile='name = "test"\n',
|
|
70
|
+
root_module="",
|
|
71
|
+
manifest={"packages": [], "packagesDir": "vendor"},
|
|
72
|
+
packages=(
|
|
73
|
+
LockedPackage(
|
|
74
|
+
name="sample",
|
|
75
|
+
url="https://example.test/sample",
|
|
76
|
+
revision="b" * 40,
|
|
77
|
+
source_id="source_" + "c" * 64,
|
|
78
|
+
tree_hash="d" * 40,
|
|
79
|
+
subdir="lean",
|
|
80
|
+
),
|
|
81
|
+
),
|
|
82
|
+
)
|
|
83
|
+
workspace = tmp_path / "workspace"
|
|
84
|
+
root_build = workspace / ".lake" / "build" / "lib" / "lean"
|
|
85
|
+
package_build = workspace / "vendor" / "sample" / "lean" / ".lake" / "build" / "lib" / "lean"
|
|
86
|
+
root_build.mkdir(parents=True)
|
|
87
|
+
package_build.mkdir(parents=True)
|
|
88
|
+
|
|
89
|
+
assert _check_lean_paths(workspace, tmp_path / "scratch", lock) == (
|
|
90
|
+
tmp_path / "scratch" / ".lake" / "build" / "lib" / "lean",
|
|
91
|
+
package_build,
|
|
92
|
+
root_build,
|
|
93
|
+
)
|
|
@@ -7,7 +7,18 @@ from pathlib import Path
|
|
|
7
7
|
|
|
8
8
|
import pytest
|
|
9
9
|
|
|
10
|
-
from lean_runtime import
|
|
10
|
+
from lean_runtime import (
|
|
11
|
+
EnvironmentLock,
|
|
12
|
+
EnvironmentSpec,
|
|
13
|
+
ExecutionJob,
|
|
14
|
+
ResolutionError,
|
|
15
|
+
Runtime,
|
|
16
|
+
ToolchainError,
|
|
17
|
+
)
|
|
18
|
+
from lean_runtime.backends import LocalBackend
|
|
19
|
+
from lean_runtime.environments import Environment, EnvironmentManager
|
|
20
|
+
from lean_runtime.runtime import _bundled_lock_for_references
|
|
21
|
+
from lean_runtime.store import EnvironmentStore
|
|
11
22
|
|
|
12
23
|
|
|
13
24
|
class FakeToolchains:
|
|
@@ -35,6 +46,54 @@ class FakeToolchains:
|
|
|
35
46
|
return [sys.executable, "-c", "raise SystemExit(0)"]
|
|
36
47
|
|
|
37
48
|
|
|
49
|
+
def test_exact_mathlib_reference_matches_bundled_catalog_lock() -> None:
|
|
50
|
+
lock = _bundled_lock_for_references(["mathlib@v4.32.2"], None)
|
|
51
|
+
assert lock is not None
|
|
52
|
+
assert lock.toolchain == "leanprover/lean4:v4.32.2"
|
|
53
|
+
assert any(package.name == "mathlib" for package in lock.packages)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def test_catalog_reference_match_respects_context_and_toolchain() -> None:
|
|
57
|
+
assert _bundled_lock_for_references(["mathlib@main"], None) is None
|
|
58
|
+
assert _bundled_lock_for_references(["mathlib@v4.32.2", "leancert@main"], None) is None
|
|
59
|
+
assert _bundled_lock_for_references(["mathlib@v4.32.2"], "v4.31.0") is None
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def test_environment_check_does_not_clone_published_workspace(
|
|
63
|
+
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
|
64
|
+
) -> None:
|
|
65
|
+
store = EnvironmentStore(tmp_path / "runtime")
|
|
66
|
+
environment_id = "env_" + "a" * 64
|
|
67
|
+
root = store.environment_path(environment_id)
|
|
68
|
+
(root / "workspace" / ".lake" / "build" / "lib" / "lean").mkdir(parents=True)
|
|
69
|
+
lock = EnvironmentLock(
|
|
70
|
+
toolchain="leanprover/lean4:v4.32.0",
|
|
71
|
+
spec_digest="spec_" + "b" * 64,
|
|
72
|
+
root_lakefile='name = "test"\n',
|
|
73
|
+
root_module="",
|
|
74
|
+
manifest={"packages": []},
|
|
75
|
+
packages=(),
|
|
76
|
+
)
|
|
77
|
+
manager = EnvironmentManager(
|
|
78
|
+
store,
|
|
79
|
+
FakeToolchains(tmp_path / "runtime"), # type: ignore[arg-type]
|
|
80
|
+
LocalBackend(),
|
|
81
|
+
)
|
|
82
|
+
environment = Environment(
|
|
83
|
+
manager,
|
|
84
|
+
environment_id,
|
|
85
|
+
lock,
|
|
86
|
+
root,
|
|
87
|
+
{"platform": {}, "build_profile": "release", "created_at": "2026-08-12T00:00:00Z"},
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
def unexpected_clone(_source: Path, _destination: Path) -> None:
|
|
91
|
+
raise AssertionError("checks must not clone a published workspace")
|
|
92
|
+
|
|
93
|
+
monkeypatch.setattr("lean_runtime.environments.clone_tree", unexpected_clone)
|
|
94
|
+
assert environment.check("example : True := by trivial").ok
|
|
95
|
+
|
|
96
|
+
|
|
38
97
|
def test_check_accepts_source(tmp_path: Path) -> None:
|
|
39
98
|
runtime = Runtime(toolchains=FakeToolchains(tmp_path)) # type: ignore[arg-type]
|
|
40
99
|
result = runtime.check("example : True := by trivial", toolchain="4.32.0")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/discovery/schemas/catalog-v1.schema.json
RENAMED
|
File without changes
|
{lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/discovery/schemas/plan-v1.schema.json
RENAMED
|
File without changes
|
{lean_runtime-2.1.2 → lean_runtime-2.2.0}/lean_runtime/discovery/schemas/result-v1.schema.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lean_runtime-2.1.2 → lean_runtime-2.2.0}/tests/discovery/test_discovery_schema_resources.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|