-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ENH(TST): add a test to verify correct operation on closures/local functions #18
Comments
The tests already apply memoization to local functions, e.g., here: fscacher/src/fscacher/tests/test_cache.py Lines 87 to 94 in 3bb9d0c
|
this is within a single test function run. What if could we detect whenever function uses |
@yarikoptic The following test succeeds (Is this what you had in mind?), though I don't immediately see anything in joblib that would address this: def test_memoize_path_closure(cache, monkeypatch, tmp_path):
def mkfunc(x):
@cache.memoize_path
def func(path):
return (x, os.stat(path).st_size)
return func
monkeypatch.chdir(tmp_path)
fname = "foo.txt"
with open(fname, "wb") as fp:
fp.write(b"This is test text.\n")
func1 = mkfunc(23)
func2 = mkfunc(42)
assert func1(fname) == (23, 19)
assert func2(fname) == (42, 19) |
can we detect a closure (i.e. whenever |
@yarikoptic The closest thing I can find is the
|
cool. Let's just add |
@yarikoptic The |
Tracking for closures is largely a "safety" measure, sure thing people (and us) can find ways around. I guess "workaround" would be to use some |
@yarikoptic You're suggesting that I rewrite the tests so that they don't use local functions so that the library can fail when it detects a closure? I feel that that's a bad idea, especially since the test I posted above suggests that fscacher already correctly handles closures via some behavior of joblib that I can't find with a quick search. I think the library should continue being closure-agnostic, we add the above test (and maybe a couple others) to the test suite, and if a problem with closures ever occurs that the library doesn't handle properly, then we can revisit this issue. |
my bad, indeed it does somehow! magic... ok, let's continue to be "closure-agnostic" but can that test also be extended to verify that subsequent |
@yarikoptic I'm confused. What I was going to post originally was:
But then I thought "Should this be regarded as a bug in joblib? I should write an MVCE." So I wrote this: from pathlib import Path
from tempfile import TemporaryDirectory
from joblib import Memory
with TemporaryDirectory() as tmpdir_:
tmpdir = Path(tmpdir_)
cache = Memory(str(tmpdir / "foo"), verbose=0)
def show_record(recordfile):
try:
return recordfile.read_text().splitlines()
except FileNotFoundError:
return []
def local_closure(recordfile):
@cache.cache
def func(x):
with recordfile.open("a") as fp:
print(x, file=fp)
return recordfile.stat().st_size
print("record =", show_record(recordfile))
print("func(23) =", func(23))
print("record =", show_record(recordfile))
print("func(42) =", func(42))
print("record =", show_record(recordfile))
print("func(23) =", func(23))
print("record =", show_record(recordfile))
local_closure(tmpdir / "record01.txt")
print()
def return_closure(recordfile):
@cache.cache
def func2(x):
with recordfile.open("a") as fp:
print(x, file=fp)
return recordfile.stat().st_size
return func2
rec = tmpdir / "record02.txt"
func = return_closure(rec)
print("record =", show_record(rec))
print("func(23) =", func(23))
print("record =", show_record(rec))
print("func(42) =", func(42))
print("record =", show_record(rec))
print("func(23) =", func(23))
print("record =", show_record(rec))
print()
rec = tmpdir / "record03.txt"
func = return_closure(rec)
print("record =", show_record(rec))
print("func(23) =", func(23))
print("record =", show_record(rec))
print("func(42) =", func(42))
print("record =", show_record(rec))
print("func(23) =", func(23))
print("record =", show_record(rec)) and when I ran it, I found that the first two record+func blocks returned properly cached results, while, for the third block, |
thanks for digging! I have no immediate ideas, and memory fails me (again) -- I remember vaguely having to deal with something related to
told you -- it is magic! ;) but we will figure it out and turn it either into boring "technology" or a bug ;-) |
as given in example of #17
if that could not work (e.g. we then need to add closure's space into fingerprinted signature, and somehow cannot/should not do that) -- we should raise some exception (might be
NotImplementedError("caching on functions with closures is not supported")
)the same probably would go for functions accessing
global
variables space, but I guess it is nothing we could deduce/control for, right?The text was updated successfully, but these errors were encountered: