Skip to content

Commit 5126164

Browse files
puredangerstuarthalloway
authored andcommitted
CLJ-2469 Make fewer assumptions about maps when printing them
Signed-off-by: Stuart Halloway <stu@cognitect.com>
1 parent fb341d3 commit 5126164

File tree

2 files changed

+57
-15
lines changed

2 files changed

+57
-15
lines changed

src/clj/clojure/core_print.clj

+12-12
Original file line numberDiff line numberDiff line change
@@ -226,14 +226,14 @@
226226
(print-meta v w)
227227
(print-sequential "[" pr-on " " "]" v w))
228228

229-
(defn- print-prefix-map [prefix m print-one w]
229+
(defn- print-prefix-map [prefix kvs print-one w]
230230
(print-sequential
231231
(str prefix "{")
232-
(fn [e ^Writer w]
233-
(do (print-one (key e) w) (.append w \space) (print-one (val e) w)))
232+
(fn [[k v] ^Writer w]
233+
(do (print-one k w) (.append w \space) (print-one v w)))
234234
", "
235235
"}"
236-
(seq m) w))
236+
kvs w))
237237

238238
(defn- print-map [m print-one w]
239239
(print-prefix-map nil m print-one w))
@@ -245,26 +245,26 @@
245245
(keyword nil (name named))))
246246

247247
(defn- lift-ns
248-
"Returns [lifted-ns lifted-map] or nil if m can't be lifted."
248+
"Returns [lifted-ns lifted-kvs] or nil if m can't be lifted."
249249
[m]
250250
(when *print-namespace-maps*
251251
(loop [ns nil
252252
[[k v :as entry] & entries] (seq m)
253-
lm {}]
253+
kvs []]
254254
(if entry
255-
(when (or (keyword? k) (symbol? k))
255+
(when (qualified-ident? k)
256256
(if ns
257257
(when (= ns (namespace k))
258-
(recur ns entries (assoc lm (strip-ns k) v)))
258+
(recur ns entries (conj kvs [(strip-ns k) v])))
259259
(when-let [new-ns (namespace k)]
260-
(recur new-ns entries (assoc lm (strip-ns k) v)))))
261-
[ns (apply conj (empty m) lm)]))))
260+
(recur new-ns entries (conj kvs [(strip-ns k) v])))))
261+
[ns kvs]))))
262262

263263
(defmethod print-method clojure.lang.IPersistentMap [m, ^Writer w]
264264
(print-meta m w)
265-
(let [[ns lift-map] (lift-ns m)]
265+
(let [[ns lift-kvs] (lift-ns m)]
266266
(if ns
267-
(print-prefix-map (str "#:" ns) lift-map pr-on w)
267+
(print-prefix-map (str "#:" ns) lift-kvs pr-on w)
268268
(print-map m pr-on w))))
269269

270270
(defmethod print-dup java.util.Map [m, ^Writer w]

test/clojure/test_clojure/printer.clj

+45-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
;; Created 29 October 2008
1515

1616
(ns clojure.test-clojure.printer
17-
(:use clojure.test))
17+
(:use clojure.test)
18+
(:require [clojure.pprint :refer [pprint]]))
1819

1920
(deftest print-length-empty-seq
2021
(let [coll () val "()"]
@@ -135,8 +136,49 @@
135136
{:with "even" :more 'data})))))))
136137

137138
(deftest print-ns-maps
138-
(is (= "#:user{:a 1}" (binding [*print-namespace-maps* true] (pr-str {:user/a 1}))))
139-
(is (= "{:user/a 1}" (binding [*print-namespace-maps* false] (pr-str {:user/a 1}))))
139+
(are [m s-on pp-on s-off]
140+
(and (= s-on (binding [*print-namespace-maps* true] (pr-str m)))
141+
(= pp-on (binding [*print-namespace-maps* true] (with-out-str (pprint m))))
142+
(= s-off (binding [*print-namespace-maps* false] (pr-str m))))
143+
{} "{}" "{}\n" "{}"
144+
{:a 1, :b 2} "{:a 1, :b 2}" "{:a 1, :b 2}\n" "{:a 1, :b 2}"
145+
{:user/a 1} "#:user{:a 1}" "#:user{:a 1}\n" "{:user/a 1}"
146+
{:user/a 1, :user/b 2} "#:user{:a 1, :b 2}" "#:user{:a 1, :b 2}\n" "{:user/a 1, :user/b 2}"
147+
{:user/a 1, :b 2} "{:user/a 1, :b 2}" "{:user/a 1, :b 2}\n" "{:user/a 1, :b 2}"
148+
{:user/a 1, 'user/b 2} "#:user{:a 1, b 2}" "#:user{:a 1, b 2}\n" "{:user/a 1, user/b 2}"
149+
{:user/a 1, :foo/b 2} "{:user/a 1, :foo/b 2}" "{:user/a 1, :foo/b 2}\n" "{:user/a 1, :foo/b 2}"
150+
151+
{:user/a 1, :user/b 2, 100 200}
152+
"{:user/a 1, :user/b 2, 100 200}"
153+
"{:user/a 1, :user/b 2, 100 200}\n"
154+
"{:user/a 1, :user/b 2, 100 200}"
155+
156+
;; CLJ-2469
157+
(struct (create-struct :q/a :q/b :q/c) 1 2 3)
158+
"#:q{:a 1, :b 2, :c 3}"
159+
"#:q{:a 1, :b 2, :c 3}\n"
160+
"{:q/a 1, :q/b 2, :q/c 3}"
161+
162+
;; CLJ-2537
163+
{:x.y/a {:rem 0}, :x.y/b {:rem 1}}
164+
"#:x.y{:a {:rem 0}, :b {:rem 1}}"
165+
"#:x.y{:a {:rem 0}, :b {:rem 1}}\n"
166+
"{:x.y/a {:rem 0}, :x.y/b {:rem 1}}"
167+
168+
(into (sorted-map-by (fn [k1 k2]
169+
(when-not (every? qualified-ident? [k1 k2])
170+
(throw (RuntimeException. (str "Invalid keys:" [k1 k2]))))
171+
(compare k1 k2))
172+
:x.y/a {:rem 0}, :x.y/b {:rem 1}))
173+
"#:x.y{:a {:rem 0}, :b {:rem 1}}"
174+
"#:x.y{:a {:rem 0}, :b {:rem 1}}\n"
175+
"{:x.y/a {:rem 0}, :x.y/b {:rem 1}}"
176+
177+
(sorted-map-by #(compare %2 %1) :k/a 1 :k/b 2 :k/c 3 :k/d 4 :k/e 5 :k/f 6 :k/g 7 :k/h 8 :k/i 9)
178+
"#:k{:i 9, :h 8, :g 7, :f 6, :e 5, :d 4, :c 3, :b 2, :a 1}"
179+
"#:k{:i 9, :h 8, :g 7, :f 6, :e 5, :d 4, :c 3, :b 2, :a 1}\n"
180+
"{:k/i 9, :k/h 8, :k/g 7, :k/f 6, :k/e 5, :k/d 4, :k/c 3, :k/b 2, :k/a 1}")
181+
140182
(let [date-map (bean (java.util.Date. 0))]
141183
(is (= (binding [*print-namespace-maps* true] (pr-str date-map))
142184
(binding [*print-namespace-maps* false] (pr-str date-map))))))

0 commit comments

Comments
 (0)