Summary
An Optional key with a mutable default (e.g. default=[] or default={}) returns the same object on every validate(). Mutating one validation's result corrupts the default for all subsequent validations of the same Schema — the classic shared-mutable-default footgun, causing state to leak between unrelated validate() calls.
Reproduction
from schema import Schema, Optional
s = Schema({Optional("items", default=[]): list})
a = s.validate({})
a["items"].append(1)
b = s.validate({})
print(b["items"]) # [1] <- expected []
Expected
Each independent validate({}) returns a fresh default; b["items"] == [].
Actual
b["items"] == [1] — the default object is shared and leaks across calls.
Fix sketch
Copy the default when applying it (e.g. copy.deepcopy(default)), and/or support callable defaults.
Environment
schema 0.7.8 (master @ 310a123), Python 3.12.
Summary
An
Optionalkey with a mutabledefault(e.g.default=[]ordefault={}) returns the same object on everyvalidate(). Mutating one validation's result corrupts the default for all subsequent validations of the sameSchema— the classic shared-mutable-default footgun, causing state to leak between unrelatedvalidate()calls.Reproduction
Expected
Each independent
validate({})returns a fresh default;b["items"] == [].Actual
b["items"] == [1]— the default object is shared and leaks across calls.Fix sketch
Copy the default when applying it (e.g.
copy.deepcopy(default)), and/or support callable defaults.Environment
schema 0.7.8 (master @ 310a123), Python 3.12.