brandonbloom / fipp

Fast Idiomatic Pretty Printer for Clojure
525 stars 44 forks source link

pprint-document throws exception for high values of :width on certain inputs #53

Closed aeriksson closed 4 years ago

aeriksson commented 5 years ago

I'm occasionally encountering an exception when calling pprint-document with (somewhat) complex data structures and high values of :width.

Some observations:

(def bad-data '[:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:pass ""] "" [:pass ""]] :line [:span [:pass ""] "" [:pass ""]])] [:span [:pass ""] "" [:pass ""]]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:group [:span [:pass ""] "" [:pass ""]] [:align ([:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:group [:span [:pass ""] "" [:pass ""]] [:align ([:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]] :line [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]] :line [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:group [:span [:pass ""] "" [:pass ""]] [:align ([:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]]])] [:span [:pass ""] "" [:pass ""]]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]] :line [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:group [:span [:pass ""] "" [:pass ""]] [:align ([:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]] :line [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]] :line [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]] :line [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:group [:span [:pass ""] "" [:pass ""]] [:align ([:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]]])] [:span [:pass ""] "" [:pass ""]]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]] :line [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:group [:span [:pass ""] "" [:pass ""]] [:align ([:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]] :line [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]] :line [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]] :line [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:group [:span [:pass ""] "" [:pass ""]] [:align ([:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]]])] [:span [:pass ""] "" [:pass ""]]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]] :line [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:group [:span [:pass ""] "" [:pass ""]] [:align ([:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]] :line [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]] :line [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]] :line [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:group [:span [:pass ""] "" [:pass ""]] [:align ([:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]]])] [:span [:pass ""] "" [:pass ""]]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]] :line [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:group [:span [:pass ""] "" [:pass ""]] [:align ([:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]] :line [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]] :line [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]] :line [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:group [:span [:pass ""] "" [:pass ""]] [:align ([:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]]])] [:span [:pass ""] "" [:pass ""]]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]] :line [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:group [:span [:pass ""] "" [:pass ""]] [:align ([:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]] :line [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]] :line [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:group [:span [:pass ""] "" [:pass ""]] [:align ([:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]]])] [:span [:pass ""] "" [:pass ""]]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]] :line [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]] :line [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:group [:span [:pass ""] "" [:pass ""]] [:align ([:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]]])] [:span [:pass ""] "" [:pass ""]]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]]])] [:span [:pass ""] "" [:pass ""]]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]] [:span "" :line] [:span [:span [:pass ""] "" [:pass ""]] "" [:span [:pass ""] "" [:pass ""]]])] [:span [:pass ""] "" [:pass ""]]])
(fipp.engine/pprint-document bad-data)               ;; works
(fipp.engine/pprint-document bad-data {:width 1000}) ;; throws ClassCastException clojure.lang.PersistentVector$Node cannot be cast to [I

The exception thrown:

#error {
 :cause "clojure.lang.PersistentVector$Node cannot be cast to [I"
 :via
 [{:type java.lang.ClassCastException
   :message "clojure.lang.PersistentVector$Node cannot be cast to [I"
   :at [clojure.lang.Numbers ints "Numbers.java" 1396]}]
 :trace
 [[clojure.lang.Numbers ints "Numbers.java" 1396]
  [clojure.core.rrb_vector.rrbt$slot_count invokeStatic "rrbt.clj" 1286]
  [clojure.core.rrb_vector.rrbt$slot_count invoke "rrbt.clj" 1280]
  [clojure.core.rrb_vector.rrbt$subtree_branch_count invokeStatic "rrbt.clj" 1305]
  [clojure.core.rrb_vector.rrbt$subtree_branch_count invoke "rrbt.clj" 1289]
  [clojure.core.rrb_vector.rrbt$rebalance invokeStatic "rrbt.clj" 1392]
  [clojure.core.rrb_vector.rrbt$rebalance invoke "rrbt.clj" 1384]
  [clojure.core.rrb_vector.rrbt$zippath invokeStatic "rrbt.clj" 1492]
  [clojure.core.rrb_vector.rrbt$zippath invoke "rrbt.clj" 1469]
  [clojure.core.rrb_vector.rrbt$splice_rrbts invokeStatic "rrbt.clj" 1566]
  [clojure.core.rrb_vector.rrbt$splice_rrbts invoke "rrbt.clj" 1536]
  [clojure.core.rrb_vector.rrbt.Vector splicev "rrbt.clj" 1111]
  [clojure.core.rrb_vector.interop$eval2324$fn__2325 invoke "interop.clj" 30]
  [clojure.core.rrb_vector.protocols$eval1711$fn__1712$G__1702__1719 invoke "protocols.clj" 3]
  [clojure.core.rrb_vector$catvec invokeStatic "rrb_vector.clj" 57]
  [clojure.core.rrb_vector$catvec invoke "rrb_vector.clj" 48]
  [fipp.deque$conjlr invokeStatic "deque.cljc" 16]
  [fipp.deque$conjlr invoke "deque.cljc" 15]
  [fipp.engine$annotate_begins$fn__2457$fn__2459 invoke "engine.cljc" 121]
  [fipp.engine$annotate_rights$fn__2450 invoke "engine.cljc" 85]
  [clojure.lang.ArrayChunk reduce "ArrayChunk.java" 58]
  [clojure.core.protocols$fn__6750 invokeStatic "protocols.clj" 136]
  [clojure.core.protocols$fn__6750 invoke "protocols.clj" 124]
  [clojure.core.protocols$fn__6710$G__6705__6719 invoke "protocols.clj" 19]
  [clojure.core.protocols$seq_reduce invokeStatic "protocols.clj" 31]
  [clojure.core.protocols$fn__6738 invokeStatic "protocols.clj" 75]
  [clojure.core.protocols$fn__6738 invoke "protocols.clj" 75]
  [clojure.core.protocols$fn__6684$G__6679__6697 invoke "protocols.clj" 13]
  [clojure.core$transduce invokeStatic "core.clj" 6601]
  [clojure.core.Eduction reduce "core.clj" 7360]
  [clojure.core$reduce invokeStatic "core.clj" 6544]
  [clojure.core$run_BANG_ invokeStatic "core.clj" 7388]
  [clojure.core$run_BANG_ invoke "core.clj" 7388]
  [fipp.engine$pprint_document invokeStatic "engine.cljc" 241]
  [fipp.engine$pprint_document invoke "engine.cljc" 234]
  [user$eval2630 invokeStatic "form-init1429134254741924018.clj" 1]
  [user$eval2630 invoke "form-init1429134254741924018.clj" 1]
  [clojure.lang.Compiler eval "Compiler.java" 6927]
  [clojure.lang.Compiler eval "Compiler.java" 6890]
  [clojure.core$eval invokeStatic "core.clj" 3105]
  [clojure.core$eval invoke "core.clj" 3101]
  [clojure.main$repl$read_eval_print__7408$fn__7411 invoke "main.clj" 240]
  [clojure.main$repl$read_eval_print__7408 invoke "main.clj" 240]
  [clojure.main$repl$fn__7417 invoke "main.clj" 258]
  [clojure.main$repl invokeStatic "main.clj" 258]
  [clojure.main$repl doInvoke "main.clj" 174]
  [clojure.lang.RestFn invoke "RestFn.java" 1523]
  [clojure.tools.nrepl.middleware.interruptible_eval$evaluate$fn__648 invoke "interruptible_eval.clj" 87]
  [clojure.lang.AFn applyToHelper "AFn.java" 152]
  [clojure.lang.AFn applyTo "AFn.java" 144]
  [clojure.core$apply invokeStatic "core.clj" 646]
  [clojure.core$with_bindings_STAR_ invokeStatic "core.clj" 1881]
  [clojure.core$with_bindings_STAR_ doInvoke "core.clj" 1881]
  [clojure.lang.RestFn invoke "RestFn.java" 425]
  [clojure.tools.nrepl.middleware.interruptible_eval$evaluate invokeStatic "interruptible_eval.clj" 85]
  [clojure.tools.nrepl.middleware.interruptible_eval$evaluate invoke "interruptible_eval.clj" 55]
  [clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn__693$fn__696 invoke "interruptible_eval.clj" 222]
  [clojure.tools.nrepl.middleware.interruptible_eval$run_next$fn__688 invoke "interruptible_eval.clj" 190]
  [clojure.lang.AFn run "AFn.java" 22]
  [java.util.concurrent.ThreadPoolExecutor runWorker "ThreadPoolExecutor.java" 1167]
  [java.util.concurrent.ThreadPoolExecutor$Worker run "ThreadPoolExecutor.java" 641]
  [java.lang.Thread run "Thread.java" 844]]}

I have a suspicion that the bug actually lies in clojure.core.rrb-vector  — If I replace the calls in fipp.deque to clojure.core.rrb-vector/catvec with concat, the issue goes away. However, my attempts to prove this (by serializing and re-playing all rrb-vector operations for the above data) have been unsuccessful.

Note: I ran into this issue when using puget, which depends on fipp. I've filed an issue there as well: https://github.com/greglook/puget/issues/39

jafingerhut commented 5 years ago

I would also strongly suspect a bug in core.rrb-vector here. There are known sequences of operations described in JIRA tickets on core.rrb-vector's bug tracker that I have exercised myself and seen exceptions raised from core.rrb-vector code. I would not be surprised if you have found another one. I have created a new JIRA ticket that simply links to this issue here: https://dev.clojure.org/jira/browse/CRRBV-20

If you could add a note of which version of fipp you are using to get this, that should enable someone else to reproduce this more easily.

brandonbloom commented 5 years ago

1) Definitely a bug in RRB vector. Happy to upgrade when a fix is released upstream. 2) A width of 1000 is pretty far outside of the expected range. May I ask why you have it set so high? Does this issue happen at more reasonable widths? Say 40 to 300?

