Completed
Details
Details
Assignee
Unassigned
UnassignedReporter
Shogo Ohta
Shogo OhtaLabels
Approval
Ok
Patch
Code and Test
Priority
Affects versions
Fix versions
Created June 8, 2017 at 10:51 AM
Updated June 26, 2018 at 4:59 PM
Resolved June 26, 2018 at 4:59 PM
In the following example, the ::x key is required in the map but it will conform without error for an empty collection:
(s/def ::x integer?) (s/conform (s/keys* :req-un [::x]) []) ;; nil, expected error (s/explain (s/keys* :req-un [::x]) []) ;; Success!, expected explanation
Cause: At the moment,
(s/keys* :req-un [::x])
is expanded to a form equivalent to the following one:(s/& (s/* (s/cat ::s/k keyword? ::s/v)) ::s/kvs->map (s/keys :req-un [::x]))
The issue seems to be in the implementation of
s/&
, specifically the ::amp branch of accept-nil? which expects that either the conformed regex returns empty or that the preds are not invalid. This seems like a false assumption that an empty conformed regex ret does not require the s/& preds to be valid. In this case we are using a conformer to transform the input and do another check, so it's certainly not valid here.Proposed: Modify s/& to always validate the preds when accepting nil.
user=> (s/conform (s/keys* :req-un [::x]) []) :clojure.spec.alpha/invalid user=> (-> (s/explain-data (s/keys* :req-un [::x]) []) ::s/problems first :pred) (clojure.core/fn [%] (clojure.core/contains? % :x))
Patch: clj-2182-2.patch
Screened by: Stu Halloway