commit 9379a82f3e413a41335a642081018fb08a9348f7
parent fb9a6fe690ec46a2a4c8f872c6a6b2840c2296d4
Author: gracefu <81774659+gracefuu@users.noreply.github.com>
Date: Sun, 20 Apr 2025 08:01:30 +0800
Refactor the rerun_if_changed based build system into its own file
Diffstat:
| A | make3.py | | | 136 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | tar-sketch/a.txt | | | 2 | +- |
| M | tar-sketch/tar2.py | | | 118 | ++++--------------------------------------------------------------------------- |
3 files changed, 143 insertions(+), 113 deletions(-)
diff --git a/make3.py b/make3.py
@@ -0,0 +1,136 @@
+import contextvars
+import functools
+import inspect
+import pickle
+from typing import Any
+
+rerun_db_var: contextvars.ContextVar[dict] = contextvars.ContextVar("rerun_db")
+rerun_changes_var: contextvars.ContextVar[list[tuple[str, Any]]] = (
+ contextvars.ContextVar("rerun_changes")
+)
+rerun_globals_var: contextvars.ContextVar[dict[str, Any]] = contextvars.ContextVar(
+ "rerun_globals"
+)
+rerun_locals_var: contextvars.ContextVar[dict[str, Any]] = contextvars.ContextVar(
+ "rerun_locals"
+)
+
+
+def with_rerun_context(
+ rerun_changes, rerun_globals, rerun_locals, f, /, *args, **kwargs
+):
+ rerun_changes_var.set(rerun_changes)
+ rerun_globals_var.set(rerun_globals)
+ rerun_locals_var.set(rerun_locals)
+ return f(*args, **kwargs)
+
+
+class UseEval: ...
+
+
+def rerun_if_changed(f_str, current_value: Any = UseEval):
+ rerun_changes_var.get().append(
+ (
+ f_str,
+ (
+ eval(
+ f_str,
+ globals=rerun_globals_var.get(),
+ locals=rerun_locals_var.get(),
+ )
+ if current_value == UseEval
+ else current_value
+ ),
+ )
+ )
+
+
+def rerun_if(f_str):
+ return rerun_if_changed(f"bool({f_str})", False)
+
+
+def cache_conditionally(
+ keys_fn=lambda *args, **kwargs: (args, tuple(sorted(kwargs.items()))),
+ store_fn=lambda result, /, *_, **__: result,
+ load_fn=lambda cached_result, /, *_, **__: cached_result,
+):
+ def decorator(fn):
+ signature = inspect.signature(fn)
+
+ @functools.wraps(fn)
+ def wrapped(*args, **kwargs):
+ db = rerun_db_var.get()
+ keys = keys_fn(*args, **kwargs)
+ bound_args = signature.bind(*args, **kwargs)
+ bound_args.apply_defaults()
+ rerun_locals = bound_args.arguments
+ if ("track", "result", fn.__qualname__, keys) in db:
+ if ("track", "rerun_changes", fn.__qualname__, keys) not in db:
+ old_rerun_changes = []
+ db[("track", "rerun_changes", fn.__qualname__, keys)] = (
+ old_rerun_changes
+ )
+ else:
+ old_rerun_changes = db[
+ ("track", "rerun_changes", fn.__qualname__, keys)
+ ]
+ for expr, old_val in old_rerun_changes:
+ try:
+ res = eval(expr, globals=fn.__globals__, locals=rerun_locals)
+ if res != old_val:
+ break
+ except BaseException:
+ break
+ else:
+ return load_fn(
+ db[("track", "result", fn.__qualname__, keys)], *args, **kwargs
+ )
+
+ context = contextvars.copy_context()
+ rerun_changes = []
+ result = context.run(
+ with_rerun_context,
+ rerun_changes,
+ fn.__globals__,
+ rerun_locals,
+ fn,
+ *args,
+ **kwargs,
+ )
+ db[("track", "rerun_changes", fn.__qualname__, keys)] = rerun_changes
+ db[("track", "result", fn.__qualname__, keys)] = store_fn(
+ result, *args, **kwargs
+ )
+ return result
+
+ return wrapped
+
+ return decorator
+
+
+class Rerunner:
+ def __init__(self, db_filename=b".makedb", db_file=None):
+ if db_file:
+ self.db_file = db_file
+ else:
+ self.db_file = open(db_filename, "a+b")
+ self.db_file.seek(0)
+
+ def __enter__(self):
+ self.db_file.__enter__()
+ try:
+ self.db = pickle.load(self.db_file)
+ except pickle.PickleError:
+ self.db = dict()
+ except EOFError:
+ self.db = dict()
+ self.var_tok = rerun_db_var.set(self.db)
+ return self
+
+ def __exit__(self, ty, exc, tb):
+ rerun_db_var.reset(self.var_tok)
+ if exc is None:
+ self.db_file.seek(0)
+ self.db_file.truncate(0)
+ pickle.dump(self.db, self.db_file)
+ self.db_file.__exit__(ty, exc, tb)
diff --git a/tar-sketch/a.txt b/tar-sketch/a.txt
@@ -1 +1 @@
-Sun Apr 20 07:16:53 AM +08 2025
+Sun Apr 20 08:02:47 AM +08 2025
diff --git a/tar-sketch/tar2.py b/tar-sketch/tar2.py
@@ -1,117 +1,13 @@
-import contextvars
-import functools
-import inspect
-import pickle
-from typing import Any
-
-db: dict = dict()
-
-try:
- with open(b".makedb", "rb") as f:
- db = pickle.load(f)
-except BaseException as e:
- pass
-
-
-def get_or_set(d, k, v):
- if k in d:
- return d[k]
- d[k] = v
- return v
-
-
-rerun_changes_var: contextvars.ContextVar[list[tuple[str, Any]]] = (
- contextvars.ContextVar("rerun_changes")
-)
-rerun_locals_var: contextvars.ContextVar[dict[str, Any]] = contextvars.ContextVar(
- "rerun_locals"
-)
-
-
-def with_rerun_context(rerun_changes, rerun_locals, f, /, *args, **kwargs):
- rerun_changes_var.set(rerun_changes)
- rerun_locals_var.set(rerun_locals)
- return f(*args, **kwargs)
-
-
-class UseEval:
- pass
-
-
-class UseCaller:
- pass
-
-
-def rerun_if_changed(f_str, current_value: Any = UseEval):
- rerun_changes_var.get().append(
- (
- f_str,
- (
- eval(f_str, locals=rerun_locals_var.get())
- if current_value == UseEval
- else current_value
- ),
- )
- )
-
-
-def rerun_if(f_str):
- return rerun_if_changed(f"bool({f_str})", False)
-
-
-def cache_conditionally(
- keys_fn=lambda *args, **kwargs: (args, tuple(sorted(kwargs.items()))),
- store_fn=lambda cached_result, /, *_, **__: cached_result,
- load_fn=lambda cached_result, /, *_, **__: cached_result,
-):
- def decorator(fn):
- signature = inspect.signature(fn)
-
- @functools.wraps(fn)
- def wrapped(*args, **kwargs):
- keys = keys_fn(*args, **kwargs)
- bound_args = signature.bind(*args, **kwargs)
- bound_args.apply_defaults()
- rerun_locals = bound_args.arguments
- if ("track", "result", fn.__qualname__, keys) in db:
- old_rerun_changes = get_or_set(
- db, ("track", "rerun_changes", fn.__qualname__, keys), []
- )
- for expr, old_val in old_rerun_changes:
- try:
- res = eval(expr, locals=rerun_locals)
- if res != old_val:
- break
- except:
- break
- else:
- return load_fn(
- db[("track", "result", fn.__qualname__, keys)], *args, **kwargs
- )
-
- context = contextvars.copy_context()
- rerun_changes = []
- result = context.run(
- with_rerun_context, rerun_changes, rerun_locals, fn, *args, **kwargs
- )
- db[("track", "rerun_changes", fn.__qualname__, keys)] = rerun_changes
- db[("track", "result", fn.__qualname__, keys)] = store_fn(
- result, *args, **kwargs
- )
- return result
-
- return wrapped
-
- return decorator
+import sys
+sys.path.append("..")
+from make3 import cache_conditionally, rerun_if_changed, Rerunner
+from io import BufferedReader
import hashlib
import os
import subprocess
-from io import BufferedReader
-
-
file_modtime = lambda f: os.stat(f.fileno()).st_mtime_ns
@@ -146,7 +42,5 @@ def tar(manifest=b"manifest", output=b"archive.tar.gz"):
rerun_if_changed(f"file_hash({repr(output)})")
-tar()
-
-with open(b".makedb", "wb") as f:
- pickle.dump(db, f)
+with Rerunner():
+ tar()