aeriksson commented 5 years ago

@jafingerhut thanks for creating the rrb-vector ticket. I've tried this on both fipp 0.6.14 and 2bef22d.

@brandonbloom I'm using puget to pretty-print data for logging purposes. In certain situations, it's preferable to print the data on a single line while retaining the syntax coloring, type extensions, etc that puget provides. I do this by setting the width to a high value (puget passes the width directly through to fipp.engine/pprint-document).

The problem happens for certain inputs once width is above some (input-dependent) threshold. For the example I provided above, that threshold is 155.

brandonbloom commented 5 years ago

@aeriksson Thanks for the details. Considering this is input dependent, 155 is still pretty large, and I've routinely used fipp with width set to 200 or so without issue, I'm not going to race to dive in to fix this rrb-vector issue. If and when it does get fixed over there, let me know and I'll update the dependency.

brandonbloom commented 5 years ago

Oh and if others are encountering this issue with smaller widths or more common inputs, please do speak up!

jafingerhut commented 5 years ago

I have some fairly new proposed changes to the core.rrb-vector library that seem like they might fix this, and several other, issues. They are not yet in the core.rrb-vector official source repository, nor in any released JAR files, but if you use deps.edn you can try it out from source in my branch of core.rrb-vector by adding this dependency:

{org.clojure/core.rrb-vector
 {:git/url "https://github.com/jafingerhut/core.rrb-vector"
  :sha "4f3dec8039bce68f59345ccb6801897260468514"}}

Let me know if you try it out and have any results to share, but when I tried it with the test case from this issue, there was no exception.

I can try to remember to update this issue whenever there is an official core.rrb-vector release with fixes.

jafingerhut commented 5 years ago

I have some additional improvements over the ones mentioned in my previous comment above. You can try them out using tools.deps with this dependency:

{org.clojure/core.rrb-vector
 {:git/url "https://github.com/jafingerhut/core.rrb-vector"
  :sha "cd32cdd48678ebfc052f6dd6726858fce89858b2"}}
jafingerhut commented 4 years ago

core.rrb-vector version 0.1.0 was released earlier today. It does not show up in search.maven.org search results yet as of the last time I tried, but I could use Leiningen to download it.

With no changes to fipp except bumping up the version to core.rrb-vector used to version 0.1.0, the test case given in this issue no longer throws an exception. It seems likely that the only issue here was a bug in the core.rrb-vector library, which version 0.1.0 seems to fix.

brandonbloom commented 4 years ago

Fixed in 2534620, will be available in 0.6.20 release, which I will cut soon.

brandonbloom commented 4 years ago

Oh and thanks!